From 6f127fac8cffb3d909053def042f262ee89f92d6 Mon Sep 17 00:00:00 2001 From: Boris van Schooten Date: Tue, 13 Nov 2018 12:23:44 +0100 Subject: [PATCH 1/4] Added copy function to array toolbar. --- src/js/fields/basic/ArrayField.js | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/js/fields/basic/ArrayField.js b/src/js/fields/basic/ArrayField.js index f5f5eaa6e..2386307aa 100644 --- a/src/js/fields/basic/ArrayField.js +++ b/src/js/fields/basic/ArrayField.js @@ -252,6 +252,17 @@ }); } }); + applyAction(self.actionbar.actions, "copy", { + "label": self.getMessage("addButtonLabel"), + "action": "copy", + "iconClass": self.view.getStyle("addIcon"), + "click": function(key, action, itemIndex) { + + self.handleActionBarCopyItemClick(itemIndex, function(item) { + // done + }); + } + }); applyAction(self.actionbar.actions, "remove", { "label": self.getMessage("removeButtonLabel"), "action": "remove", @@ -1218,6 +1229,39 @@ }); }, + handleActionBarCopyItemClick: function(itemIndex, callback) + { + var self = this; + + self.resolveItemSchemaOptions(function(itemSchema, itemOptions, circular) { + + // we only allow addition if the resolved schema isn't circularly referenced + // or the schema is optional + if (circular) + { + return Alpaca.throwErrorWithCallback("Circular reference detected for schema: " + JSON.stringify(itemSchema), self.errorCallback); + } + + var arrayValues = self.getValue(); + + + //var itemData = Alpaca.createEmptyDataInstance(itemSchema); + var itemData = self.children[itemIndex].getValue(); + // XXX no cloning necessary? + self.addItem(itemIndex + 1, itemSchema, itemOptions, itemData, function(item) { + + // this is necessary because some underlying fields require their data to be reset + // in order for the display to work out properly (radio fields) + arrayValues.splice(itemIndex + 1, 0, item.getValue()); + self.setValue(arrayValues); + + if (callback) { + callback(item); + } + }); + }); + }, + handleActionBarRemoveItemClick: function(itemIndex, callback) { var self = this; From fc88013a781b19e2b2775cb64817331da8541c95 Mon Sep 17 00:00:00 2001 From: Boris van Schooten Date: Tue, 13 Nov 2018 16:24:45 +0100 Subject: [PATCH 2/4] Added dependency system based on absolute paths. --- README.md | 31 ++++++++ gulpfile.js | 1 + src/js/Alpaca.js | 2 + src/js/PathBasedDependencies.js | 133 ++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 src/js/PathBasedDependencies.js diff --git a/README.md b/README.md index 15673ce8f..ac7c03e7e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,36 @@ Buy Me a Coffee at ko-fi.com +# Alpaca - Modified version - New features added + +- A Copy function for arrays. A new icon is added to the toolbar that copies + the current element. + +- New dependency system. Dependencies are specified as part of the options json, using the field "x\_dependencies". x\_dependencies is an array of objects, with the following fields: + - "field" : path to field that is to be checked (no leading slash). Use "[]" to indicate all elements of an array. + - "values": array of values against which field is checked. + - "enables": relative path to field that is enabled when field is equal to one of the values. + + Example. + ``` + { + "options": { + "x_dependencies": [ + { + "field": "questions[]/openoption", + "values": [true], + "enables": "desc/nld_nld/openoption" + }, + { + "field": "questions[]/type", + "values": ["likert","vas"], + "enables": "desc/nld_nld/anchors" + } + ] + } + } + + ``` + # Alpaca - JSON Forms for jQuery and Bootstrap Alpaca provides the easiest and fastest way to generate interactive forms for the web and mobile devices. diff --git a/gulpfile.js b/gulpfile.js index 8e260ff0a..939ee3c48 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -55,6 +55,7 @@ var paths = { "src/js/ControlField.js", "src/js/ContainerField.js", "src/js/Form.js", + "src/js/PathBasedDependencies.js", // cache implementations "src/js/cache/memory.js", diff --git a/src/js/Alpaca.js b/src/js/Alpaca.js index ad2c688ae..7f58b3cec 100644 --- a/src/js/Alpaca.js +++ b/src/js/Alpaca.js @@ -394,6 +394,8 @@ _resetInitValidationError(field); } + // Dependency management is performed as a postrender call + Alpaca.PathBasedDependencies.postRenderCallback(field); if (renderedCallback) { renderedCallback(field); diff --git a/src/js/PathBasedDependencies.js b/src/js/PathBasedDependencies.js new file mode 100644 index 000000000..53584ec2f --- /dev/null +++ b/src/js/PathBasedDependencies.js @@ -0,0 +1,133 @@ +(function() { +Alpaca.PathBasedDependencies = (function() { + + //var registry = {}; + + return { + + postRenderCallback: function(control) { + if (!control.options.x_dependencies) return; + var deps = control.options.x_dependencies; + control.on("change", function() { + var deps = this.options.x_dependencies; + Alpaca.PathBasedDependencies.updateDeps(deps,this, + Alpaca.PathBasedDependencies.processDepLeaf); + }); + Alpaca.PathBasedDependencies.doRecursive(control, function(current) { + current.on("add",function() { + //console.log("########ADD EVENT"); + Alpaca.PathBasedDependencies.updateDeps(deps,control, + Alpaca.PathBasedDependencies.processDepLeaf); + }); + current.on("move",function() { + //console.log("########ADD EVENT"); + Alpaca.PathBasedDependencies.updateDeps(deps,control, + Alpaca.PathBasedDependencies.processDepLeaf); + }); + }); + }, + + // call callback(element) on current and all of its children + doRecursive: function(current,callback) { + callback(current); + if (!current.children) return; + for (var i=0; i check dependency + if (typeof current == "undefined") return; + if (!current) return; + callback(dep,current); + return; + } + var name = pathArray.shift(); + var isArray=false; + var z = name.indexOf("[]"); + if (z >= 0) { + name = name.substring(0,z); + isArray=true; + } + //console.log(name+"#"+isArray+"$"); + current = current.childrenByPropertyId[name]; + if (!isArray) { + Alpaca.PathBasedDependencies.processDep(dep,pathArray,current,callback); + } else { + //console.log("array size "+current.children.length); + for (var j=0; j Date: Tue, 13 Nov 2018 17:24:57 +0100 Subject: [PATCH 3/4] Dependency enables field is now an array. --- README.md | 13 ++++--------- src/js/PathBasedDependencies.js | 16 ++++++++++------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ac7c03e7e..8a658b850 100644 --- a/README.md +++ b/README.md @@ -7,29 +7,24 @@ - New dependency system. Dependencies are specified as part of the options json, using the field "x\_dependencies". x\_dependencies is an array of objects, with the following fields: - "field" : path to field that is to be checked (no leading slash). Use "[]" to indicate all elements of an array. - - "values": array of values against which field is checked. - - "enables": relative path to field that is enabled when field is equal to one of the values. + - "values": array of values against which _field_ is checked. + - "enables": array of relative paths to fields that are to be enabled when _field_ is equal to one of the values. The path root is the parent of the element indicated by _field_. So, dependencies can refer to siblings of the _field_ element, or to elements deeper in the tree. "[]" can again be used to specify all elements of an array. Example. ``` { "options": { "x_dependencies": [ - { - "field": "questions[]/openoption", - "values": [true], - "enables": "desc/nld_nld/openoption" - }, { "field": "questions[]/type", "values": ["likert","vas"], - "enables": "desc/nld_nld/anchors" + "enables": [ "desc/nld_nld/anchors", "range"] } ] } } - ``` + This checks if the _type_ field of each element of the _questions_ array is equal to either of the two given strings. If true, the _range_ field in the same element and the *desc.nld_nld.anchors* subfields are enabled. If false, they are disabled (hidden). # Alpaca - JSON Forms for jQuery and Bootstrap diff --git a/src/js/PathBasedDependencies.js b/src/js/PathBasedDependencies.js index 53584ec2f..fb81cb340 100644 --- a/src/js/PathBasedDependencies.js +++ b/src/js/PathBasedDependencies.js @@ -40,8 +40,8 @@ Alpaca.PathBasedDependencies = (function() { // deps - array of dependencies: {field, values, enables} // field - path to source field // values - array of source field values - // enables - relative path to element(s) to enable when source field - // matches one of the values + // enables - array of relative paths to element(s) to enable + // when source field matches one of the values updateDeps: function(deps,rootelem,callback) { for (var i=0; i disable - Alpaca.PathBasedDependencies.processDepLeafEnable(false,dep.enables,current.parent, - Alpaca.PathBasedDependencies.enableField); + for (var j=0; j Date: Thu, 15 Nov 2018 15:31:05 +0100 Subject: [PATCH 4/4] Dependencies are now propery updated on initialization. --- src/js/PathBasedDependencies.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/js/PathBasedDependencies.js b/src/js/PathBasedDependencies.js index fb81cb340..1949b46e0 100644 --- a/src/js/PathBasedDependencies.js +++ b/src/js/PathBasedDependencies.js @@ -25,6 +25,9 @@ Alpaca.PathBasedDependencies = (function() { Alpaca.PathBasedDependencies.processDepLeaf); }); }); + // now, run it once to initialize + Alpaca.PathBasedDependencies.updateDeps(deps,control, + Alpaca.PathBasedDependencies.processDepLeaf); }, // call callback(element) on current and all of its children