From 1f67ffb512e11866572ccc094e77567761c76aaf Mon Sep 17 00:00:00 2001 From: Indri Muska Date: Tue, 12 Apr 2016 18:18:38 +0200 Subject: [PATCH] Form data and field name passed to required validation function rule --- CHANGELOG.md | 3 + dist/form-for.css | 9 -- dist/form-for.js | 206 ++++++++++++++--------------- dist/form-for.min.js | 2 +- dist/form-for.min.js.map | 2 +- package.json | 2 +- source/services/model-validator.ts | 6 +- 7 files changed, 112 insertions(+), 118 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d80a391..eec1076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 4.1.12 +Form data and field name passed to required validation function rule. + ## 4.1.11 Fixed `TypeError: Cannot read property 'unwatchers' of undefined` bug reported in issue #186. Special thanks to @baconcutter for submitting this PR. diff --git a/dist/form-for.css b/dist/form-for.css index 1191397..8c1932c 100644 --- a/dist/form-for.css +++ b/dist/form-for.css @@ -23,7 +23,6 @@ text-align: center; vertical-align: middle; display: inline-block; - background-image: -webkit-linear-gradient(bottom, #f9f9f9, #fff); background-image: linear-gradient(to top, #f9f9f9, #fff); border: 1px solid #aaa; position: relative; @@ -157,7 +156,6 @@ field-label { text-align: center; vertical-align: middle; display: inline-block; - background-image: -webkit-linear-gradient(bottom, #f9f9f9, #fff); background-image: linear-gradient(to top, #f9f9f9, #fff); border: 1px solid #aaa; position: relative; @@ -233,7 +231,6 @@ select-field { } /************************* Select *************************/ .form-for-field select { - background: -webkit-linear-gradient(top, #fff, #efefef); background: linear-gradient(top, #fff, #efefef); padding-right: 30px; } @@ -339,7 +336,6 @@ submit-field { -moz-user-select: none; -ms-user-select: none; user-select: none; - -webkit-transition: all; transition: all; border-radius: 6px; border-style: none; @@ -361,7 +357,6 @@ submit-field { color: #fff; } .submit-button:active { - -webkit-transition: none; transition: none; box-shadow: inset 0 4px 2px rgba(0,0,0,0.1); } @@ -449,11 +444,9 @@ text-field { } .form-for-tooltip { - display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; - -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; @@ -464,7 +457,6 @@ text-field { display: inline-block; width: 15px; height: 15px; - -webkit-box-flex: 0; -webkit-flex: 0 0 15px; -ms-flex: 0 0 15px; flex: 0 0 15px; @@ -485,7 +477,6 @@ text-field { display: none; position: relative; z-index: 2; - -webkit-box-flex: 0; -webkit-flex: 0 0 350px; -ms-flex: 0 0 350px; flex: 0 0 350px; diff --git a/dist/form-for.js b/dist/form-for.js index 41c8951..0f71a20 100644 --- a/dist/form-for.js +++ b/dist/form-for.js @@ -2362,106 +2362,6 @@ var formFor; ; })(formFor || (formFor = {})); ; -/// -var formFor; -(function (formFor) { - /* - * Organizes state management for form-submission and field validity. - * - *

Intended for use only by formFor directive; this class is not exposed to the $injector. - */ - var FormForStateHelper = (function () { - // TODO Add some documentation - function FormForStateHelper($parse, $scope) { - this.formForScope_ = $scope; - this.nestedObjectHelper_ = new formFor.NestedObjectHelper($parse); - this.formForScope_.fieldNameToErrorMap = $scope.fieldNameToErrorMap || {}; - this.formForScope_.valid = true; - this.fieldNameToModifiedStateMap_ = {}; - this.formSubmitted_ = false; - this.fieldNameToErrorMap_ = {}; - this.watchable = 0; - } - FormForStateHelper.prototype.getFieldError = function (fieldName) { - return this.nestedObjectHelper_.readAttribute(this.formForScope_.fieldNameToErrorMap, fieldName); - }; - FormForStateHelper.prototype.hasFieldBeenModified = function (fieldName) { - return this.nestedObjectHelper_.readAttribute(this.fieldNameToModifiedStateMap_, fieldName); - }; - FormForStateHelper.prototype.hasFormBeenSubmitted = function () { - return this.formSubmitted_; - }; - FormForStateHelper.prototype.isFormInvalid = function () { - return !this.isFormValid(); - }; - FormForStateHelper.prototype.isFormValid = function () { - for (var prop in this.fieldNameToErrorMap_) { - return false; - } - return true; - }; - FormForStateHelper.prototype.resetFieldErrors = function () { - this.formForScope_.fieldNameToErrorMap = {}; - }; - FormForStateHelper.prototype.setFieldError = function (fieldName, error) { - var safeFieldName = this.nestedObjectHelper_.flattenAttribute(fieldName); - this.nestedObjectHelper_.writeAttribute(this.formForScope_.fieldNameToErrorMap, fieldName, error); - if (error) { - this.fieldNameToErrorMap_[safeFieldName] = error; - } - else { - delete this.fieldNameToErrorMap_[safeFieldName]; - } - this.formForScope_.valid = this.isFormValid(); - this.watchable++; - }; - FormForStateHelper.prototype.setFieldHasBeenModified = function (fieldName, hasBeenModified) { - this.nestedObjectHelper_.writeAttribute(this.fieldNameToModifiedStateMap_, fieldName, hasBeenModified); - this.watchable++; - }; - FormForStateHelper.prototype.setFormSubmitted = function (submitted) { - this.formSubmitted_ = submitted; - this.watchable++; - }; - return FormForStateHelper; - })(); - formFor.FormForStateHelper = FormForStateHelper; -})(formFor || (formFor = {})); -var formFor; -(function (formFor) { - /** - * Utility for working with strings. - * - *

Intended for use only by formFor directive; this class is not exposed to the $injector. - */ - var StringUtil = (function () { - function StringUtil() { - } - /** - * Converts text in common variable formats to humanized form. - * - * @param text Name of variable to be humanized (ex. myVariable, my_variable) - * @returns Humanized string (ex. 'My Variable') - */ - StringUtil.humanize = function (text) { - if (!text) { - return ''; - } - text = text.replace(/[A-Z]/g, function (match) { - return ' ' + match; - }); - text = text.replace(/_([a-z])/g, function (match, $1) { - return ' ' + $1.toUpperCase(); - }); - text = text.replace(/\s+/g, ' '); - text = text.trim(); - text = text.charAt(0).toUpperCase() + text.slice(1); - return text; - }; - return StringUtil; - })(); - formFor.StringUtil = StringUtil; -})(formFor || (formFor = {})); /// /// /// @@ -2574,7 +2474,7 @@ var formFor; if (value === undefined || value === null) { value = ""; // Escape falsy values liked null or undefined, but not ones like 0 } - return this.validateFieldRequired_(value, validationRules) || + return this.validateFieldRequired_(value, validationRules, formData, fieldName) || this.validateFieldMinimum_(value, validationRules) || this.validateFieldMinLength_(value, validationRules) || this.validateFieldIncrement_(value, validationRules) || @@ -2840,12 +2740,12 @@ var formFor; } return null; }; - ModelValidator.prototype.validateFieldRequired_ = function (value, validationRules) { + ModelValidator.prototype.validateFieldRequired_ = function (value, validationRules, formData, fieldName) { if (validationRules.required) { var required = angular.isObject(validationRules.required) ? validationRules.required.rule : angular.isFunction(validationRules.required) - ? validationRules.required.call(this, value) + ? validationRules.required.apply(this, [value, formData, fieldName]) : validationRules.required; // Compare both string and numeric values to avoid rejecting non-empty but falsy values (e.g. 0). var stringValue = value.toString().replace(/\s+$/, ''); // Disallow an all-whitespace string @@ -2935,4 +2835,104 @@ var formFor; return new ModelValidator($interpolate, $parse, $q, FormForConfiguration); }]); })(formFor || (formFor = {})); +/// +var formFor; +(function (formFor) { + /* + * Organizes state management for form-submission and field validity. + * + *

Intended for use only by formFor directive; this class is not exposed to the $injector. + */ + var FormForStateHelper = (function () { + // TODO Add some documentation + function FormForStateHelper($parse, $scope) { + this.formForScope_ = $scope; + this.nestedObjectHelper_ = new formFor.NestedObjectHelper($parse); + this.formForScope_.fieldNameToErrorMap = $scope.fieldNameToErrorMap || {}; + this.formForScope_.valid = true; + this.fieldNameToModifiedStateMap_ = {}; + this.formSubmitted_ = false; + this.fieldNameToErrorMap_ = {}; + this.watchable = 0; + } + FormForStateHelper.prototype.getFieldError = function (fieldName) { + return this.nestedObjectHelper_.readAttribute(this.formForScope_.fieldNameToErrorMap, fieldName); + }; + FormForStateHelper.prototype.hasFieldBeenModified = function (fieldName) { + return this.nestedObjectHelper_.readAttribute(this.fieldNameToModifiedStateMap_, fieldName); + }; + FormForStateHelper.prototype.hasFormBeenSubmitted = function () { + return this.formSubmitted_; + }; + FormForStateHelper.prototype.isFormInvalid = function () { + return !this.isFormValid(); + }; + FormForStateHelper.prototype.isFormValid = function () { + for (var prop in this.fieldNameToErrorMap_) { + return false; + } + return true; + }; + FormForStateHelper.prototype.resetFieldErrors = function () { + this.formForScope_.fieldNameToErrorMap = {}; + }; + FormForStateHelper.prototype.setFieldError = function (fieldName, error) { + var safeFieldName = this.nestedObjectHelper_.flattenAttribute(fieldName); + this.nestedObjectHelper_.writeAttribute(this.formForScope_.fieldNameToErrorMap, fieldName, error); + if (error) { + this.fieldNameToErrorMap_[safeFieldName] = error; + } + else { + delete this.fieldNameToErrorMap_[safeFieldName]; + } + this.formForScope_.valid = this.isFormValid(); + this.watchable++; + }; + FormForStateHelper.prototype.setFieldHasBeenModified = function (fieldName, hasBeenModified) { + this.nestedObjectHelper_.writeAttribute(this.fieldNameToModifiedStateMap_, fieldName, hasBeenModified); + this.watchable++; + }; + FormForStateHelper.prototype.setFormSubmitted = function (submitted) { + this.formSubmitted_ = submitted; + this.watchable++; + }; + return FormForStateHelper; + })(); + formFor.FormForStateHelper = FormForStateHelper; +})(formFor || (formFor = {})); +var formFor; +(function (formFor) { + /** + * Utility for working with strings. + * + *

Intended for use only by formFor directive; this class is not exposed to the $injector. + */ + var StringUtil = (function () { + function StringUtil() { + } + /** + * Converts text in common variable formats to humanized form. + * + * @param text Name of variable to be humanized (ex. myVariable, my_variable) + * @returns Humanized string (ex. 'My Variable') + */ + StringUtil.humanize = function (text) { + if (!text) { + return ''; + } + text = text.replace(/[A-Z]/g, function (match) { + return ' ' + match; + }); + text = text.replace(/_([a-z])/g, function (match, $1) { + return ' ' + $1.toUpperCase(); + }); + text = text.replace(/\s+/g, ' '); + text = text.trim(); + text = text.charAt(0).toUpperCase() + text.slice(1); + return text; + }; + return StringUtil; + })(); + formFor.StringUtil = StringUtil; +})(formFor || (formFor = {})); /// diff --git a/dist/form-for.min.js b/dist/form-for.min.js index f70298e..b1501c7 100644 --- a/dist/form-for.min.js +++ b/dist/form-for.min.js @@ -1,3 +1,3 @@ angular.module("formFor",[]);var formFor;!function(e){var t=function(){function e(){this.restrict="A"}return e.prototype.link=function(e,t,i){e.$watch("model.uid",function(e){i.$set("ariaDescribedby",e+"-error"),i.$set("ariaLabelledby",e+"-label")}),e.$watch("model.error",function(e){i.$set("ariaInvalid",!!e)})},e.prototype.link.$inject=["$scope","$element","$attributes"],e}();e.AriaManager=t,angular.module("formFor").directive("ariaManager",function(){return new t})}(formFor||(formFor={}));var formFor;!function(e){var t=function(){function t(){this.autoGenerateLabels=!1,this.autoTrimValues=!1,this.defaultDebounceDuration=500,this.defaultSubmitComplete=angular.noop,this.defaultSubmitError=angular.noop,this.defaultValidationFailed=angular.noop,this.defaultSelectEmptyOptionValue=void 0,this.helpIcon=null,this.labelClass=null,this.requiredLabel=null,this.validationFailedForCustomMessage_="Failed custom validation",this.validationFailedForEmailTypeMessage_="Invalid email format",this.validationFailedForIncrementMessage_="Value must be in increments of {{num}}",this.validationFailedForIntegerTypeMessage_="Must be an integer",this.validationFailedForMaxCollectionSizeMessage_="Must be fewer than {{num}} items",this.validationFailedForMaximumMessage_="Must be no more than {{num}}",this.validationFailedForMaxLengthMessage_="Must be fewer than {{num}} characters",this.validationFailedForMinimumMessage_="Must be at least {{num}}",this.validationFailedForMinCollectionSizeMessage_="Must at least {{num}} items",this.validationFailedForMinLengthMessage_="Must be at least {{num}} characters",this.validationFailedForNegativeTypeMessage_="Must be negative",this.validationFailedForNonNegativeTypeMessage_="Must be non-negative",this.validationFailedForNumericTypeMessage_="Must be numeric",this.validationFailedForPatternMessage_="Invalid format",this.validationFailedForPositiveTypeMessage_="Must be positive",this.validationFailedForRequiredMessage_="Required field"}return t.prototype.disableAutoLabels=function(){this.autoGenerateLabels=!1},t.prototype.enableAutoLabels=function(){this.autoGenerateLabels=!0},t.prototype.disableAutoTrimValues=function(){this.autoTrimValues=!1},t.prototype.enableAutoTrimValues=function(){this.autoTrimValues=!0},t.prototype.getFailedValidationMessage=function(t){switch(t){case e.ValidationFailureType.CUSTOM:return this.validationFailedForCustomMessage_;case e.ValidationFailureType.COLLECTION_MAX_SIZE:return this.validationFailedForMaxCollectionSizeMessage_;case e.ValidationFailureType.COLLECTION_MIN_SIZE:return this.validationFailedForMinCollectionSizeMessage_;case e.ValidationFailureType.INCREMENT:return this.validationFailedForIncrementMessage_;case e.ValidationFailureType.MINIMUM:return this.validationFailedForMinimumMessage_;case e.ValidationFailureType.MAX_LENGTH:return this.validationFailedForMaxLengthMessage_;case e.ValidationFailureType.MAXIMUM:return this.validationFailedForMaximumMessage_;case e.ValidationFailureType.MIN_LENGTH:return this.validationFailedForMinLengthMessage_;case e.ValidationFailureType.PATTERN:return this.validationFailedForPatternMessage_;case e.ValidationFailureType.REQUIRED:return this.validationFailedForRequiredMessage_;case e.ValidationFailureType.TYPE_EMAIL:return this.validationFailedForEmailTypeMessage_;case e.ValidationFailureType.TYPE_INTEGER:return this.validationFailedForIntegerTypeMessage_;case e.ValidationFailureType.TYPE_NEGATIVE:return this.validationFailedForNegativeTypeMessage_;case e.ValidationFailureType.TYPE_NON_NEGATIVE:return this.validationFailedForNonNegativeTypeMessage_;case e.ValidationFailureType.TYPE_NUMERIC:return this.validationFailedForNumericTypeMessage_;case e.ValidationFailureType.TYPE_POSITIVE:return this.validationFailedForPositiveTypeMessage_}},t.prototype.setDefaultDebounceDuration=function(e){this.defaultDebounceDuration=e},t.prototype.setDefaultSubmitComplete=function(e){this.defaultSubmitComplete=e},t.prototype.setDefaultSubmitError=function(e){this.defaultSubmitError=e},t.prototype.setDefaultValidationFailed=function(e){this.defaultValidationFailed=e},t.prototype.setDefaultSelectEmptyOptionValue=function(e){this.defaultSelectEmptyOptionValue=e},t.prototype.setHelpIcon=function(e){this.helpIcon=e},t.prototype.setLabelClass=function(e){this.labelClass=e},t.prototype.setRequiredLabel=function(e){this.requiredLabel=e},t.prototype.setValidationFailedForCustomMessage=function(e){this.validationFailedForCustomMessage_=e},t.prototype.setValidationFailedForIncrementMessage=function(e){this.validationFailedForIncrementMessage_=e},t.prototype.setValidationFailedForMaxCollectionSizeMessage=function(e){this.validationFailedForMaxCollectionSizeMessage_=e},t.prototype.setValidationFailedForMaximumMessage=function(e){this.validationFailedForMaximumMessage_=e},t.prototype.setValidationFailedForMaxLengthMessage=function(e){this.validationFailedForMaxLengthMessage_=e},t.prototype.setValidationFailedForMinCollectionSizeMessage=function(e){this.validationFailedForMaxCollectionSizeMessage_=e},t.prototype.setValidationFailedForMinimumMessage=function(e){this.validationFailedForMinimumMessage_=e},t.prototype.setValidationFailedForMinLengthMessage=function(e){this.validationFailedForMinLengthMessage_=e},t.prototype.setValidationFailedForPatternMessage=function(e){this.validationFailedForPatternMessage_=e},t.prototype.setValidationFailedForRequiredMessage=function(e){this.validationFailedForRequiredMessage_=e},t.prototype.setValidationFailedForEmailTypeMessage=function(e){this.validationFailedForEmailTypeMessage_=e},t.prototype.setValidationFailedForIntegerTypeMessage=function(e){this.validationFailedForIntegerTypeMessage_=e},t.prototype.setValidationFailedForNegativeTypeMessage=function(e){this.validationFailedForNegativeTypeMessage_=e},t.prototype.setValidationFailedForNonNegativeTypeMessage=function(e){this.validationFailedForNonNegativeTypeMessage_=e},t.prototype.setValidationFailedForNumericTypeMessage=function(e){this.validationFailedForNumericTypeMessage_=e},t.prototype.setValidationFailedForPositiveTypeMessage=function(e){this.validationFailedForPositiveTypeMessage_=e},t}();e.FormForConfiguration=t,angular.module("formFor").service("FormForConfiguration",function(){return new t})}(formFor||(formFor={}));var formFor;!function(e){var t=function(){function t(e){this.formForConfiguration_=e}return t.prototype.manageLabel=function(t,i,r){this.formForConfiguration_.autoGenerateLabels&&(t.label=r?e.StringUtil.humanize(t.value):e.StringUtil.humanize(t.attribute)),this.formForConfiguration_.labelClass&&(t.labelClass=this.formForConfiguration_.labelClass),i.hasOwnProperty("label")&&i.$observe("label",function(e){t.label=e}),i.hasOwnProperty("labelClass")&&i.$observe("labelClass",function(e){t.labelClass=e})},t.prototype.manageFieldRegistration=function(e,t,i){e.$watch("attribute",function(r,o){e.model&&i.unregisterFormField(o),e.model=i.registerFormField(e.attribute),t.uid&&(e.model.uid=t.uid)}),e.$on("$destroy",function(){i.unregisterFormField(e.attribute)})},t}();e.FieldHelper=t,angular.module("formFor").service("FieldHelper",["FormForConfiguration",function(e){return new t(e)}])}(formFor||(formFor={}));var formFor;!function(e){var t,i,r=function(){function e(e,r){this.require="^formFor",this.restrict="EA",this.templateUrl=function(e,t){return t.template||"form-for/templates/checkbox-field.html"},this.scope={attribute:"@",disable:"=",help:"@?",changed:"&?"},t=e,i=r}return e.$inject=["$log","fieldHelper"],e.prototype.link=function(e,r,o,n){return e.attribute?(e.attributes=o,e.tabIndex=o.tabIndex||0,e.toggle=function(){e.disable||e.model.disabled||(e.model.bindable=!e.model.bindable)},e.$watch("model.bindable",function(t){e.model&&(e.model.bindable=e.model.required?t||void 0:!!t)}),i.manageLabel(e,o,!1),void i.manageFieldRegistration(e,o,n)):void t.error('Missing required field "attribute"')},e.prototype.link.$inject=["$scope","$element","$attributes","formForController"],e}();e.CheckboxFieldDirective=r,angular.module("formFor").directive("checkboxField",["$log","FieldHelper",function(e,t){return new r(e,t)}])}(formFor||(formFor={}));var formFor;!function(e){var t,i=function(){function e(e){this.require="^formFor",this.restrict="EA",this.templateUrl=function(e,t){return t.template||"form-for/templates/collection-label.html"},this.scope={attribute:"@",help:"@?",label:"@"},t=e}return e.$inject=["$sce"],e.prototype.link=function(e,i,r,o){e.$watch("label",function(i){e.bindableLabel=t.trustAsHtml(i)}),e.model=o.registerCollectionLabel(e.attribute)},e.prototype.link.$inject=["$scope","$element","$attributes","formForController"],e}();e.CollectionLabelDirective=i,angular.module("formFor").directive("collectionLabel",["$sce",function(e){return new i(e)}])}(formFor||(formFor={}));var formFor;!function(e){var t=function(){function e(){this.restrict="EA",this.templateUrl=function(e,t){return t.template||"form-for/templates/field-error.html"},this.scope={error:"=",leftAligned:"@?",uid:"@"}}return e.prototype.link=function(e){},e.prototype.link.$inject=["$scope"],e}();e.FieldErrorDirective=t,angular.module("formFor").directive("fieldError",function(){return new t})}(formFor||(formFor={}));var formFor;!function(e){var t,i,r=function(){function e(e,r){this.replace=!0,this.restrict="EA",this.templateUrl=function(e,t){return t.template||"form-for/templates/field-label.html"},this.scope={inputUid:"@",help:"@?",label:"@",labelClass:"@?",required:"@?",uid:"@"},t=e,i=r}return e.$inject=["$sce","formForConfiguration"],e.prototype.link=function(e,r,o){e.attributes=o,e.helpIcon=i.helpIcon,e.$watch("label",function(i){e.bindableLabel=t.trustAsHtml(i)}),e.$watch("required",function(t){e.requiredLabel=e.$eval(t)?i.requiredLabel:null})},e.prototype.link.$inject=["$scope","$element","$attributes"],e}();e.FieldLabelDirective=r,angular.module("formFor").directive("fieldLabel",["$sce","FormForConfiguration",function(e,t){return new r(e,t)}])}(formFor||(formFor={}));var formFor;!function(e){var t,i,r=function(){function r(r,o){this.require="^formFor",this.restrict="A",t=r,i=new e.NestedObjectHelper(o)}return r.$inject=["$compile","$parse"],r.prototype.link=function(r,o,n,a){var l;n.formForBuilder?l=r.$eval(n.formForBuilder):n.validationRules?l=r.$eval(n.validationRules):n.$service&&(l=r.$eval(n.$service.validationRules));for(var s=i.flattenObjectKeys(l),u="",d=0,c=s.length;c>d;d++){var f=s[d],p=i.readAttribute(l,f);if(p&&p.hasOwnProperty("inputType")){var m,F=p.help||"",b=p.label||"",h="",v=p.template||"",g=p.uid||"",y=b?'label="'+b+'"':"";switch(p.hasOwnProperty("placeholder")&&(h='placeholder="'+p.placeholder+'"'),p.inputType){case e.BuilderFieldType.CHECKBOX:u+='\n ';break;case e.BuilderFieldType.RADIO:m=JSON.stringify(p.values).replace(/"/g,"""),u+='\n ';break;case e.BuilderFieldType.SELECT:m=JSON.stringify(p.values).replace(/"/g,"""),u+='\n ';break;case e.BuilderFieldType.NUMBER:case e.BuilderFieldType.PASSWORD:case e.BuilderFieldType.TEXT:default:var h;p.hasOwnProperty("placeholder")&&(h='placeholder="'+p.placeholder+'"'),u+='\n '}}}0===o.find("input[type=button], button, submit-button").length&&(u+='');var E=t(u),_=E(r,void 0,{transcludeControllers:a});o.prepend(_)},r.prototype.link.$inject=["$scope","$element","$attributes","formForController"],r}();e.FormForBuilderDirective=r,angular.module("formFor").directive("formForBuilder",["$compile","$parse",function(e,t){return new r(e,t)}])}(formFor||(formFor={}));var formFor;!function(e){var t,i,r,o,n=function(){function e(e,n,a,l){this.priority=99,this.require="ngModel",this.restrict="A",this.scope={formForDebounce:"@"},t=e,i=n,r=a,o=l}return e.$inject=["$log","$sniffer","$timeout","formForConfiguration"],e.prototype.link=function(e,n,a,l){if("radio"===a.type||"checkbox"===a.type)return void t.warn("formForDebounce should only be used with and