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