diff --git a/CHANGELOG.md b/CHANGELOG.md index 379eaac7..563456ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog - FeedHenry Javascript SDK +## 2.16.3 - 2016-08-12 - Niall Donnelly +* RHMAP-9444 - Applying field and page rules whenever a field value changes. + ## 2.16.2 - 2016-07-28 - Wei Li * RHMAP-5793 - Decode the parameters in the url query string. diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f7c9b24e..73282660 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "fh-js-sdk", - "version": "2.16.2", + "version": "2.16.3", "dependencies": { "loglevel": { "version": "0.6.0", diff --git a/package.json b/package.json index 16c2c449..d0c51a8b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fh-js-sdk", - "version": "2.16.2", + "version": "2.16.3", "description": "feedhenry js sdk", "main": "dist/feedhenry.js", "browser": { diff --git a/src/appforms/script/sampleData/getForm.json b/src/appforms/script/sampleData/getForm.json index 265e4f2f..385d9889 100644 --- a/src/appforms/script/sampleData/getForm.json +++ b/src/appforms/script/sampleData/getForm.json @@ -87,7 +87,18 @@ ], "fieldRules": [ - + { + "type": "hide", + "_id": "57adaea2c94486873bb29789", + "targetField": ["52cfc0a78a31bc1524000004"], + "ruleConditionalStatements": [{ + "sourceField": "52cfc0a78a31bc1524000003", + "restriction": "is", + "sourceValue": "hideparagraph" + }], + "ruleConditionalOperator": "and", + "relationType": "and" + } ], "pages": [ { diff --git a/src/appforms/src/backbone/040-view02field01field.js b/src/appforms/src/backbone/040-view02field01field.js index 46db866c..ffdcdd85 100644 --- a/src/appforms/src/backbone/040-view02field01field.js +++ b/src/appforms/src/backbone/040-view02field01field.js @@ -211,6 +211,7 @@ var FieldView = Backbone.View.extend({ } while (parent); return view; }, + validate: function () {}, validateElement: function(index, element, cb) { var self = this; var fieldId = self.model.getFieldId(); @@ -237,16 +238,13 @@ var FieldView = Backbone.View.extend({ } }); }, - validate: function(e) { + setValueToSubmission: function(params, cb) { var self = this; - this.options.formView.markFormEdited(); - var currentTarget = $(e.currentTarget); - var target = $(e.target); - - var index = currentTarget.data().index || target.data().index; - var val = self.valueFromElement(index); - self.validateElement(index, val); - self.trigger("checkrules"); + //Adding the field value to the submission. + self.options.formView.addFieldInputValue(params, cb); + }, + removeValueFromSubmission: function(params) { + this.options.formView.removeFieldInputValue(params); }, setErrorText: function(index, text) { var wrapperObj = this.getWrapper(index); @@ -257,12 +255,43 @@ var FieldView = Backbone.View.extend({ if(wrapperObj.find("input[type='checkbox']").length === 0){ wrapperObj.find("input,textarea,select").addClass(this.errorClassName); } - }, + //The content of the field has changed, ensure the new value is persisted to the submission contentChanged: function(e) { - this.options.formView.markFormEdited(); + var self = this; e.preventDefault(); - this.validate(e); + self.options.formView.markFormEdited(); + var currentTarget = $(e.currentTarget); + var target = $(e.target); + var index = currentTarget.data().index || target.data().index; + var val = self.valueFromElement(index); + + self.validateElement(index, val); + + self.updateOrRemoveValue({ + index: index, + value: val, + isStore: true, + fieldId: self.model.getFieldId() + }, function() { + //Value has been persisted, now check for any rule changes. + self.checkRules(); + }); + }, + + checkRules: function() { + this.trigger('checkrules'); + }, + + updateOrRemoveValue: function(params, cb) { + var self = this; + //Ensuring that if the field value was removed from the element, that it is removed from the submission also + if(!params.value) { + self.removeValueFromSubmission(params); + return cb(); + } else { + self.setValueToSubmission(params, cb); + } }, isRequired: function() { diff --git a/src/appforms/src/backbone/040-view02field10field_file.js b/src/appforms/src/backbone/040-view02field10field_file.js index 95f9bd95..72c69675 100644 --- a/src/appforms/src/backbone/040-view02field10field_file.js +++ b/src/appforms/src/backbone/040-view02field10field_file.js @@ -9,30 +9,44 @@ FieldFileView = FieldView.extend({ self.fileObjs = []; FieldView.prototype.initialize.apply(self, arguments); }, + //The file has changed, make sure the file is validated and saved to the submission. contentChanged: function(e) { var self = this; var fileEle = e.target; var filejQ = $(fileEle); var index = filejQ.data().index; var file = fileEle.files ? fileEle.files[0] : null; - if (file) { - self.validateElement(index, file, function(err) { - //File Needs to be validated. - if (!err) { //Validation of file is valid - var fileObj = { - "fileName": file.name, - "fileSize": file.size, - "fileType": file.type - }; - self.showButton(index, fileObj); - } else { - filejQ.val(""); - self.showButton(index, null); - } - }); - } else { //user cancelled file selection + + self.updateOrRemoveValue({ + fieldId: self.model.getFieldId(), + value: file, + isStore: true, + index: index + }, function() { + self.checkRules(); + if (file) { + self.validateAndUpdateButtons(index, file); + } else { //user cancelled file selection self.showButton(index, null); + } + }); + }, + validateAndUpdateButtons: function(index, file) { + var self = this; + self.validateElement(index, file, function(err) { + //File Needs to be validated. + if (!err) { //Validation of file is valid + var fileObj = { + "fileName": file.name, + "fileSize": file.size, + "fileType": file.type + }; + self.showButton(index, fileObj); + } else { + filejQ.val(""); + self.showButton(index, null); } + }); }, valueFromElement: function(index) { var wrapperObj = this.getWrapper(index); diff --git a/src/appforms/src/backbone/040-view02field21field_signature.js b/src/appforms/src/backbone/040-view02field21field_signature.js index 6d4a8b3a..08df479c 100644 --- a/src/appforms/src/backbone/040-view02field21field_signature.js +++ b/src/appforms/src/backbone/040-view02field21field_signature.js @@ -22,9 +22,6 @@ FieldSignatureView = FieldView.extend({ } }, - validate: function(e) { - this.trigger("checkrules"); - }, showSignatureCapture: function(index) { var self = this; var winHeight = $(window).height(); @@ -91,8 +88,17 @@ FieldSignatureView = FieldView.extend({ }); }, setSignature: function(index, base64Img) { + var self = this; var wrapper = this.getWrapper(index); - wrapper.find("img.sigImage").attr("src", base64Img); + + self.updateOrRemoveValue({ + fieldId: self.model.getFieldId(), + index: index, + isStore: true, + value: base64Img + }, function() { + wrapper.find("img.sigImage").attr("src", base64Img); + }); }, valueFromElement: function(index) { var wrapper = this.getWrapper(index); diff --git a/src/appforms/src/backbone/040-view02field29barcode.js b/src/appforms/src/backbone/040-view02field29barcode.js index 20f19f79..f400cd11 100644 --- a/src/appforms/src/backbone/040-view02field29barcode.js +++ b/src/appforms/src/backbone/040-view02field29barcode.js @@ -26,7 +26,16 @@ FieldBarcodeView = FieldView.extend({ //Dont need to do anything when the content changes. self.barcodeObjects[index] = result; - self.validateElement(index, result); + + self.updateOrRemoveValue({ + fieldId: self.model.getFieldId(), + index: index, + value: result, + isStore: true + }, function() { + self.validateElement(index, result); + self.checkRules(); + }); }, valueFromElement: function(index) { var self = this; diff --git a/src/appforms/src/backbone/040-view02field30sliderNumber.js b/src/appforms/src/backbone/040-view02field30sliderNumber.js index f598a9ef..8cc4e8db 100644 --- a/src/appforms/src/backbone/040-view02field30sliderNumber.js +++ b/src/appforms/src/backbone/040-view02field30sliderNumber.js @@ -93,9 +93,16 @@ FieldSliderNumberView = FieldView.extend({ var input = $(wrapperObj.find("input[type='range']")); var value = input.attr('value') || input.val(); - wrapperObj.find(".slideValue").html("Selected Value: " + value); - self.validateElement(index, value); - self.trigger('checkrules'); + self.updateOrRemoveValue({ + fieldId: self.model.getFieldId(), + index: index, + value: value, + isStore: true + }, function() { + wrapperObj.find(".slideValue").html("Selected Value: " + value); + self.validateElement(index, value); + self.checkRules(); + }); }, getHTMLInputType: function() { return "text"; diff --git a/src/appforms/src/backbone/040-view04Form.js b/src/appforms/src/backbone/040-view04Form.js index 958b8dd7..d608b73c 100644 --- a/src/appforms/src/backbone/040-view04Form.js +++ b/src/appforms/src/backbone/040-view04Form.js @@ -501,6 +501,13 @@ var FormView = BaseView.extend({ }); }); }, + addFieldInputValue: function(params, cb) { + cb = cb || function() {}; + this.submission.addInputValue(params, cb); + }, + removeFieldInputValue: function(params) { + this.submission.removeFieldValue(params.fieldId, params.index); + }, populateFieldViewsToSubmission: function(isStore, cb) { if (typeof cb === "undefined") { cb = isStore; diff --git a/src/appforms/tests/tests/backbone/040-view02field01field.js b/src/appforms/tests/tests/backbone/040-view02field01field.js index 5d531e97..80d850b2 100644 --- a/src/appforms/tests/tests/backbone/040-view02field01field.js +++ b/src/appforms/tests/tests/backbone/040-view02field01field.js @@ -3,6 +3,9 @@ var assert = chai.assert; describe("Backbone - Field View", function() { + var textFieldId = "52cfc0a78a31bc1524000003"; + var textFieldSelector = 'input[data-field="' + textFieldId + '"]'; + before(function(done){ var self = this; var Form = appForm.models.Form; @@ -25,7 +28,6 @@ describe("Backbone - Field View", function() { assert.ok(!err, "Expected no error"); self.formView.render(); - done(); }); }); @@ -35,7 +37,7 @@ describe("Backbone - Field View", function() { var fieldView; var fieldModel; - fieldModel = this.form.getFieldModelById("52cfc0a78a31bc1524000003"); + fieldModel = this.form.getFieldModelById(textFieldId); assert(fieldModel, "Expected a field model"); // create backbone field View @@ -49,4 +51,49 @@ describe("Backbone - Field View", function() { done(); }); + + it("Field values should be populated to the submission immediately when the content changes ", function(done) { + var testValue = 'sometestval'; + this.formView.$el.find(textFieldSelector).val(testValue).trigger('change'); + + //The submission should have that value + this.formView.submission.getInputValueByFieldId(textFieldId, function(err, fieldValues) { + assert.ok(!err, "Expected no error"); + assert.equal(testValue, fieldValues[0]); + done(); + }); + }); + + it("Field values should be removed from the submission when the content is removed ", function(done) { + this.formView.$el.find(textFieldSelector).val('').trigger('change'); + + //The submission should have the value removed + this.formView.submission.getInputValueByFieldId(textFieldId, function(err, fieldValues) { + assert.ok(!err, "Expected no error"); + assert.equal(null, fieldValues[0]); + done(); + }); + }); + + it("Field rules should be triggered when a field value changes", function(done) { + //Value that will hide the paragraph field. Defined in the form with id 527d4539639f521e0a000004 + var self = this; + var testValue = 'hideparagraph'; + var paragraphFieldId = "52cfc0a78a31bc1524000004"; + var paragraphFieldIdSelector = 'div[data-field="' + paragraphFieldId +'"]'; + + //The field should be present + var visibleField = this.formView.$el.find(paragraphFieldIdSelector); + assert.equal(1, visibleField.length, "The paragraph field should be present"); + + //Add the new value that should hide the paragraph field + this.formView.$el.find(textFieldSelector).val(testValue).trigger('change'); + + //The field should not be visible + setTimeout(function() { + visibleField = self.formView.$el.find(paragraphFieldIdSelector + '[style="display: none;"]'); + assert.equal(1, visibleField.length, "Expected the paragraph field to be hidden"); + done(); + }, 1); + }); }); \ No newline at end of file