You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

angular-auto-validate

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-auto-validate - npm Package Compare versions

Comparing version

to
1.18.14

dist/lang/jcs-auto-validate_es-co.json

2

bower.json
{
"name": "angular-auto-validate",
"version": "1.18.6",
"version": "1.18.14",
"description": "An automatic validation module for AngularJS which gets rid of excess html in favour of dynamic element modification to notify the user of validation errors",

@@ -5,0 +5,0 @@ "main": "dist/jcs-auto-validate.js",

@@ -0,1 +1,32 @@

V1.18.14 23/08/2015
Fixed issue with globally changing default form validation options.
V1.18.13 21/08/2015
Added a default value for the form option validateOnFormSubmit in the validator.
V1.18.12 20/08/2015
Added the ability to defer validation until after a form submit by adding the attribute 'validate-on-form-submit="true"'
to the form element.
V1.18.11 20/08/2015
Fixed issue ngModelDecorator not working with angular-material due to incorrect pre and post function invocations
V1.18.10 03/08/2015
Fixed issue #61 with globally disabling the library and enabling it for a particular form
V1.18.9 03/08/2015
Fixed #68
Setting form to untouched and pristine when a form reset is requested
V1.18.8 03/08/2015
Reset a form programatically is now possible via the resetForm method on the form controllers autoValidateFormOptions object
or by raising the event 'form:{formName}:reset on the controllers scope. The formName is the value in the name attribute
on the form tag which also corresponds to the formController.$name property.
Fixes issue with removing external validation raised in https://github.com/jonsamwell/angular-auto-validate/issues/39
V1.18.7 01/08/2015
Added Spanish i18n file.
Fixed issue https://github.com/jonsamwell/angular-auto-validate/issues/73
Added the ability to reset the form via the form controller (https://github.com/jonsamwell/angular-auto-validate/issues/82)
V1.18.6 16/04/2015

@@ -2,0 +33,0 @@ Increased limit on findWithClassElementAsc in BS3Modifier to find an element.

/*
* angular-auto-validate - v1.18.6 - 2015-04-16
* angular-auto-validate - v1.18.14 - 2015-08-23
* https://github.com/jonsamwell/angular-auto-validate
* Copyright (c) 2015 Jon Samwell (http://www.jonsamwell.com)
*/
(function (angular) {
(function (String, angular) {
'use strict';
angular.module('jcs-autoValidate', []);
}(angular));
angular.module('jcs-autoValidate', []);
(function (angular) {
'use strict';
function ValidatorFn() {
var elementStateModifiers = {},
enableValidElementStyling = true,
enableInvalidElementStyling = true,
validationEnabled = true,
angular.module('jcs-autoValidate')
.provider('validator', [
function () {
var elementStateModifiers = {},
enableValidElementStyling = true,
enableInvalidElementStyling = true,
validationEnabled = true,
toBoolean = function (value) {
var v;
if (value && value.length !== 0) {
v = value.toLowerCase();
value = !(v === 'f' || v === '0' || v === 'false');
} else {
value = false;
}
toBoolean = function (value) {
var v;
if (value && value.length !== 0) {
v = value.toLowerCase();
value = !(v === 'f' || v === '0' || v === 'false');
} else {
value = false;
}
return value;
},
return value;
},
getAttributeValue = function (el, attrName) {
var val;
getAttributeValue = function (el, attrName) {
var val;
if (el !== undefined) {
val = el.attr(attrName) || el.attr('data-' + attrName);
}
if (el !== undefined) {
val = el.attr(attrName) || el.attr('data-' + attrName);
}
return val;
},
return val;
},
attributeExists = function (el, attrName) {
var exists;
attributeExists = function (el, attrName) {
var exists;
if (el !== undefined) {
exists = el.attr(attrName) !== undefined || el.attr('data-' + attrName) !== undefined;
}
if (el !== undefined) {
exists = el.attr(attrName) !== undefined || el.attr('data-' + attrName) !== undefined;
}
return exists;
},
return exists;
},
getBooleanAttributeValue = function (el, attrName) {
return toBoolean(getAttributeValue(el, attrName));
},
getBooleanAttributeValue = function (el, attrName) {
return toBoolean(getAttributeValue(el, attrName));
},
validElementStylingEnabled = function (el) {
return enableValidElementStyling && !getBooleanAttributeValue(el, 'disable-valid-styling');
},
validElementStylingEnabled = function (el) {
return enableValidElementStyling && !getBooleanAttributeValue(el, 'disable-valid-styling');
},
invalidElementStylingEnabled = function (el) {
return enableInvalidElementStyling && !getBooleanAttributeValue(el, 'disable-invalid-styling');
};
invalidElementStylingEnabled = function (el) {
return enableInvalidElementStyling && !getBooleanAttributeValue(el, 'disable-invalid-styling');
};
/**
* @ngdoc function
* @name validator#enable
* @methodOf validator
*
* @description
* By default auto validate will validate all forms and elements with an ngModel directive on. By
* setting enabled to false you will explicitly have to opt in to enable validation on forms and child
* elements.
*
* Note: this can be overridden by add the 'auto-validate-enabled="true/false' attribute to a form.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.enable(false);
* });
* </pre>
*
* @param {Boolean} isEnabled true to enable, false to disable.
*/
this.enable = function (isEnabled) {
validationEnabled = isEnabled;
};
/**
* @ngdoc function
* @name validator#enable
* @methodOf validator
*
* @description
* By default auto validate will validate all forms and elements with an ngModel directive on. By
* setting enabled to false you will explicitly have to opt in to enable validation on forms and child
* elements.
*
* Note: this can be overridden by add the 'auto-validate-enabled="true/false' attribute to a form.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.enable(false);
* });
* </pre>
*
* @param {Boolean} isEnabled true to enable, false to disable.
*/
this.enable = function (isEnabled) {
validationEnabled = isEnabled;
};
/**
* @ngdoc function
* @name validator#isEnabled
* @methodOf validator
*
* @description
* Returns true if the library is enabeld.
*
* @return {Boolean} true if enabled, otherwise false.
*/
this.isEnabled = function () {
return validationEnabled;
};
/**
* @ngdoc function
* @name validator#isEnabled
* @methodOf validator
*
* @description
* Returns true if the library is enabeld.
*
* @return {Boolean} true if enabled, otherwise false.
*/
this.isEnabled = function () {
return validationEnabled;
};
/**
* @ngdoc function
* @name validator#setDefaultElementModifier
* @methodOf validator
*
* @description
* Sets the default element modifier that will be used by the validator
* to change an elements UI state. Please ensure the modifier has been registered
* before setting it as default.
*
* Note: this can be changed by setting the
* element modifier attribute on the input element 'data-element-modifier="myCustomModifier"'
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setDefaultElementModifier('myCustomModifier');
* });
* </pre>
*
* @param {string} key The key name of the modifier.
*/
this.setDefaultElementModifier = function (key) {
if (elementStateModifiers[key] === undefined) {
throw new Error('Element modifier not registered: ' + key);
}
/**
* @ngdoc function
* @name validator#setDefaultElementModifier
* @methodOf validator
*
* @description
* Sets the default element modifier that will be used by the validator
* to change an elements UI state. Please ensure the modifier has been registered
* before setting it as default.
*
* Note: this can be changed by setting the
* element modifier attribute on the input element 'data-element-modifier="myCustomModifier"'
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setDefaultElementModifier('myCustomModifier');
* });
* </pre>
*
* @param {string} key The key name of the modifier.
*/
this.setDefaultElementModifier = function (key) {
if (elementStateModifiers[key] === undefined) {
throw new Error('Element modifier not registered: ' + key);
}
this.defaultElementModifier = key;
};
this.defaultElementModifier = key;
};
/**
* @ngdoc function
* @name validator#registerDomModifier
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.registerDomModifier('customDomModifier', {
* makeValid: function (el) {
* el.removeClass(el, 'invalid');
* el.addClass(el, 'valid');
* },
* makeInvalid: function (el, err, domManipulator) {
* el.removeClass(el, 'valid');
* el.addClass(el, 'invalid');
* }
* });
* });
* </pre>
*
* @param {string} key The key name of the modifier
* @param {object} modifier An object which implements the elementModifier interface
*/
this.registerDomModifier = function (key, modifier) {
elementStateModifiers[key] = modifier;
};
/**
* @ngdoc function
* @name validator#registerDomModifier
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.registerDomModifier('customDomModifier', {
* makeValid: function (el) {
* el.removeClass(el, 'invalid');
* el.addClass(el, 'valid');
* },
* makeInvalid: function (el, err, domManipulator) {
* el.removeClass(el, 'valid');
* el.addClass(el, 'invalid');
* }
* });
* });
* </pre>
*
* @param {string} key The key name of the modifier
* @param {object} modifier An object which implements the elementModifier interface
*/
this.registerDomModifier = function (key, modifier) {
elementStateModifiers[key] = modifier;
};
/**
* @ngdoc function
* @name validator#setErrorMessageResolver
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setErrorMessageResolver(function (errorKey, el) {
* var defer = $q.defer();
* // resolve the correct error from the given key and resolve the returned promise.
* return defer.promise();
* });
* });
* </pre>
*
* @param {function} resolver A method that returns a promise with the resolved error message in.
*/
this.setErrorMessageResolver = function (resolver) {
this.errorMessageResolver = resolver;
};
/**
* @ngdoc function
* @name validator#setErrorMessageResolver
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setErrorMessageResolver(function (errorKey, el) {
* var defer = $q.defer();
* // resolve the correct error from the given key and resolve the returned promise.
* return defer.promise();
* });
* });
* </pre>
*
* @param {function} resolver A method that returns a promise with the resolved error message in.
*/
this.setErrorMessageResolver = function (resolver) {
this.errorMessageResolver = resolver;
};
/**
* @ngdoc function
* @name validator#getErrorMessage
* @methodOf validator
*
* @description
* Resolves the error message for the given error type.
*
* @param {String} errorKey The error type.
* @param {Element} el The UI element that is the focus of the error.
* It is provided as the error message may need information from the element i.e. ng-min (the min allowed value).
*/
this.getErrorMessage = function (errorKey, el) {
var defer;
if (this.errorMessageResolver === undefined) {
throw new Error('Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
}
/**
* @ngdoc function
* @name validator#getErrorMessage
* @methodOf validator
*
* @description
* Resolves the error message for the given error type.
*
* @param {String} errorKey The error type.
* @param {Element} el The UI element that is the focus of the error.
* It is provided as the error message may need information from the element i.e. ng-min (the min allowed value).
*/
this.getErrorMessage = function (errorKey, el) {
var defer;
if (this.errorMessageResolver === undefined) {
throw new Error('Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
}
if (attributeExists(el, 'disable-validation-message')) {
defer = angular.injector(['ng']).get('$q').defer();
defer.resolve('');
return defer.promise;
} else {
return this.errorMessageResolver(errorKey, el);
}
};
if (attributeExists(el, 'disable-validation-message')) {
defer = angular.injector(['ng']).get('$q').defer();
defer.resolve('');
return defer.promise;
} else {
return this.errorMessageResolver(errorKey, el);
}
};
/**
* @ngdoc function
* @name validator#setValidElementStyling
* @methodOf validator
*
* @description
* Globally enables valid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setValidElementStyling = function (enabled) {
enableValidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setValidElementStyling
* @methodOf validator
*
* @description
* Globally enables valid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setValidElementStyling = function (enabled) {
enableValidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setInvalidElementStyling
* @methodOf validator
*
* @description
* Globally enables invalid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setInvalidElementStyling = function (enabled) {
enableInvalidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setInvalidElementStyling
* @methodOf validator
*
* @description
* Globally enables invalid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setInvalidElementStyling = function (enabled) {
enableInvalidElementStyling = enabled;
};
this.getDomModifier = function (el) {
var modifierKey = (el !== undefined ? el.attr('element-modifier') : this.defaultElementModifier) ||
(el !== undefined ? el.attr('data-element-modifier') : this.defaultElementModifier) ||
this.defaultElementModifier;
this.getDomModifier = function (el) {
var modifierKey = (el !== undefined ? el.attr('element-modifier') : this.defaultElementModifier) ||
(el !== undefined ? el.attr('data-element-modifier') : this.defaultElementModifier) ||
this.defaultElementModifier;
if (modifierKey === undefined) {
throw new Error('Please set a default dom modifier via the setDefaultElementModifier method on the validator class.');
}
if (modifierKey === undefined) {
throw new Error('Please set a default dom modifier via the setDefaultElementModifier method on the validator class.');
}
return elementStateModifiers[modifierKey];
};
return elementStateModifiers[modifierKey];
};
this.makeValid = function (el) {
if (validElementStylingEnabled(el)) {
this.getDomModifier(el).makeValid(el);
} else {
this.makeDefault(el);
}
};
this.makeValid = function (el) {
if (validElementStylingEnabled(el)) {
this.getDomModifier(el).makeValid(el);
} else {
this.makeDefault(el);
}
};
this.makeInvalid = function (el, errorMsg) {
if (invalidElementStylingEnabled(el)) {
this.getDomModifier(el).makeInvalid(el, errorMsg);
} else {
this.makeDefault(el);
}
};
this.makeInvalid = function (el, errorMsg) {
if (invalidElementStylingEnabled(el)) {
this.getDomModifier(el).makeInvalid(el, errorMsg);
} else {
this.makeDefault(el);
}
};
this.makeDefault = function (el) {
var dm = this.getDomModifier(el);
if (dm.makeDefault) {
dm.makeDefault(el);
}
};
this.makeDefault = function (el) {
var dm = this.getDomModifier(el);
if (dm.makeDefault) {
dm.makeDefault(el);
}
};
this.defaultFormValidationOptions = {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false,
removeExternalValidationErrorsOnSubmit: true,
validateOnFormSubmit: false
};
this.defaultFormValidationOptions = {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false,
removeExternalValidationErrorsOnSubmit: true
};
this.$get = [
function () {
return this;
}
];
}
this.$get = [
function () {
return this;
}
];
}
]);
}(angular));
angular.module('jcs-autoValidate').provider('validator', ValidatorFn);
(function (angular) {
'use strict';
function Bootstrap3ElementModifierFn($log) {
var reset = function (el) {
angular.forEach(el.find('span'), function (spanEl) {
spanEl = angular.element(spanEl);
if (spanEl.hasClass('error-msg') || spanEl.hasClass('form-control-feedback') || spanEl.hasClass('control-feedback')) {
spanEl.remove();
}
});
angular.module('jcs-autoValidate')
.factory('bootstrap3ElementModifier', [
'$log',
function ($log) {
var reset = function (el) {
angular.forEach(el.find('span'), function (spanEl) {
spanEl = angular.element(spanEl);
if (spanEl.hasClass('error-msg') || spanEl.hasClass('form-control-feedback') || spanEl.hasClass('control-feedback')) {
spanEl.remove();
}
});
el.removeClass('has-success has-error has-feedback');
},
findWithClassElementAsc = function (el, klass) {
var returnEl,
parent = el;
for (var i = 0; i <= 10; i += 1) {
if (parent !== undefined && parent.hasClass(klass)) {
returnEl = parent;
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
el.removeClass('has-success has-error has-feedback');
},
findWithClassElementAsc = function (el, klass) {
var returnEl,
parent = el;
for (var i = 0; i <= 10; i += 1) {
if (parent !== undefined && parent.hasClass(klass)) {
returnEl = parent;
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
return returnEl;
},
return returnEl;
},
findWithClassElementDesc = function (el, klass) {
var child;
for (var i = 0; i < el.children.length; i += 1) {
child = el.children[i];
if (child !== undefined && angular.element(child).hasClass(klass)) {
break;
} else if (child.children !== undefined) {
child = findWithClassElementDesc(child, klass);
if (child.length > 0) {
break;
}
}
}
findWithClassElementDesc = function (el, klass) {
var child;
for (var i = 0; i < el.children.length; i += 1) {
child = el.children[i];
if (child !== undefined && angular.element(child).hasClass(klass)) {
break;
} else if (child.children !== undefined) {
child = findWithClassElementDesc(child, klass);
if (child.length > 0) {
break;
}
}
}
return angular.element(child);
},
return angular.element(child);
},
findFormGroupElement = function (el) {
return findWithClassElementAsc(el, 'form-group');
},
findFormGroupElement = function (el) {
return findWithClassElementAsc(el, 'form-group');
},
findInputGroupElement = function (el) {
return findWithClassElementDesc(el, 'input-group');
},
findInputGroupElement = function (el) {
return findWithClassElementDesc(el, 'input-group');
},
insertAfter = function (referenceNode, newNode) {
referenceNode[0].parentNode.insertBefore(newNode[0], referenceNode[0].nextSibling);
},
insertAfter = function (referenceNode, newNode) {
referenceNode[0].parentNode.insertBefore(newNode[0], referenceNode[0].nextSibling);
},
/**
* @ngdoc property
* @name bootstrap3ElementModifier#addValidationStateIcons
* @propertyOf bootstrap3ElementModifier
* @returns {bool} True if an state icon will be added to the element in the valid and invalid control
* states. The default is false.
*/
addValidationStateIcons = false,
/**
* @ngdoc property
* @name bootstrap3ElementModifier#addValidationStateIcons
* @propertyOf bootstrap3ElementModifier
* @returns {bool} True if an state icon will be added to the element in the valid and invalid control
* states. The default is false.
*/
addValidationStateIcons = false,
/**
* @ngdoc function
* @name bootstrap3ElementModifier#enableValidationStateIcons
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply an icon to the input element.
*
* @param {bool} enable - True to enable the icon otherwise false.
*/
enableValidationStateIcons = function (enable) {
addValidationStateIcons = enable;
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#enableValidationStateIcons
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply an icon to the input element.
*
* @param {bool} enable - True to enable the icon otherwise false.
*/
enableValidationStateIcons = function (enable) {
addValidationStateIcons = enable;
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeValid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear valid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var frmGroupEl = findFormGroupElement(el),
inputGroupEl;
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeValid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear valid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var frmGroupEl = findFormGroupElement(el),
inputGroupEl;
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-success ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-ok form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-success ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-ok form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeInvalid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var frmGroupEl = findFormGroupElement(el),
helpTextEl = angular.element('<span class="help-block has-error error-msg">' + errorMsg + '</span>'),
inputGroupEl;
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeInvalid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var frmGroupEl = findFormGroupElement(el),
helpTextEl = angular.element('<span class="help-block has-error error-msg">' + errorMsg + '</span>'),
inputGroupEl;
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-error ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
insertAfter(inputGroupEl.length > 0 ? inputGroupEl : el, helpTextEl);
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-remove form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-error ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
insertAfter(inputGroupEl.length > 0 ? inputGroupEl : el, helpTextEl);
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-remove form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeDefault
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply bootstrap 3 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
var frmGroupEl = findFormGroupElement(el);
if (frmGroupEl) {
reset(frmGroupEl);
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
};
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeDefault
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply bootstrap 3 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
var frmGroupEl = findFormGroupElement(el);
if (frmGroupEl) {
reset(frmGroupEl);
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
};
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
enableValidationStateIcons: enableValidationStateIcons,
key: 'bs3'
};
}
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
enableValidationStateIcons: enableValidationStateIcons,
key: 'bs3'
};
}
]);
}(angular));
Bootstrap3ElementModifierFn.$inject = [
'$log'
];
(function (angular) {
'use strict';
angular.module('jcs-autoValidate').factory('bootstrap3ElementModifier', Bootstrap3ElementModifierFn);
/*
* Taken from https://github.com/angular/angular.js/issues/2690#issue-14462164 (with added tests of course!)
/*
* Taken from https://github.com/angular/angular.js/issues/2690#issue-14462164 (with added tests of course!)
*/
function JCSDebounceFn($timeout) {
var debounce = function (fn, timeout, apply) {
timeout = angular.isUndefined(timeout) ? 0 : timeout;
apply = angular.isUndefined(apply) ? true : apply; // !!default is true! most suitable to my experience
var nthCall = 0;
return function () { // intercepting fn
var that = this;
var argz = arguments;
nthCall += 1;
var later = (function (version) {
return function () {
if (version === nthCall) {
return fn.apply(that, argz);
}
};
})(nthCall);
return $timeout(later, timeout, apply);
};
};
return {
debounce: debounce
};
}
JCSDebounceFn.$inject = [
'$timeout'
];
angular.module('jcs-autoValidate').factory('jcs-debounce', JCSDebounceFn);
/**
* Replaces string placeholders with corresponding template string
*/
if (!('format' in String.prototype)) {
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] !== undefined ? args[number] : match;
});
};
}
angular.autoValidate = angular.autoValidate || {
errorMessages: {}
};
angular.autoValidate.errorMessages['en-us'] = angular.autoValidate.errorMessages['en-gb'] = {
defaultMsg: 'Please add error message for {0}',
email: 'Please enter a valid email address',
minlength: 'Please enter at least {0} characters',
maxlength: 'You have entered more than the maximum {0} characters',
min: 'Please enter the minimum number of {0}',
max: 'Please enter the maximum number of {0}',
required: 'This field is required',
date: 'Please enter a valid date',
pattern: 'Please ensure the entered information adheres to this pattern {0}',
number: 'Please enter a valid number',
url: 'Please enter a valid URL in the format of http(s)://www.google.com'
};
function DefaultErrorMessageResolverFn($q, $http) {
var currentCulture = 'en-gb',
i18nFileRootPath = 'js/angular-auto-validate/dist/lang',
cultureRetrievalPromise,
loadRemoteCulture = function (culture) {
cultureRetrievalPromise = $http.get('{0}/jcs-auto-validate_{1}.json'.format(i18nFileRootPath, culture.toLowerCase()));
return cultureRetrievalPromise;
},
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setI18nFileRootPath
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the root path to the il8n files on the server
*
* @param {String} rootPath - The root path on the server to the il8n file - this defaults
* to 'js/angular-auto-validate/lang/'
*/
angular.module('jcs-autoValidate').factory('jcs-debounce', [
'$timeout',
function ($timeout) {
var debounce = function (fn, timeout, apply) {
timeout = angular.isUndefined(timeout) ? 0 : timeout;
apply = angular.isUndefined(apply) ? true : apply; // !!default is true! most suitable to my experience
var nthCall = 0;
return function () { // intercepting fn
var that = this;
var argz = arguments;
nthCall += 1;
var later = (function (version) {
return function () {
if (version === nthCall) {
return fn.apply(that, argz);
}
};
})(nthCall);
setI18nFileRootPath = function (rootPath) {
i18nFileRootPath = rootPath;
},
return $timeout(later, timeout, apply);
};
};
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setCulture
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the culture for the error messages by loading an the correct culture resource file.
*
* @param {String} culture - The new culture in the format of 'en-gb' etc.
* @param {Function} cultureLoadingFn - A optional function to load the culture resolve which should
* return a promise which is resolved with the culture errorMessage object. If a function is not specified
* the culture file is loaded from the **i18nFileRootPath**.
* @returns {Promise} - A promise which is resolved with the loaded culture error messages object.
*/
setCulture = function (culture, cultureLoadingFn) {
var defer = $q.defer();
cultureLoadingFn = cultureLoadingFn || loadRemoteCulture;
currentCulture = culture.toLowerCase();
if (angular.autoValidate.errorMessages[currentCulture] === undefined) {
cultureRetrievalPromise = cultureLoadingFn(culture);
cultureRetrievalPromise.then(function (response) {
cultureRetrievalPromise = undefined;
angular.autoValidate.errorMessages[currentCulture] = response.data;
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}, function (err) {
angular.autoValidate.errorMessages[currentCulture] = {
defaultMsg: 'Loading culture failed!'
};
cultureRetrievalPromise = null;
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}
return {
debounce: debounce
};
return defer.promise;
},
getErrorMessages = function (culture) {
var defer = $q.defer();
culture = culture === undefined ? currentCulture : culture.toLowerCase();
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}, function (err) {
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}
return defer.promise;
},
getMessageTypeOverride = function (errorType, el) {
var overrideKey;
if (el) {
// try and find an attribute which overrides the given error type in the form of errorType-err-type="someMsgKey"
errorType += '-err-type';
overrideKey = el.attr('ng-' + errorType);
if (overrideKey === undefined) {
overrideKey = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
]);
}(angular));
(function (String, angular) {
'use strict';
if (overrideKey) {
overrideKey = overrideKey.replace(/[\W]/g, '');
}
}
return overrideKey;
},
/**
* Replaces string placeholders with corresponding template string
* @ngdoc function
* @name defaultErrorMessageResolver#resolve
* @methodOf defaultErrorMessageResolver
*
* @description
* Resolves a validate error type into a user validation error message
*
* @param {String} errorType - The type of validation error that has occurred.
* @param {Element} el - The input element that is the source of the validation error.
* @returns {Promise} A promise that is resolved when the validation message has been produced.
*/
if (!('format' in String.prototype)) {
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] !== undefined ? args[number] : match;
});
};
}
resolve = function (errorType, el) {
var defer = $q.defer(),
errMsg,
parameters = [],
parameter,
messageTypeOverride;
angular.autoValidate = angular.autoValidate || {
errorMessages: {}
};
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
resolve(errorType, el).then(function (msg) {
defer.resolve(msg);
});
});
} else {
errMsg = angular.autoValidate.errorMessages[currentCulture][errorType];
messageTypeOverride = getMessageTypeOverride(errorType, el);
if (messageTypeOverride) {
errMsg = angular.autoValidate.errorMessages[currentCulture][messageTypeOverride];
}
angular.autoValidate.errorMessages['en-us'] = angular.autoValidate.errorMessages['en-gb'] = {
defaultMsg: 'Please add error message for {0}',
email: 'Please enter a valid email address',
minlength: 'Please enter at least {0} characters',
maxlength: 'You have entered more than the maximum {0} characters',
min: 'Please enter the minimum number of {0}',
max: 'Please enter the maximum number of {0}',
required: 'This field is required',
date: 'Please enter a valid date',
pattern: 'Please ensure the entered information adheres to this pattern {0}',
number: 'Please enter a valid number',
url: 'Please enter a valid URL in the format of http(s)://www.google.com'
};
if (errMsg === undefined) {
errMsg = angular.autoValidate.errorMessages[currentCulture].defaultMsg.format(errorType);
}
angular.module('jcs-autoValidate')
.factory('defaultErrorMessageResolver', [
'$q',
'$http',
function ($q, $http) {
var currentCulture = 'en-gb',
if (el && el.attr) {
try {
parameter = el.attr('ng-' + errorType);
if (parameter === undefined) {
parameter = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
i18nFileRootPath = 'js/angular-auto-validate/dist/lang',
parameters.push(parameter || '');
cultureRetrievalPromise,
errMsg = errMsg.format(parameters);
} catch (e) {}
}
loadRemoteCulture = function (culture) {
cultureRetrievalPromise = $http.get('{0}/jcs-auto-validate_{1}.json'.format(i18nFileRootPath, culture.toLowerCase()));
return cultureRetrievalPromise;
},
defer.resolve(errMsg);
}
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setI18nFileRootPath
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the root path to the il8n files on the server
*
* @param {String} rootPath - The root path on the server to the il8n file - this defaults
* to 'js/angular-auto-validate/lang/'
*/
setI18nFileRootPath = function (rootPath) {
i18nFileRootPath = rootPath;
},
return defer.promise;
};
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setCulture
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the culture for the error messages by loading an the correct culture resource file.
*
* @param {String} culture - The new culture in the format of 'en-gb' etc.
* @param {Function} cultureLoadingFn - A optional function to load the culture resolve which should
* return a promise which is resolved with the culture errorMessage object. If a function is not specified
* the culture file is loaded from the **i18nFileRootPath**.
* @returns {Promise} - A promise which is resolved with the loaded culture error messages object.
*/
setCulture = function (culture, cultureLoadingFn) {
var defer = $q.defer();
cultureLoadingFn = cultureLoadingFn || loadRemoteCulture;
currentCulture = culture.toLowerCase();
if (angular.autoValidate.errorMessages[currentCulture] === undefined) {
cultureRetrievalPromise = cultureLoadingFn(culture);
cultureRetrievalPromise.then(function (response) {
cultureRetrievalPromise = undefined;
angular.autoValidate.errorMessages[currentCulture] = response.data;
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}, function (err) {
angular.autoValidate.errorMessages[currentCulture] = {
defaultMsg: 'Loading culture failed!'
};
cultureRetrievalPromise = null;
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}
return {
setI18nFileRootPath: setI18nFileRootPath,
setCulture: setCulture,
getErrorMessages: getErrorMessages,
resolve: resolve
};
}
return defer.promise;
},
DefaultErrorMessageResolverFn.$inject = [
'$q',
'$http'
];
getErrorMessages = function (culture) {
var defer = $q.defer();
culture = culture === undefined ? currentCulture : culture.toLowerCase();
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}, function (err) {
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}
return defer.promise;
},
angular.module('jcs-autoValidate').factory('defaultErrorMessageResolver', DefaultErrorMessageResolverFn);
getMessageTypeOverride = function (errorType, el) {
var overrideKey;
function Foundation5ElementModifierFn() {
var reset = function (el, inputEl) {
angular.forEach(el.find('small'), function (smallEl) {
if (angular.element(smallEl).hasClass('error')) {
angular.element(smallEl).remove();
}
});
if (el) {
// try and find an attribute which overrides the given error type in the form of errorType-err-type="someMsgKey"
errorType += '-err-type';
inputEl.removeClass('error');
},
findParentColumn = function (el) {
var parent = el;
for (var i = 0; i <= 3; i += 1) {
if (parent !== undefined && parent.hasClass('columns')) {
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
return parent;
},
overrideKey = el.attr('ng-' + errorType);
if (overrideKey === undefined) {
overrideKey = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
/**
* @ngdoc function
* @name foundation5ElementModifier#makeValid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear valid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var parentColumn = findParentColumn(el);
reset(parentColumn && parentColumn.length > 0 ? parentColumn : el, el);
},
if (overrideKey) {
overrideKey = overrideKey.replace(/[\W]/g, '');
}
}
/**
* @ngdoc function
* @name foundation5ElementModifier#makeInvalid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear invalid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var parentColumn = findParentColumn(el),
helpTextEl;
reset(parentColumn || el, el);
el.addClass('error');
if (parentColumn) {
helpTextEl = angular.element('<small class="error">' + errorMsg + '</small>');
parentColumn.append(helpTextEl);
}
},
return overrideKey;
},
/**
* @ngdoc function
* @name foundation5ElementModifier#makeDefault
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply foundation 5 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
makeValid(el);
};
/**
* @ngdoc function
* @name defaultErrorMessageResolver#resolve
* @methodOf defaultErrorMessageResolver
*
* @description
* Resolves a validate error type into a user validation error message
*
* @param {String} errorType - The type of validation error that has occurred.
* @param {Element} el - The input element that is the source of the validation error.
* @returns {Promise} A promise that is resolved when the validation message has been produced.
*/
resolve = function (errorType, el) {
var defer = $q.defer(),
errMsg,
parameters = [],
parameter,
messageTypeOverride;
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
key: 'foundation5'
};
}
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
resolve(errorType, el).then(function (msg) {
defer.resolve(msg);
});
});
} else {
errMsg = angular.autoValidate.errorMessages[currentCulture][errorType];
messageTypeOverride = getMessageTypeOverride(errorType, el);
if (messageTypeOverride) {
errMsg = angular.autoValidate.errorMessages[currentCulture][messageTypeOverride];
}
angular.module('jcs-autoValidate').factory('foundation5ElementModifier', Foundation5ElementModifierFn);
if (errMsg === undefined) {
errMsg = angular.autoValidate.errorMessages[currentCulture].defaultMsg.format(errorType);
}
function ElementUtilsFn() {
var isElementVisible = function (el) {
return el[0].offsetWidth > 0 && el[0].offsetHeight > 0;
};
if (el && el.attr) {
try {
parameter = el.attr('ng-' + errorType);
if (parameter === undefined) {
parameter = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
return {
isElementVisible: isElementVisible
};
}
parameters.push(parameter || '');
function ValidationManagerFn(validator, elementUtils) {
var elementTypesToValidate = ['input', 'textarea', 'select', 'form'],
errMsg = errMsg.format(parameters);
} catch (e) {}
}
elementIsVisible = function (el) {
return elementUtils.isElementVisible(el);
},
defer.resolve(errMsg);
}
getFormOptions = function (el) {
var frmCtrl = angular.element(el).controller('form'),
options;
return defer.promise;
};
if (frmCtrl !== undefined && frmCtrl !== null) {
options = frmCtrl.autoValidateFormOptions;
} else {
options = validator.defaultFormValidationOptions;
}
return {
setI18nFileRootPath: setI18nFileRootPath,
setCulture: setCulture,
getErrorMessages: getErrorMessages,
resolve: resolve
};
}
]);
}(String, angular));
return options;
},
(function (angular) {
'use strict';
/**
* Only validate if the element is present, it is visible
* it is either a valid user input control (input, select, textare, form) or
* it is a custom control register by the developer.
* @param el
* @param formOptions The validation options of the parent form
* @returns {boolean} true to indicate it should be validated
*/
shouldValidateElement = function (el, formOptions, formSubmitted) {
var elementExists = el && el.length > 0,
correctVisibilityToValidate,
correctTypeToValidate,
correctPhaseToValidate;
angular.module('jcs-autoValidate')
.factory('foundation5ElementModifier', [
if (elementExists) {
correctVisibilityToValidate = elementIsVisible(el) || formOptions.validateNonVisibleControls;
correctTypeToValidate = elementTypesToValidate.indexOf(el[0].nodeName.toLowerCase()) > -1 ||
el[0].hasAttribute('register-custom-form-control');
correctPhaseToValidate = formOptions.validateOnFormSubmit === false ||
(formOptions.validateOnFormSubmit === true && formSubmitted === true);
}
function () {
var reset = function (el, inputEl) {
angular.forEach(el.find('small'), function (smallEl) {
if (angular.element(smallEl).hasClass('error')) {
angular.element(smallEl).remove();
}
});
return elementExists && correctVisibilityToValidate && correctTypeToValidate && correctPhaseToValidate;
inputEl.removeClass('error');
},
findParentColumn = function (el) {
var parent = el;
for (var i = 0; i <= 3; i += 1) {
if (parent !== undefined && parent.hasClass('columns')) {
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
},
return parent;
},
/**
* @ngdoc validateElement
* @name validation#validateElement
* @param {object} modelCtrl holds the information about the element e.g. $invalid, $valid
* @param {options}
* - forceValidation if set to true forces the validation even if the element is pristine
* - disabled if set to true forces the validation is disabled and will return true
* - validateNonVisibleControls if set to true forces the validation of non visible element i.e. display:block
* @description
* Validate the form element and make invalid/valid element model status.
*
* As of v1.17.22:
* BREAKING CHANGE to validateElement on the validationManger. The third parameter is now the parent form's
* autoValidateFormOptions object on the form controller. This can be left blank and will be found by the
* validationManager.
*/
validateElement = function (modelCtrl, el, options) {
var isValid = true,
frmOptions = options || getFormOptions(el),
needsValidation = modelCtrl.$pristine === false || frmOptions.forceValidation,
errorType,
findErrorType = function ($errors) {
var keepGoing = true,
errorTypeToReturn;
angular.forEach($errors, function (status, errortype) {
if (keepGoing && status) {
keepGoing = false;
errorTypeToReturn = errortype;
}
});
/**
* @ngdoc function
* @name foundation5ElementModifier#makeValid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear valid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var parentColumn = findParentColumn(el);
reset(parentColumn && parentColumn.length > 0 ? parentColumn : el, el);
},
return errorTypeToReturn;
};
/**
* @ngdoc function
* @name foundation5ElementModifier#makeInvalid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear invalid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var parentColumn = findParentColumn(el),
helpTextEl;
reset(parentColumn || el, el);
el.addClass('error');
if (parentColumn) {
helpTextEl = angular.element('<small class="error">' + errorMsg + '</small>');
parentColumn.append(helpTextEl);
}
},
if (frmOptions.disabled === false) {
if ((frmOptions.forceValidation ||
(shouldValidateElement(el, frmOptions, frmOptions.formController.$submitted) &&
modelCtrl &&
needsValidation))) {
isValid = !modelCtrl.$invalid;
/**
* @ngdoc function
* @name foundation5ElementModifier#makeDefault
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply foundation 5 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
makeValid(el);
};
if (frmOptions.removeExternalValidationErrorsOnSubmit && modelCtrl.removeAllExternalValidation) {
modelCtrl.removeAllExternalValidation();
}
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
key: 'foundation5'
};
if (isValid) {
validator.makeValid(el);
} else {
errorType = findErrorType(modelCtrl.$errors || modelCtrl.$error);
if (errorType === undefined) {
// we have a weird situation some users are encountering where a custom control
// is valid but the ngModel is report it isn't and thus no valid error type can be found
isValid = true;
} else {
validator.getErrorMessage(errorType, el).then(function (errorMsg) {
validator.makeInvalid(el, errorMsg);
});
}
]);
}(angular));
}
}
}
(function (angular) {
'use strict';
return isValid;
},
angular.module('jcs-autoValidate')
.factory('jcs-elementUtils', [
function () {
var isElementVisible = function (el) {
return el[0].offsetWidth > 0 && el[0].offsetHeight > 0;
};
resetElement = function (element) {
validator.makeDefault(element);
},
return {
isElementVisible: isElementVisible
};
}
]);
resetForm = function (frmElement) {
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (element) {
var controller,
ctrlElement = angular.element(element);
controller = ctrlElement.controller('ngModel');
angular.module('jcs-autoValidate')
.factory('validationManager', [
'validator',
'jcs-elementUtils',
function (validator, elementUtils) {
var elementTypesToValidate = ['input', 'textarea', 'select', 'form'],
if (controller !== undefined) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
resetForm(ctrlElement);
} else {
controller.$setPristine();
}
}
});
},
elementIsVisible = function (el) {
return elementUtils.isElementVisible(el);
},
validateForm = function (frmElement) {
var frmValid = true,
frmCtrl = frmElement ? angular.element(frmElement).controller('form') : undefined,
processElement = function (ctrlElement, force, formOptions) {
var controller, isValid, ctrlFormOptions, originalForceValue;
getFormOptions = function (el) {
var frmCtrl = angular.element(el).controller('form');
return frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : validator.defaultFormValidationOptions;
},
ctrlElement = angular.element(ctrlElement);
controller = ctrlElement.controller('ngModel');
/**
* Only validate if the element is present, it is visible
* it is either a valid user input control (input, select, textare, form) or
* it is a custom control register by the developer.
* @param el
* @param formOptions The validation options of the parent form
* @returns {boolean} true to indicate it should be validated
*/
shouldValidateElement = function (el, formOptions) {
var result = el &&
el.length > 0 &&
(elementIsVisible(el) || formOptions.validateNonVisibleControls) &&
(elementTypesToValidate.indexOf(el[0].nodeName.toLowerCase()) > -1 ||
el[0].hasAttribute('register-custom-form-control'));
return result;
},
if (controller !== undefined && (force || shouldValidateElement(ctrlElement, formOptions, frmCtrl.$submitted))) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
validateForm(ctrlElement);
} else {
// we need to get the options for the element rather than use the passed in as the
// element could be an ng-form and have different options to the parent form.
ctrlFormOptions = getFormOptions(ctrlElement);
originalForceValue = ctrlFormOptions.forceValidation;
ctrlFormOptions.forceValidation = force;
try {
isValid = validateElement(controller, ctrlElement, ctrlFormOptions);
frmValid = frmValid && isValid;
} finally {
ctrlFormOptions.forceValidation = originalForceValue;
}
}
}
},
clonedOptions;
/**
* @ngdoc validateElement
* @name validation#validateElement
* @param {object} modelCtrl holds the information about the element e.g. $invalid, $valid
* @param {options}
* - forceValidation if set to true forces the validation even if the element is pristine
* - disabled if set to true forces the validation is disabled and will return true
* - validateNonVisibleControls if set to true forces the validation of non visible element i.e. display:block
* @description
* Validate the form element and make invalid/valid element model status.
*
* As of v1.17.22:
* BREAKING CHANGE to validateElement on the validationManger. The third parameter is now the parent form's
* autoValidateFormOptions object on the form controller. This can be left blank and will be found by the
* validationManager.
*/
validateElement = function (modelCtrl, el, options) {
var isValid = true,
frmOptions = options || getFormOptions(el),
needsValidation = modelCtrl.$pristine === false || frmOptions.forceValidation,
errorType,
findErrorType = function ($errors) {
var keepGoing = true,
errorTypeToReturn;
angular.forEach($errors, function (status, errortype) {
if (keepGoing && status) {
keepGoing = false;
errorTypeToReturn = errortype;
}
});
if (frmElement === undefined || (frmCtrl !== undefined && frmCtrl.autoValidateFormOptions.disabled)) {
return frmElement !== undefined;
}
return errorTypeToReturn;
};
//force the validation of controls
clonedOptions = angular.copy(frmCtrl.autoValidateFormOptions);
clonedOptions.forceValidation = true;
if (frmOptions.disabled === false) {
if ((frmOptions.forceValidation || (shouldValidateElement(el, frmOptions) && modelCtrl && needsValidation))) {
isValid = !modelCtrl.$invalid;
// IE8 holds the child controls collection in the all property
// Firefox in the elements and chrome as a child iterator
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (ctrlElement) {
processElement(ctrlElement, true, clonedOptions);
});
if (frmOptions.removeExternalValidationErrorsOnSubmit && modelCtrl.removeAllExternalValidation) {
modelCtrl.removeAllExternalValidation();
}
// If you have a custom form control that should be validated i.e.
// <my-custom-element>...</my-custom-element> it will not be part of the forms
// HTMLFormControlsCollection and thus won't be included in the above element iteration although
// it will be on the Angular FormController (if it has a name attribute). So adding the directive
// register-custom-form-control="" to the control root and autoValidate will include it in this
// iteration.
if (frmElement[0].customHTMLFormControlsCollection) {
angular.forEach(frmElement[0].customHTMLFormControlsCollection, function (ctrlElement) {
// need to force the validation as the element might not be a known form input type
// so the normal validation process will ignore it.
processElement(ctrlElement, true, clonedOptions);
});
}
if (isValid) {
validator.makeValid(el);
} else {
errorType = findErrorType(modelCtrl.$errors || modelCtrl.$error);
if (errorType === undefined) {
return frmValid;
},
// we have a weird situation some users are encountering where a custom control
// is valid but the ngModel is report it isn't and thus no valid error type can be found
isValid = true;
} else {
validator.getErrorMessage(errorType, el).then(function (errorMsg) {
validator.makeInvalid(el, errorMsg);
});
}
}
}
}
setElementValidationError = function (element, errorMsgKey, errorMsg) {
if (errorMsgKey) {
validator.getErrorMessage(errorMsgKey, element).then(function (msg) {
validator.makeInvalid(element, msg);
});
} else {
validator.makeInvalid(element, errorMsg);
}
};
return isValid;
},
return {
setElementValidationError: setElementValidationError,
validateElement: validateElement,
validateForm: validateForm,
resetElement: resetElement,
resetForm: resetForm
};
}
resetElement = function (element) {
validator.makeDefault(element);
},
ValidationManagerFn.$inject = [
'validator',
'jcs-elementUtils'
];
resetForm = function (frmElement) {
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (element) {
var controller,
ctrlElement = angular.element(element);
controller = ctrlElement.controller('ngModel');
angular.module('jcs-autoValidate').factory('jcs-elementUtils', ElementUtilsFn);
angular.module('jcs-autoValidate').factory('validationManager', ValidationManagerFn);
if (controller !== undefined) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
resetForm(ctrlElement);
} else {
controller.$setPristine();
}
}
});
},
function parseBooleanAttributeValue(val, defaultValue) {
if ((val === undefined || val === null) && defaultValue !== undefined) {
return defaultValue;
} else {
return val !== 'false';
}
}
validateForm = function (frmElement) {
var frmValid = true,
frmCtrl = frmElement ? angular.element(frmElement).controller('form') : undefined,
processElement = function (ctrlElement, force, formOptions) {
var controller, isValid, ctrlFormOptions;
function parseOptions(ctrl, validator, attrs) {
var opts = ctrl.autoValidateFormOptions = ctrl.autoValidateFormOptions || angular.copy(validator.defaultFormValidationOptions);
opts.formController = ctrl;
opts.forceValidation = false;
opts.disabled = !validator.isEnabled() || parseBooleanAttributeValue(attrs.disableDynamicValidation, opts.disabled);
opts.validateNonVisibleControls = parseBooleanAttributeValue(attrs.validateNonVisibleControls, opts.validateNonVisibleControls);
opts.validateOnFormSubmit = parseBooleanAttributeValue(attrs.validateOnFormSubmit, opts.validateOnFormSubmit);
opts.removeExternalValidationErrorsOnSubmit = attrs.removeExternalValidationErrorsOnSubmit === undefined ?
opts.removeExternalValidationErrorsOnSubmit :
parseBooleanAttributeValue(attrs.removeExternalValidationErrorsOnSubmit, opts.removeExternalValidationErrorsOnSubmit);
ctrlElement = angular.element(ctrlElement);
controller = ctrlElement.controller('ngModel');
// the library might be globally disabled but enabled on a particular form so check the
// disableDynamicValidation attribute is on the form
if (validator.isEnabled() === false && attrs.disableDynamicValidation === 'false') {
opts.disabled = false;
}
}
if (controller !== undefined && (force || shouldValidateElement(ctrlElement, formOptions))) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
validateForm(ctrlElement);
} else {
// we need to get the options for the element rather than use the passed in as the
// element could be an ng-form and have different options to the parent form.
ctrlFormOptions = getFormOptions(ctrlElement);
ctrlFormOptions.forceValidation = force;
isValid = validateElement(controller, ctrlElement, ctrlFormOptions);
frmValid = frmValid && isValid;
}
}
},
clonedOptions;
angular.module('jcs-autoValidate').directive('form', [
'validator',
function (validator) {
return {
restrict: 'E',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
if (frmElement === undefined || (frmCtrl !== undefined && frmCtrl.autoValidateFormOptions.disabled)) {
return frmElement !== undefined;
}
angular.module('jcs-autoValidate').directive('ngForm', [
'validator',
function (validator) {
return {
restrict: 'EA',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
//force the validation of controls
clonedOptions = angular.copy(frmCtrl.autoValidateFormOptions);
clonedOptions.forceValidation = true;
function FormResetDirectiveFn(validationManager) {
return {
restrict: 'E',
link: function (scope, el) {
var formController = el.controller('form');
// IE8 holds the child controls collection in the all property
// Firefox in the elements and chrome as a child iterator
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (ctrlElement) {
processElement(ctrlElement, true, clonedOptions);
});
function resetFn() {
validationManager.resetForm(el);
if (formController.$setPristine) {
formController.$setPristine();
}
// If you have a custom form control that should be validated i.e.
// <my-custom-element>...</my-custom-element> it will not be part of the forms
// HTMLFormControlsCollection and thus won't be included in the above element iteration although
// it will be on the Angular FormController (if it has a name attribute). So adding the directive
// register-custom-form-control="" to the control root and autoValidate will include it in this
// iteration.
if (frmElement[0].customHTMLFormControlsCollection) {
angular.forEach(frmElement[0].customHTMLFormControlsCollection, function (ctrlElement) {
// need to force the validation as the element might not be a known form input type
// so the normal validation process will ignore it.
processElement(ctrlElement, true, clonedOptions);
});
}
if (formController.$setUntouched) {
formController.$setUntouched();
}
}
return frmValid;
},
if (formController !== undefined &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === false) {
el.on('reset', resetFn);
setElementValidationError = function (element, errorMsgKey, errorMsg) {
if (errorMsgKey) {
validator.getErrorMessage(errorMsgKey, element).then(function (msg) {
validator.makeInvalid(element, msg);
});
} else {
validator.makeInvalid(element, errorMsg);
}
};
scope.$on('$destroy', function () {
el.off('reset', resetFn);
});
}
}
};
}
return {
setElementValidationError: setElementValidationError,
validateElement: validateElement,
validateForm: validateForm,
resetElement: resetElement,
resetForm: resetForm
};
}
]);
}(angular));
FormResetDirectiveFn.$inject = [
'validationManager'
];
(function (angular) {
'use strict';
angular.module('jcs-autoValidate').directive('form', FormResetDirectiveFn);
function parseBooleanAttributeValue(val) {
return val !== undefined && val !== 'false';
function RegisterCustomFormControlFn() {
var findParentForm = function (el) {
var parent = el;
for (var i = 0; i <= 50; i += 1) {
if (parent !== undefined && parent.nodeName.toLowerCase() === 'form') {
break;
} else if (parent !== undefined) {
parent = angular.element(parent).parent()[0];
}
}
function parseOptions(ctrl, validator, attrs) {
var opts = ctrl.autoValidateFormOptions = ctrl.autoValidateFormOptions || angular.copy(validator.defaultFormValidationOptions);
opts.forceValidation = false;
opts.disabled = !validator.isEnabled() || parseBooleanAttributeValue(attrs.disableDynamicValidation);
opts.validateNonVisibleControls = parseBooleanAttributeValue(attrs.validateNonVisibleControls);
opts.removeExternalValidationErrorsOnSubmit = attrs.removeExternalValidationErrorsOnSubmit === undefined ? true : parseBooleanAttributeValue(attrs.removeExternalValidationErrorsOnSubmit);
return parent;
};
if (validator.isEnabled() === false && parseBooleanAttributeValue(attrs.disableDynamicValidation) === false) {
opts.disabled = false;
}
return {
restrict: 'A',
link: function (scope, element) {
var frmEl = findParentForm(element.parent()[0]);
if (frmEl) {
frmEl.customHTMLFormControlsCollection = frmEl.customHTMLFormControlsCollection || [];
frmEl.customHTMLFormControlsCollection.push(element[0]);
}
}
};
}
angular.module('jcs-autoValidate').directive('form', [
'validator',
function (validator) {
return {
restrict: 'E',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
angular.module('jcs-autoValidate').directive('registerCustomFormControl', RegisterCustomFormControlFn);
angular.module('jcs-autoValidate').directive('ngForm', [
'validator',
function (validator) {
return {
restrict: 'EA',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
}(angular));
function SubmitDecorator($delegate, $parse, validationManager) {
$delegate[0].compile = function ($element, attrs) {
var fn = $parse(attrs.ngSubmit),
force = attrs.ngSubmitForce === 'true';
(function (angular) {
'use strict';
return function (scope, element) {
var formController = element.controller('form'),
resetListenerOffFn;
angular.module('jcs-autoValidate').directive('form', [
'validationManager',
function (validationManager) {
return {
restrict: 'E',
link: function (scope, el) {
var formController = el.controller('form');
function handlerFn(event) {
scope.$apply(function () {
if (formController !== undefined &&
formController !== null &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === true) {
fn(scope, {
$event: event
});
} else {
if (formController.$setSubmitted === undefined) {
// we probably have angular <= 1.2
formController.$submitted = true;
}
if (formController !== undefined &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === false) {
el.on('reset', function () {
validationManager.resetForm(el);
});
if (validationManager.validateForm(element) || force === true) {
fn(scope, {
$event: event
});
}
}
});
}
scope.$on('$destroy', function () {
el.off('reset');
});
}
}
};
function resetFormFn() {
if (element[0].reset) {
element[0].reset();
} else {
validationManager.resetForm(element);
}
]);
}(angular));
}
(function (angular) {
'use strict';
if (formController && formController.autoValidateFormOptions) {
// allow the form to be reset programatically or via raising the event
// form:formName:reset
formController.autoValidateFormOptions.resetForm = resetFormFn;
if (formController.$name !== undefined && formController.$name !== '') {
resetListenerOffFn = scope.$on('form:' + formController.$name + ':reset', resetFormFn);
}
}
angular.module('jcs-autoValidate').directive('registerCustomFormControl', [
function () {
var findParentForm = function (el) {
var parent = el;
for (var i = 0; i <= 50; i += 1) {
if (parent !== undefined && parent.nodeName.toLowerCase() === 'form') {
break;
} else if (parent !== undefined) {
parent = angular.element(parent).parent()[0];
}
}
element.on('submit', handlerFn);
scope.$on('$destroy', function () {
element.off('submit', handlerFn);
if (resetListenerOffFn) {
resetListenerOffFn();
}
});
};
};
return parent;
};
return $delegate;
}
return {
restrict: 'A',
link: function (scope, element) {
var frmEl = findParentForm(element.parent()[0]);
if (frmEl) {
frmEl.customHTMLFormControlsCollection = frmEl.customHTMLFormControlsCollection || [];
frmEl.customHTMLFormControlsCollection.push(element[0]);
}
}
};
}
]);
}(angular));
SubmitDecorator.$inject = [
'$delegate',
'$parse',
'validationManager'
];
(function (angular) {
'use strict';
function ProviderFn($provide) {
$provide.decorator('ngSubmitDirective', SubmitDecorator);
}
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngSubmitDirective', [
'$delegate',
'$parse',
'validationManager',
function ($delegate, $parse, validationManager) {
$delegate[0].compile = function ($element, attrs) {
var fn = $parse(attrs.ngSubmit),
force = attrs.ngSubmitForce === 'true';
ProviderFn.$inject = [
'$provide'
];
return function (scope, element) {
function handlerFn(event) {
scope.$apply(function () {
var formController = $element.controller('form');
if (formController !== undefined &&
formController !== null &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === true) {
fn(scope, {
$event: event
});
} else {
if (validationManager.validateForm(element) || force === true) {
fn(scope, {
$event: event
});
}
}
});
}
angular.module('jcs-autoValidate').config(ProviderFn);
element.on('submit', handlerFn);
scope.$on('$destroy', function () {
element.off('submit', handlerFn);
});
};
};
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngModelDirective', [
'$timeout',
'$delegate',
'validationManager',
'jcs-debounce',
function ($timeout, $delegate, validationManager, debounce) {
var directive = $delegate[0],
link = directive.link || directive.compile;
return $delegate;
}
]);
}
]);
}(angular));
directive.compile = function (el) {
var supportsNgModelOptions = angular.version.major >= 1 && angular.version.minor >= 3,
originalLink = link;
(function (angular) {
'use strict';
// in the RC of 1.3 there is no directive.link only the directive.compile which
// needs to be invoked to get at the link functions.
if (supportsNgModelOptions && angular.isFunction(link)) {
originalLink = link(el);
}
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngModelDirective', [
'$timeout',
'$delegate',
'validationManager',
'jcs-debounce',
function ($timeout, $delegate, validationManager, debounce) {
var directive = $delegate[0],
link = directive.link || directive.compile;
return {
pre: function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0],
frmCtrl = ctrls[1],
ngModelOptions = attrs.ngModelOptions === undefined ? undefined : scope.$eval(attrs.ngModelOptions),
setValidity = ngModelCtrl.$setValidity,
setPristine = ngModelCtrl.$setPristine,
setValidationState = debounce.debounce(function () {
var validateOptions = frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : undefined;
validationManager.validateElement(ngModelCtrl, element, validateOptions);
}, 100);
directive.compile = function (el) {
return function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0],
frmCtrl = ctrls[1],
supportsNgModelOptions = angular.version.major >= 1 && angular.version.minor >= 3,
ngModelOptions = attrs.ngModelOptions === undefined ? undefined : scope.$eval(attrs.ngModelOptions),
setValidity = ngModelCtrl.$setValidity,
setPristine = ngModelCtrl.$setPristine,
setValidationState = debounce.debounce(function () {
var validateOptions = frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : undefined;
validationManager.validateElement(ngModelCtrl, element, validateOptions);
}, 100);
if (attrs.formnovalidate === undefined &&
(frmCtrl !== undefined && frmCtrl !== null && frmCtrl.autoValidateFormOptions &&
frmCtrl.autoValidateFormOptions.disabled === false)) {
if (supportsNgModelOptions || ngModelOptions === undefined || ngModelOptions.updateOn === undefined || ngModelOptions.updateOn === '') {
ngModelCtrl.$setValidity = function (validationErrorKey, isValid) {
setValidity.call(ngModelCtrl, validationErrorKey, isValid);
setValidationState();
};
} else {
element.on(ngModelOptions.updateOn, function () {
setValidationState();
});
// in the RC of 1.3 there is no directive.link only the directive.compile which
// needs to be invoked to get at the link functions.
if (supportsNgModelOptions && angular.isFunction(link)) {
link = link(el);
}
scope.$on('$destroy', function () {
element.off(ngModelOptions.updateOn);
});
}
if (link.pre) {
link.pre.apply(this, arguments);
ngModelOptions = ngModelCtrl.$options === undefined ? undefined : ngModelCtrl.$options;
}
// We override this so we can reset the element state when it is called.
ngModelCtrl.$setPristine = function () {
setPristine.call(ngModelCtrl);
validationManager.resetElement(element);
};
if (attrs.formnovalidate === undefined &&
(frmCtrl !== undefined && frmCtrl !== null && frmCtrl.autoValidateFormOptions &&
frmCtrl.autoValidateFormOptions.disabled === false)) {
if (supportsNgModelOptions || ngModelOptions === undefined || ngModelOptions.updateOn === undefined || ngModelOptions.updateOn === '') {
ngModelCtrl.$setValidity = function (validationErrorKey, isValid) {
setValidity.call(ngModelCtrl, validationErrorKey, isValid);
setValidationState();
};
} else {
element.on(ngModelOptions.updateOn, function () {
setValidationState();
});
ngModelCtrl.autoValidated = true;
}
scope.$on('$destroy', function () {
element.off(ngModelOptions.updateOn);
});
}
ngModelCtrl.setExternalValidation = function (errorMsgKey, errorMessage, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = false;
}
// We override this so we can reset the element state when it is called.
ngModelCtrl.$setPristine = function () {
setPristine.call(ngModelCtrl);
validationManager.resetElement(element);
};
ngModelCtrl.externalErrors = ngModelCtrl.externalErrors || {};
ngModelCtrl.externalErrors[errorMsgKey] = false;
validationManager.setElementValidationError(element, errorMsgKey, errorMessage);
};
ngModelCtrl.autoValidated = true;
}
ngModelCtrl.removeExternalValidation = function (errorMsgKey, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
delete collection[errorMsgKey];
}
if (link.post) {
link.post.apply(this, arguments);
} else {
link.apply(this, arguments);
}
if (ngModelCtrl.externalErrors) {
delete ngModelCtrl.externalErrors[errorMsgKey];
}
ngModelCtrl.setExternalValidation = function (errorMsgKey, errorMessage, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = false;
}
validationManager.resetElement(element);
};
ngModelCtrl.externalErrors = ngModelCtrl.externalErrors || {};
ngModelCtrl.externalErrors[errorMsgKey] = false;
validationManager.setElementValidationError(element, errorMsgKey, errorMessage);
};
ngModelCtrl.removeAllExternalValidation = function () {
if (ngModelCtrl.externalErrors) {
var errorCollection = ngModelCtrl.$error || ngModelCtrl.$errors;
angular.forEach(ngModelCtrl.externalErrors, function (value, key) {
delete errorCollection[key];
});
ngModelCtrl.removeExternalValidation = function (errorMsgKey, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = true;
}
ngModelCtrl.externalErrors = {};
if (ngModelCtrl.externalErrors) {
delete ngModelCtrl.externalErrors[errorMsgKey];
}
validationManager.resetElement(element);
}
};
validationManager.resetElement(element);
};
if (frmCtrl) {
frmCtrl.setExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].setExternalValidation(errorMsgKey, errorMessageOverride, addToModelErrors);
success = true;
}
ngModelCtrl.removeAllExternalValidation = function () {
if (ngModelCtrl.externalErrors) {
var errorCollection = ngModelCtrl.$error || ngModelCtrl.$errors;
angular.forEach(ngModelCtrl.externalErrors, function (value, key) {
errorCollection[key] = true;
});
return success;
};
ngModelCtrl.externalErrors = {};
frmCtrl.removeExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].removeExternalValidation(errorMsgKey, addToModelErrors);
success = true;
}
validationManager.resetElement(element);
}
};
return success;
};
}
if (frmCtrl) {
frmCtrl.setExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].setExternalValidation(errorMsgKey, errorMessageOverride, addToModelErrors);
success = true;
}
return originalLink.pre ?
originalLink.pre.apply(this, arguments) :
this;
},
post: function (scope, element, attrs, ctrls) {
return originalLink.post ?
originalLink.post.apply(this, arguments) :
originalLink.apply(this, arguments);
}
};
};
return success;
};
return $delegate;
}
]);
}
]);
frmCtrl.removeExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].removeExternalValidation(errorMsgKey, addToModelErrors);
success = true;
}
function AutoValidateRunFn(validator, defaultErrorMessageResolver, bootstrap3ElementModifier, foundation5ElementModifier) {
validator.setErrorMessageResolver(defaultErrorMessageResolver.resolve);
validator.registerDomModifier(bootstrap3ElementModifier.key, bootstrap3ElementModifier);
validator.registerDomModifier(foundation5ElementModifier.key, foundation5ElementModifier);
validator.setDefaultElementModifier(bootstrap3ElementModifier.key);
}
return success;
};
}
};
};
AutoValidateRunFn.$inject = [
'validator',
'defaultErrorMessageResolver',
'bootstrap3ElementModifier',
'foundation5ElementModifier'
];
return $delegate;
}
]);
}
]);
}(angular));
angular.module('jcs-autoValidate').run(AutoValidateRunFn);
(function (angular) {
'use strict';
angular.module('jcs-autoValidate')
.run([
'validator',
'defaultErrorMessageResolver',
'bootstrap3ElementModifier',
'foundation5ElementModifier',
function (validator, defaultErrorMessageResolver, bootstrap3ElementModifier, foundation5ElementModifier) {
validator.setErrorMessageResolver(defaultErrorMessageResolver.resolve);
validator.registerDomModifier(bootstrap3ElementModifier.key, bootstrap3ElementModifier);
validator.registerDomModifier(foundation5ElementModifier.key, foundation5ElementModifier);
validator.setDefaultElementModifier(bootstrap3ElementModifier.key);
}
]);
}(angular));
}(String, angular));
/*
* angular-auto-validate - v1.18.6 - 2015-04-16
* angular-auto-validate - v1.18.14 - 2015-08-23
* https://github.com/jonsamwell/angular-auto-validate
* Copyright (c) 2015 Jon Samwell (http://www.jonsamwell.com)
*/
!function(a){"use strict";a.module("jcs-autoValidate",[])}(angular),function(a){"use strict";a.module("jcs-autoValidate").provider("validator",[function(){var b={},c=!0,d=!0,e=!0,f=function(a){var b;return a&&0!==a.length?(b=a.toLowerCase(),a=!("f"===b||"0"===b||"false"===b)):a=!1,a},g=function(a,b){var c;return void 0!==a&&(c=a.attr(b)||a.attr("data-"+b)),c},h=function(a,b){var c;return void 0!==a&&(c=void 0!==a.attr(b)||void 0!==a.attr("data-"+b)),c},i=function(a,b){return f(g(a,b))},j=function(a){return c&&!i(a,"disable-valid-styling")},k=function(a){return d&&!i(a,"disable-invalid-styling")};this.enable=function(a){e=a},this.isEnabled=function(){return e},this.setDefaultElementModifier=function(a){if(void 0===b[a])throw new Error("Element modifier not registered: "+a);this.defaultElementModifier=a},this.registerDomModifier=function(a,c){b[a]=c},this.setErrorMessageResolver=function(a){this.errorMessageResolver=a},this.getErrorMessage=function(b,c){var d;if(void 0===this.errorMessageResolver)throw new Error("Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.");return h(c,"disable-validation-message")?(d=a.injector(["ng"]).get("$q").defer(),d.resolve(""),d.promise):this.errorMessageResolver(b,c)},this.setValidElementStyling=function(a){c=a},this.setInvalidElementStyling=function(a){d=a},this.getDomModifier=function(a){var c=(void 0!==a?a.attr("element-modifier"):this.defaultElementModifier)||(void 0!==a?a.attr("data-element-modifier"):this.defaultElementModifier)||this.defaultElementModifier;if(void 0===c)throw new Error("Please set a default dom modifier via the setDefaultElementModifier method on the validator class.");return b[c]},this.makeValid=function(a){j(a)?this.getDomModifier(a).makeValid(a):this.makeDefault(a)},this.makeInvalid=function(a,b){k(a)?this.getDomModifier(a).makeInvalid(a,b):this.makeDefault(a)},this.makeDefault=function(a){var b=this.getDomModifier(a);b.makeDefault&&b.makeDefault(a)},this.defaultFormValidationOptions={forceValidation:!1,disabled:!1,validateNonVisibleControls:!1,removeExternalValidationErrorsOnSubmit:!0},this.$get=[function(){return this}]}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").factory("bootstrap3ElementModifier",["$log",function(b){var c=function(b){a.forEach(b.find("span"),function(b){b=a.element(b),(b.hasClass("error-msg")||b.hasClass("form-control-feedback")||b.hasClass("control-feedback"))&&b.remove()}),b.removeClass("has-success has-error has-feedback")},d=function(a,b){for(var c,d=a,e=0;10>=e;e+=1){if(void 0!==d&&d.hasClass(b)){c=d;break}void 0!==d&&(d=d.parent())}return c},e=function(b,c){for(var d,f=0;f<b.children.length&&(d=b.children[f],void 0===d||!a.element(d).hasClass(c))&&!(void 0!==d.children&&(d=e(d,c),d.length>0));f+=1);return a.element(d)},f=function(a){return d(a,"form-group")},g=function(a){return e(a,"input-group")},h=function(a,b){a[0].parentNode.insertBefore(b[0],a[0].nextSibling)},i=!1,j=function(a){i=a},k=function(d){var e,j=f(d);if(j){if(c(j),e=g(j[0]),j.addClass("has-success "+(e.length>0?"":"has-feedback")),i){var k='<span class="glyphicon glyphicon-ok form-control-feedback"></span>';e.length>0&&(k=k.replace("form-",""),k='<span class="input-group-addon control-feedback">'+k+"</span"),h(d,a.element(k))}}else b.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")},l=function(d,e){var j,k=f(d),l=a.element('<span class="help-block has-error error-msg">'+e+"</span>");if(k){if(c(k),j=g(k[0]),k.addClass("has-error "+(j.length>0?"":"has-feedback")),h(j.length>0?j:d,l),i){var m='<span class="glyphicon glyphicon-remove form-control-feedback"></span>';j.length>0&&(m=m.replace("form-",""),m='<span class="input-group-addon control-feedback">'+m+"</span"),h(d,a.element(m))}}else b.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")},m=function(a){var d=f(a);d?c(d):b.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")};return{makeValid:k,makeInvalid:l,makeDefault:m,enableValidationStateIcons:j,key:"bs3"}}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").factory("jcs-debounce",["$timeout",function(b){var c=function(c,d,e){d=a.isUndefined(d)?0:d,e=a.isUndefined(e)?!0:e;var f=0;return function(){var a=this,g=arguments;f+=1;var h=function(b){return function(){return b===f?c.apply(a,g):void 0}}(f);return b(h,d,e)}};return{debounce:c}}])}(angular),function(a,b){"use strict";"format"in a.prototype||(a.prototype.format=function(){var a=arguments;return this.replace(/{(\d+)}/g,function(b,c){return void 0!==typeof a[c]?a[c]:b})}),b.autoValidate=b.autoValidate||{errorMessages:{}},b.autoValidate.errorMessages["en-us"]=b.autoValidate.errorMessages["en-gb"]={defaultMsg:"Please add error message for {0}",email:"Please enter a valid email address",minlength:"Please enter at least {0} characters",maxlength:"You have entered more than the maximum {0} characters",min:"Please enter the minimum number of {0}",max:"Please enter the maximum number of {0}",required:"This field is required",date:"Please enter a valid date",pattern:"Please ensure the entered information adheres to this pattern {0}",number:"Please enter a valid number",url:"Please enter a valid URL in the format of http(s)://www.google.com"},b.module("jcs-autoValidate").factory("defaultErrorMessageResolver",["$q","$http",function(a,c){var d,e="en-gb",f="js/angular-auto-validate/dist/lang",g=function(a){return d=c.get("{0}/jcs-auto-validate_{1}.json".format(f,a.toLowerCase()))},h=function(a){f=a},i=function(c,f){var h=a.defer();return f=f||g,e=c.toLowerCase(),void 0===b.autoValidate.errorMessages[e]?(d=f(c),d.then(function(a){d=void 0,b.autoValidate.errorMessages[e]=a.data,h.resolve(b.autoValidate.errorMessages[e])},function(a){b.autoValidate.errorMessages[e]={defaultMsg:"Loading culture failed!"},d=null,h.reject(a)})):h.resolve(b.autoValidate.errorMessages[e]),h.promise},j=function(c){var f=a.defer();return c=void 0===c?e:c.toLowerCase(),void 0!==d?d.then(function(){f.resolve(b.autoValidate.errorMessages[c])},function(a){f.reject(a)}):f.resolve(b.autoValidate.errorMessages[c]),f.promise},k=function(a,b){var c;return b&&(a+="-err-type",c=b.attr("ng-"+a),void 0===c&&(c=b.attr("data-ng-"+a)||b.attr(a)),c&&(c=c.replace(/[\W]/g,""))),c},l=function(c,f){var g,h,i,j=a.defer(),m=[];if(void 0!==d)d.then(function(){l(c,f).then(function(a){j.resolve(a)})});else{if(g=b.autoValidate.errorMessages[e][c],i=k(c,f),i&&(g=b.autoValidate.errorMessages[e][i]),void 0===g&&(g=b.autoValidate.errorMessages[e].defaultMsg.format(c)),f&&f.attr)try{h=f.attr("ng-"+c),void 0===h&&(h=f.attr("data-ng-"+c)||f.attr(c)),m.push(h||""),g=g.format(m)}catch(n){}j.resolve(g)}return j.promise};return{setI18nFileRootPath:h,setCulture:i,getErrorMessages:j,resolve:l}}])}(String,angular),function(a){"use strict";a.module("jcs-autoValidate").factory("foundation5ElementModifier",[function(){var b=function(b,c){a.forEach(b.find("small"),function(b){a.element(b).hasClass("error")&&a.element(b).remove()}),c.removeClass("error")},c=function(a){for(var b=a,c=0;3>=c&&(void 0===b||!b.hasClass("columns"));c+=1)void 0!==b&&(b=b.parent());return b},d=function(a){var d=c(a);b(d&&d.length>0?d:a,a)},e=function(d,e){var f,g=c(d);b(g||d,d),d.addClass("error"),g&&(f=a.element('<small class="error">'+e+"</small>"),g.append(f))},f=function(a){d(a)};return{makeValid:d,makeInvalid:e,makeDefault:f,key:"foundation5"}}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").factory("jcs-elementUtils",[function(){var a=function(a){return a[0].offsetWidth>0&&a[0].offsetHeight>0};return{isElementVisible:a}}]),a.module("jcs-autoValidate").factory("validationManager",["validator","jcs-elementUtils",function(b,c){var d=["input","textarea","select","form"],e=function(a){return c.isElementVisible(a)},f=function(c){var d=a.element(c).controller("form");return void 0!==d&&null!==d?d.autoValidateFormOptions:b.defaultFormValidationOptions},g=function(a,b){var c=a&&a.length>0&&(e(a)||b.validateNonVisibleControls)&&(d.indexOf(a[0].nodeName.toLowerCase())>-1||a[0].hasAttribute("register-custom-form-control"));return c},h=function(c,d,e){var h,i=!0,j=e||f(d),k=c.$pristine===!1||j.forceValidation,l=function(b){var c,d=!0;return a.forEach(b,function(a,b){d&&a&&(d=!1,c=b)}),c};return j.disabled===!1&&(j.forceValidation||g(d,j)&&c&&k)&&(i=!c.$invalid,j.removeExternalValidationErrorsOnSubmit&&c.removeAllExternalValidation&&c.removeAllExternalValidation(),i?b.makeValid(d):(h=l(c.$errors||c.$error),void 0===h?i=!0:b.getErrorMessage(h,d).then(function(a){b.makeInvalid(d,a)}))),i},i=function(a){b.makeDefault(a)},j=function(b){a.forEach(b[0].all||b[0].elements||b[0],function(b){var c,d=a.element(b);c=d.controller("ngModel"),void 0!==c&&("form"===d[0].nodeName.toLowerCase()?j(d):c.$setPristine())})},k=function(b){var c,d=!0,e=b?a.element(b).controller("form"):void 0,i=function(b,c,e){var i,j,l;b=a.element(b),i=b.controller("ngModel"),void 0!==i&&(c||g(b,e))&&("form"===b[0].nodeName.toLowerCase()?k(b):(l=f(b),l.forceValidation=c,j=h(i,b,l),d=d&&j))};return void 0===b||void 0!==e&&e.autoValidateFormOptions.disabled?void 0!==b:(c=a.copy(e.autoValidateFormOptions),c.forceValidation=!0,a.forEach(b[0].all||b[0].elements||b[0],function(a){i(a,!0,c)}),b[0].customHTMLFormControlsCollection&&a.forEach(b[0].customHTMLFormControlsCollection,function(a){i(a,!0,c)}),d)},l=function(a,c,d){c?b.getErrorMessage(c,a).then(function(c){b.makeInvalid(a,c)}):b.makeInvalid(a,d)};return{setElementValidationError:l,validateElement:h,validateForm:k,resetElement:i,resetForm:j}}])}(angular),function(a){"use strict";function b(a){return void 0!==a&&"false"!==a}function c(c,d,e){var f=c.autoValidateFormOptions=c.autoValidateFormOptions||a.copy(d.defaultFormValidationOptions);f.forceValidation=!1,f.disabled=!d.isEnabled()||b(e.disableDynamicValidation),f.validateNonVisibleControls=b(e.validateNonVisibleControls),f.removeExternalValidationErrorsOnSubmit=void 0===e.removeExternalValidationErrorsOnSubmit?!0:b(e.removeExternalValidationErrorsOnSubmit),d.isEnabled()===!1&&b(e.disableDynamicValidation)===!1&&(f.disabled=!1)}a.module("jcs-autoValidate").directive("form",["validator",function(a){return{restrict:"E",require:"form",priority:9999,compile:function(){return{pre:function(b,d,e,f){c(f,a,e)}}}}}]),a.module("jcs-autoValidate").directive("ngForm",["validator",function(a){return{restrict:"EA",require:"form",priority:9999,compile:function(){return{pre:function(b,d,e,f){c(f,a,e)}}}}}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").directive("form",["validationManager",function(a){return{restrict:"E",link:function(b,c){var d=c.controller("form");void 0!==d&&d.autoValidateFormOptions&&d.autoValidateFormOptions.disabled===!1&&(c.on("reset",function(){a.resetForm(c)}),b.$on("$destroy",function(){c.off("reset")}))}}}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").directive("registerCustomFormControl",[function(){var b=function(b){for(var c=b,d=0;50>=d&&(void 0===c||"form"!==c.nodeName.toLowerCase());d+=1)void 0!==c&&(c=a.element(c).parent()[0]);return c};return{restrict:"A",link:function(a,c){var d=b(c.parent()[0]);d&&(d.customHTMLFormControlsCollection=d.customHTMLFormControlsCollection||[],d.customHTMLFormControlsCollection.push(c[0]))}}}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").config(["$provide",function(a){a.decorator("ngSubmitDirective",["$delegate","$parse","validationManager",function(a,b,c){return a[0].compile=function(a,d){var e=b(d.ngSubmit),f="true"===d.ngSubmitForce;return function(b,d){function g(g){b.$apply(function(){var h=a.controller("form");void 0!==h&&null!==h&&h.autoValidateFormOptions&&h.autoValidateFormOptions.disabled===!0?e(b,{$event:g}):(c.validateForm(d)||f===!0)&&e(b,{$event:g})})}d.on("submit",g),b.$on("$destroy",function(){d.off("submit",g)})}},a}])}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").config(["$provide",function(b){b.decorator("ngModelDirective",["$timeout","$delegate","validationManager","jcs-debounce",function(b,c,d,e){var f=c[0],g=f.link||f.compile;return f.compile=function(b){return function(c,f,h,i){var j=i[0],k=i[1],l=a.version.major>=1&&a.version.minor>=3,m=void 0===h.ngModelOptions?void 0:c.$eval(h.ngModelOptions),n=j.$setValidity,o=j.$setPristine,p=e.debounce(function(){var a=void 0!==k&&null!==k?k.autoValidateFormOptions:void 0;d.validateElement(j,f,a)},100);l&&a.isFunction(g)&&(g=g(b)),g.pre&&(g.pre.apply(this,arguments),m=void 0===j.$options?void 0:j.$options),void 0===h.formnovalidate&&void 0!==k&&null!==k&&k.autoValidateFormOptions&&k.autoValidateFormOptions.disabled===!1&&(l||void 0===m||void 0===m.updateOn||""===m.updateOn?j.$setValidity=function(a,b){n.call(j,a,b),p()}:(f.on(m.updateOn,function(){p()}),c.$on("$destroy",function(){f.off(m.updateOn)})),j.$setPristine=function(){o.call(j),d.resetElement(f)},j.autoValidated=!0),g.post?g.post.apply(this,arguments):g.apply(this,arguments),j.setExternalValidation=function(a,b,c){if(c){var e=j.$error||j.$errors;e[a]=!1}j.externalErrors=j.externalErrors||{},j.externalErrors[a]=!1,d.setElementValidationError(f,a,b)},j.removeExternalValidation=function(a,b){if(b){var c=j.$error||j.$errors;c[a]=!0}j.externalErrors&&delete j.externalErrors[a],d.resetElement(f)},j.removeAllExternalValidation=function(){if(j.externalErrors){var b=j.$error||j.$errors;a.forEach(j.externalErrors,function(a,c){b[c]=!0}),j.externalErrors={},d.resetElement(f)}},k&&(k.setExternalValidation=function(a,b,c,d){var e=!1;return k[a]&&(k[a].setExternalValidation(b,c,d),e=!0),e},k.removeExternalValidation=function(a,b,c,d){var e=!1;return k[a]&&(k[a].removeExternalValidation(b,d),e=!0),e})}},c}])}])}(angular),function(a){"use strict";a.module("jcs-autoValidate").run(["validator","defaultErrorMessageResolver","bootstrap3ElementModifier","foundation5ElementModifier",function(a,b,c,d){a.setErrorMessageResolver(b.resolve),a.registerDomModifier(c.key,c),a.registerDomModifier(d.key,d),a.setDefaultElementModifier(c.key)}])}(angular);
!function(a,b){"use strict";function c(){var a={},c=!0,d=!0,e=!0,f=function(a){var b;return a&&0!==a.length?(b=a.toLowerCase(),a=!("f"===b||"0"===b||"false"===b)):a=!1,a},g=function(a,b){var c;return void 0!==a&&(c=a.attr(b)||a.attr("data-"+b)),c},h=function(a,b){var c;return void 0!==a&&(c=void 0!==a.attr(b)||void 0!==a.attr("data-"+b)),c},i=function(a,b){return f(g(a,b))},j=function(a){return c&&!i(a,"disable-valid-styling")},k=function(a){return d&&!i(a,"disable-invalid-styling")};this.enable=function(a){e=a},this.isEnabled=function(){return e},this.setDefaultElementModifier=function(b){if(void 0===a[b])throw new Error("Element modifier not registered: "+b);this.defaultElementModifier=b},this.registerDomModifier=function(b,c){a[b]=c},this.setErrorMessageResolver=function(a){this.errorMessageResolver=a},this.getErrorMessage=function(a,c){var d;if(void 0===this.errorMessageResolver)throw new Error("Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.");return h(c,"disable-validation-message")?(d=b.injector(["ng"]).get("$q").defer(),d.resolve(""),d.promise):this.errorMessageResolver(a,c)},this.setValidElementStyling=function(a){c=a},this.setInvalidElementStyling=function(a){d=a},this.getDomModifier=function(b){var c=(void 0!==b?b.attr("element-modifier"):this.defaultElementModifier)||(void 0!==b?b.attr("data-element-modifier"):this.defaultElementModifier)||this.defaultElementModifier;if(void 0===c)throw new Error("Please set a default dom modifier via the setDefaultElementModifier method on the validator class.");return a[c]},this.makeValid=function(a){j(a)?this.getDomModifier(a).makeValid(a):this.makeDefault(a)},this.makeInvalid=function(a,b){k(a)?this.getDomModifier(a).makeInvalid(a,b):this.makeDefault(a)},this.makeDefault=function(a){var b=this.getDomModifier(a);b.makeDefault&&b.makeDefault(a)},this.defaultFormValidationOptions={forceValidation:!1,disabled:!1,validateNonVisibleControls:!1,removeExternalValidationErrorsOnSubmit:!0,validateOnFormSubmit:!1},this.$get=[function(){return this}]}function d(a){var c=function(a){b.forEach(a.find("span"),function(a){a=b.element(a),(a.hasClass("error-msg")||a.hasClass("form-control-feedback")||a.hasClass("control-feedback"))&&a.remove()}),a.removeClass("has-success has-error has-feedback")},d=function(a,b){for(var c,d=a,e=0;10>=e;e+=1){if(void 0!==d&&d.hasClass(b)){c=d;break}void 0!==d&&(d=d.parent())}return c},e=function(a,c){for(var d,f=0;f<a.children.length&&(d=a.children[f],void 0===d||!b.element(d).hasClass(c))&&!(void 0!==d.children&&(d=e(d,c),d.length>0));f+=1);return b.element(d)},f=function(a){return d(a,"form-group")},g=function(a){return e(a,"input-group")},h=function(a,b){a[0].parentNode.insertBefore(b[0],a[0].nextSibling)},i=!1,j=function(a){i=a},k=function(d){var e,j=f(d);if(j){if(c(j),e=g(j[0]),j.addClass("has-success "+(e.length>0?"":"has-feedback")),i){var k='<span class="glyphicon glyphicon-ok form-control-feedback"></span>';e.length>0&&(k=k.replace("form-",""),k='<span class="input-group-addon control-feedback">'+k+"</span"),h(d,b.element(k))}}else a.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")},l=function(d,e){var j,k=f(d),l=b.element('<span class="help-block has-error error-msg">'+e+"</span>");if(k){if(c(k),j=g(k[0]),k.addClass("has-error "+(j.length>0?"":"has-feedback")),h(j.length>0?j:d,l),i){var m='<span class="glyphicon glyphicon-remove form-control-feedback"></span>';j.length>0&&(m=m.replace("form-",""),m='<span class="input-group-addon control-feedback">'+m+"</span"),h(d,b.element(m))}}else a.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")},m=function(b){var d=f(b);d?c(d):a.error("Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class")};return{makeValid:k,makeInvalid:l,makeDefault:m,enableValidationStateIcons:j,key:"bs3"}}function e(a){var c=function(c,d,e){d=b.isUndefined(d)?0:d,e=b.isUndefined(e)?!0:e;var f=0;return function(){var b=this,g=arguments;f+=1;var h=function(a){return function(){return a===f?c.apply(b,g):void 0}}(f);return a(h,d,e)}};return{debounce:c}}function f(a,c){var d,e="en-gb",f="js/angular-auto-validate/dist/lang",g=function(a){return d=c.get("{0}/jcs-auto-validate_{1}.json".format(f,a.toLowerCase()))},h=function(a){f=a},i=function(c,f){var h=a.defer();return f=f||g,e=c.toLowerCase(),void 0===b.autoValidate.errorMessages[e]?(d=f(c),d.then(function(a){d=void 0,b.autoValidate.errorMessages[e]=a.data,h.resolve(b.autoValidate.errorMessages[e])},function(a){b.autoValidate.errorMessages[e]={defaultMsg:"Loading culture failed!"},d=null,h.reject(a)})):h.resolve(b.autoValidate.errorMessages[e]),h.promise},j=function(c){var f=a.defer();return c=void 0===c?e:c.toLowerCase(),void 0!==d?d.then(function(){f.resolve(b.autoValidate.errorMessages[c])},function(a){f.reject(a)}):f.resolve(b.autoValidate.errorMessages[c]),f.promise},k=function(a,b){var c;return b&&(a+="-err-type",c=b.attr("ng-"+a),void 0===c&&(c=b.attr("data-ng-"+a)||b.attr(a)),c&&(c=c.replace(/[\W]/g,""))),c},l=function(c,f){var g,h,i,j=a.defer(),m=[];if(void 0!==d)d.then(function(){l(c,f).then(function(a){j.resolve(a)})});else{if(g=b.autoValidate.errorMessages[e][c],i=k(c,f),i&&(g=b.autoValidate.errorMessages[e][i]),void 0===g&&(g=b.autoValidate.errorMessages[e].defaultMsg.format(c)),f&&f.attr)try{h=f.attr("ng-"+c),void 0===h&&(h=f.attr("data-ng-"+c)||f.attr(c)),m.push(h||""),g=g.format(m)}catch(n){}j.resolve(g)}return j.promise};return{setI18nFileRootPath:h,setCulture:i,getErrorMessages:j,resolve:l}}function g(){var a=function(a,c){b.forEach(a.find("small"),function(a){b.element(a).hasClass("error")&&b.element(a).remove()}),c.removeClass("error")},c=function(a){for(var b=a,c=0;3>=c&&(void 0===b||!b.hasClass("columns"));c+=1)void 0!==b&&(b=b.parent());return b},d=function(b){var d=c(b);a(d&&d.length>0?d:b,b)},e=function(d,e){var f,g=c(d);a(g||d,d),d.addClass("error"),g&&(f=b.element('<small class="error">'+e+"</small>"),g.append(f))},f=function(a){d(a)};return{makeValid:d,makeInvalid:e,makeDefault:f,key:"foundation5"}}function h(){var a=function(a){return a[0].offsetWidth>0&&a[0].offsetHeight>0};return{isElementVisible:a}}function i(a,c){var d=["input","textarea","select","form"],e=function(a){return c.isElementVisible(a)},f=function(c){var d,e=b.element(c).controller("form");return d=void 0!==e&&null!==e?e.autoValidateFormOptions:a.defaultFormValidationOptions},g=function(a,b,c){var f,g,h,i=a&&a.length>0;return i&&(f=e(a)||b.validateNonVisibleControls,g=d.indexOf(a[0].nodeName.toLowerCase())>-1||a[0].hasAttribute("register-custom-form-control"),h=b.validateOnFormSubmit===!1||b.validateOnFormSubmit===!0&&c===!0),i&&f&&g&&h},h=function(c,d,e){var h,i=!0,j=e||f(d),k=c.$pristine===!1||j.forceValidation,l=function(a){var c,d=!0;return b.forEach(a,function(a,b){d&&a&&(d=!1,c=b)}),c};return j.disabled===!1&&(j.forceValidation||g(d,j,j.formController.$submitted)&&c&&k)&&(i=!c.$invalid,j.removeExternalValidationErrorsOnSubmit&&c.removeAllExternalValidation&&c.removeAllExternalValidation(),i?a.makeValid(d):(h=l(c.$errors||c.$error),void 0===h?i=!0:a.getErrorMessage(h,d).then(function(b){a.makeInvalid(d,b)}))),i},i=function(b){a.makeDefault(b)},j=function(a){b.forEach(a[0].all||a[0].elements||a[0],function(a){var c,d=b.element(a);c=d.controller("ngModel"),void 0!==c&&("form"===d[0].nodeName.toLowerCase()?j(d):c.$setPristine())})},k=function(a){var c,d=!0,e=a?b.element(a).controller("form"):void 0,i=function(a,c,i){var j,l,m,n;if(a=b.element(a),j=a.controller("ngModel"),void 0!==j&&(c||g(a,i,e.$submitted)))if("form"===a[0].nodeName.toLowerCase())k(a);else{m=f(a),n=m.forceValidation,m.forceValidation=c;try{l=h(j,a,m),d=d&&l}finally{m.forceValidation=n}}};return void 0===a||void 0!==e&&e.autoValidateFormOptions.disabled?void 0!==a:(c=b.copy(e.autoValidateFormOptions),c.forceValidation=!0,b.forEach(a[0].all||a[0].elements||a[0],function(a){i(a,!0,c)}),a[0].customHTMLFormControlsCollection&&b.forEach(a[0].customHTMLFormControlsCollection,function(a){i(a,!0,c)}),d)},l=function(b,c,d){c?a.getErrorMessage(c,b).then(function(c){a.makeInvalid(b,c)}):a.makeInvalid(b,d)};return{setElementValidationError:l,validateElement:h,validateForm:k,resetElement:i,resetForm:j}}function j(a,b){return void 0!==a&&null!==a||void 0===b?"false"!==a:b}function k(a,c,d){var e=a.autoValidateFormOptions=a.autoValidateFormOptions||b.copy(c.defaultFormValidationOptions);e.formController=a,e.forceValidation=!1,e.disabled=!c.isEnabled()||j(d.disableDynamicValidation,e.disabled),e.validateNonVisibleControls=j(d.validateNonVisibleControls,e.validateNonVisibleControls),e.validateOnFormSubmit=j(d.validateOnFormSubmit,e.validateOnFormSubmit),e.removeExternalValidationErrorsOnSubmit=void 0===d.removeExternalValidationErrorsOnSubmit?e.removeExternalValidationErrorsOnSubmit:j(d.removeExternalValidationErrorsOnSubmit,e.removeExternalValidationErrorsOnSubmit),c.isEnabled()===!1&&"false"===d.disableDynamicValidation&&(e.disabled=!1)}function l(a){return{restrict:"E",link:function(b,c){function d(){a.resetForm(c),e.$setPristine&&e.$setPristine(),e.$setUntouched&&e.$setUntouched()}var e=c.controller("form");void 0!==e&&e.autoValidateFormOptions&&e.autoValidateFormOptions.disabled===!1&&(c.on("reset",d),b.$on("$destroy",function(){c.off("reset",d)}))}}}function m(){var a=function(a){for(var c=a,d=0;50>=d&&(void 0===c||"form"!==c.nodeName.toLowerCase());d+=1)void 0!==c&&(c=b.element(c).parent()[0]);return c};return{restrict:"A",link:function(b,c){var d=a(c.parent()[0]);d&&(d.customHTMLFormControlsCollection=d.customHTMLFormControlsCollection||[],d.customHTMLFormControlsCollection.push(c[0]))}}}function n(a,b,c){return a[0].compile=function(a,d){var e=b(d.ngSubmit),f="true"===d.ngSubmitForce;return function(a,b){function d(d){a.$apply(function(){void 0!==i&&null!==i&&i.autoValidateFormOptions&&i.autoValidateFormOptions.disabled===!0?e(a,{$event:d}):(void 0===i.$setSubmitted&&(i.$submitted=!0),(c.validateForm(b)||f===!0)&&e(a,{$event:d}))})}function g(){b[0].reset?b[0].reset():c.resetForm(b)}var h,i=b.controller("form");i&&i.autoValidateFormOptions&&(i.autoValidateFormOptions.resetForm=g,void 0!==i.$name&&""!==i.$name&&(h=a.$on("form:"+i.$name+":reset",g))),b.on("submit",d),a.$on("$destroy",function(){b.off("submit",d),h&&h()})}},a}function o(a){a.decorator("ngSubmitDirective",n)}function p(a,b,c,d){a.setErrorMessageResolver(b.resolve),a.registerDomModifier(c.key,c),a.registerDomModifier(d.key,d),a.setDefaultElementModifier(c.key)}b.module("jcs-autoValidate",[]),b.module("jcs-autoValidate").provider("validator",c),d.$inject=["$log"],b.module("jcs-autoValidate").factory("bootstrap3ElementModifier",d),e.$inject=["$timeout"],b.module("jcs-autoValidate").factory("jcs-debounce",e),"format"in a.prototype||(a.prototype.format=function(){var a=arguments;return this.replace(/{(\d+)}/g,function(b,c){return void 0!==typeof a[c]?a[c]:b})}),b.autoValidate=b.autoValidate||{errorMessages:{}},b.autoValidate.errorMessages["en-us"]=b.autoValidate.errorMessages["en-gb"]={defaultMsg:"Please add error message for {0}",email:"Please enter a valid email address",minlength:"Please enter at least {0} characters",maxlength:"You have entered more than the maximum {0} characters",min:"Please enter the minimum number of {0}",max:"Please enter the maximum number of {0}",required:"This field is required",date:"Please enter a valid date",pattern:"Please ensure the entered information adheres to this pattern {0}",number:"Please enter a valid number",url:"Please enter a valid URL in the format of http(s)://www.google.com"},f.$inject=["$q","$http"],b.module("jcs-autoValidate").factory("defaultErrorMessageResolver",f),b.module("jcs-autoValidate").factory("foundation5ElementModifier",g),i.$inject=["validator","jcs-elementUtils"],b.module("jcs-autoValidate").factory("jcs-elementUtils",h),b.module("jcs-autoValidate").factory("validationManager",i),b.module("jcs-autoValidate").directive("form",["validator",function(a){return{restrict:"E",require:"form",priority:9999,compile:function(){return{pre:function(b,c,d,e){k(e,a,d)}}}}}]),b.module("jcs-autoValidate").directive("ngForm",["validator",function(a){return{restrict:"EA",require:"form",priority:9999,compile:function(){return{pre:function(b,c,d,e){k(e,a,d)}}}}}]),l.$inject=["validationManager"],b.module("jcs-autoValidate").directive("form",l),b.module("jcs-autoValidate").directive("registerCustomFormControl",m),n.$inject=["$delegate","$parse","validationManager"],o.$inject=["$provide"],b.module("jcs-autoValidate").config(o),b.module("jcs-autoValidate").config(["$provide",function(a){a.decorator("ngModelDirective",["$timeout","$delegate","validationManager","jcs-debounce",function(a,c,d,e){var f=c[0],g=f.link||f.compile;return f.compile=function(a){var c=b.version.major>=1&&b.version.minor>=3,f=g;return c&&b.isFunction(g)&&(f=g(a)),{pre:function(a,g,h,i){var j=i[0],k=i[1],l=void 0===h.ngModelOptions?void 0:a.$eval(h.ngModelOptions),m=j.$setValidity,n=j.$setPristine,o=e.debounce(function(){var a=void 0!==k&&null!==k?k.autoValidateFormOptions:void 0;d.validateElement(j,g,a)},100);return void 0===h.formnovalidate&&void 0!==k&&null!==k&&k.autoValidateFormOptions&&k.autoValidateFormOptions.disabled===!1&&(c||void 0===l||void 0===l.updateOn||""===l.updateOn?j.$setValidity=function(a,b){m.call(j,a,b),o()}:(g.on(l.updateOn,function(){o()}),a.$on("$destroy",function(){g.off(l.updateOn)})),j.$setPristine=function(){n.call(j),d.resetElement(g)},j.autoValidated=!0),j.setExternalValidation=function(a,b,c){if(c){var e=j.$error||j.$errors;e[a]=!1}j.externalErrors=j.externalErrors||{},j.externalErrors[a]=!1,d.setElementValidationError(g,a,b)},j.removeExternalValidation=function(a,b){if(b){var c=j.$error||j.$errors;delete c[a]}j.externalErrors&&delete j.externalErrors[a],d.resetElement(g)},j.removeAllExternalValidation=function(){if(j.externalErrors){var a=j.$error||j.$errors;b.forEach(j.externalErrors,function(b,c){delete a[c]}),j.externalErrors={},d.resetElement(g)}},k&&(k.setExternalValidation=function(a,b,c,d){var e=!1;return k[a]&&(k[a].setExternalValidation(b,c,d),e=!0),e},k.removeExternalValidation=function(a,b,c,d){var e=!1;return k[a]&&(k[a].removeExternalValidation(b,d),e=!0),e}),f.pre?f.pre.apply(this,arguments):this},post:function(a,b,c,d){return f.post?f.post.apply(this,arguments):f.apply(this,arguments)}}},c}])}]),p.$inject=["validator","defaultErrorMessageResolver","bootstrap3ElementModifier","foundation5ElementModifier"],b.module("jcs-autoValidate").run(p)}(String,angular);

@@ -26,3 +26,3 @@ (function (module) {

jshint: {
files: ['<%= srcfolder %>**/*.js', '<%= testsfolder %>**/*.spec.js'],
files: ['<%= srcfolder %>**/*.js','!<%= srcfolder %>**/*-postfix.js', '!<%= srcfolder %>**/*-prefix.js', '<%= testsfolder %>**/*.spec.js'],
options: {

@@ -54,3 +54,3 @@ jshintrc: '.jshintrc'

indentLevel: 0,
indentSize: 4,
indentSize: 2,
indentWithTabs: false,

@@ -156,3 +156,5 @@ jslintHappy: true,

dist: {
src: ['src/jcs-auto-validate.js',
src: [
'src/jcs-auto-validate-prefix.js',
'src/jcs-auto-validate.js',
'src/providers/validator.js',

@@ -169,3 +171,5 @@ 'src/services/bootstrap3ElementModifier.js',

'src/config/ngModelDecorator.js',
'src/jcs-auto-validate-run.js'],
'src/jcs-auto-validate-run.js',
'src/jcs-auto-validate-postfix.js'
],
dest: 'dist/jcs-auto-validate.js'

@@ -182,3 +186,3 @@ }

files: {
'tests/reports/complexity': ['src/**/*.js']
'tests/reports/complexity': ['src/**/*.js', '!src/**/*-postfix.js', '!src/**/*-prefix.js']
}

@@ -185,0 +189,0 @@ }

{
"name": "angular-auto-validate",
"version": "1.18.6",
"version": "1.18.14",
"description": "An automatic validation module for AngularJS which gets rid of excess html in favour of dynamic element modification to notify the user of validation errors",

@@ -5,0 +5,0 @@ "main": "angular-auto-validate.min.js",

@@ -1,138 +0,136 @@

(function (angular) {
'use strict';
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngModelDirective', [
'$timeout',
'$delegate',
'validationManager',
'jcs-debounce',
function ($timeout, $delegate, validationManager, debounce) {
var directive = $delegate[0],
link = directive.link || directive.compile;
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngModelDirective', [
'$timeout',
'$delegate',
'validationManager',
'jcs-debounce',
function ($timeout, $delegate, validationManager, debounce) {
var directive = $delegate[0],
link = directive.link || directive.compile;
directive.compile = function (el) {
var supportsNgModelOptions = angular.version.major >= 1 && angular.version.minor >= 3,
originalLink = link;
directive.compile = function (el) {
return function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0],
frmCtrl = ctrls[1],
supportsNgModelOptions = angular.version.major >= 1 && angular.version.minor >= 3,
ngModelOptions = attrs.ngModelOptions === undefined ? undefined : scope.$eval(attrs.ngModelOptions),
setValidity = ngModelCtrl.$setValidity,
setPristine = ngModelCtrl.$setPristine,
setValidationState = debounce.debounce(function () {
var validateOptions = frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : undefined;
validationManager.validateElement(ngModelCtrl, element, validateOptions);
}, 100);
// in the RC of 1.3 there is no directive.link only the directive.compile which
// needs to be invoked to get at the link functions.
if (supportsNgModelOptions && angular.isFunction(link)) {
originalLink = link(el);
}
// in the RC of 1.3 there is no directive.link only the directive.compile which
// needs to be invoked to get at the link functions.
if (supportsNgModelOptions && angular.isFunction(link)) {
link = link(el);
}
return {
pre: function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0],
frmCtrl = ctrls[1],
ngModelOptions = attrs.ngModelOptions === undefined ? undefined : scope.$eval(attrs.ngModelOptions),
setValidity = ngModelCtrl.$setValidity,
setPristine = ngModelCtrl.$setPristine,
setValidationState = debounce.debounce(function () {
var validateOptions = frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : undefined;
validationManager.validateElement(ngModelCtrl, element, validateOptions);
}, 100);
if (link.pre) {
link.pre.apply(this, arguments);
ngModelOptions = ngModelCtrl.$options === undefined ? undefined : ngModelCtrl.$options;
}
if (attrs.formnovalidate === undefined &&
(frmCtrl !== undefined && frmCtrl !== null && frmCtrl.autoValidateFormOptions &&
frmCtrl.autoValidateFormOptions.disabled === false)) {
if (supportsNgModelOptions || ngModelOptions === undefined || ngModelOptions.updateOn === undefined || ngModelOptions.updateOn === '') {
ngModelCtrl.$setValidity = function (validationErrorKey, isValid) {
setValidity.call(ngModelCtrl, validationErrorKey, isValid);
setValidationState();
};
} else {
element.on(ngModelOptions.updateOn, function () {
setValidationState();
});
if (attrs.formnovalidate === undefined &&
(frmCtrl !== undefined && frmCtrl !== null && frmCtrl.autoValidateFormOptions &&
frmCtrl.autoValidateFormOptions.disabled === false)) {
if (supportsNgModelOptions || ngModelOptions === undefined || ngModelOptions.updateOn === undefined || ngModelOptions.updateOn === '') {
ngModelCtrl.$setValidity = function (validationErrorKey, isValid) {
setValidity.call(ngModelCtrl, validationErrorKey, isValid);
setValidationState();
};
} else {
element.on(ngModelOptions.updateOn, function () {
setValidationState();
});
scope.$on('$destroy', function () {
element.off(ngModelOptions.updateOn);
});
}
scope.$on('$destroy', function () {
element.off(ngModelOptions.updateOn);
});
}
// We override this so we can reset the element state when it is called.
ngModelCtrl.$setPristine = function () {
setPristine.call(ngModelCtrl);
validationManager.resetElement(element);
};
// We override this so we can reset the element state when it is called.
ngModelCtrl.$setPristine = function () {
setPristine.call(ngModelCtrl);
validationManager.resetElement(element);
};
ngModelCtrl.autoValidated = true;
}
ngModelCtrl.autoValidated = true;
}
ngModelCtrl.setExternalValidation = function (errorMsgKey, errorMessage, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = false;
}
if (link.post) {
link.post.apply(this, arguments);
} else {
link.apply(this, arguments);
}
ngModelCtrl.externalErrors = ngModelCtrl.externalErrors || {};
ngModelCtrl.externalErrors[errorMsgKey] = false;
validationManager.setElementValidationError(element, errorMsgKey, errorMessage);
};
ngModelCtrl.setExternalValidation = function (errorMsgKey, errorMessage, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = false;
}
ngModelCtrl.removeExternalValidation = function (errorMsgKey, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
delete collection[errorMsgKey];
}
ngModelCtrl.externalErrors = ngModelCtrl.externalErrors || {};
ngModelCtrl.externalErrors[errorMsgKey] = false;
validationManager.setElementValidationError(element, errorMsgKey, errorMessage);
};
if (ngModelCtrl.externalErrors) {
delete ngModelCtrl.externalErrors[errorMsgKey];
}
ngModelCtrl.removeExternalValidation = function (errorMsgKey, addToModelErrors) {
if (addToModelErrors) {
var collection = ngModelCtrl.$error || ngModelCtrl.$errors;
collection[errorMsgKey] = true;
}
validationManager.resetElement(element);
};
if (ngModelCtrl.externalErrors) {
delete ngModelCtrl.externalErrors[errorMsgKey];
}
ngModelCtrl.removeAllExternalValidation = function () {
if (ngModelCtrl.externalErrors) {
var errorCollection = ngModelCtrl.$error || ngModelCtrl.$errors;
angular.forEach(ngModelCtrl.externalErrors, function (value, key) {
delete errorCollection[key];
});
validationManager.resetElement(element);
};
ngModelCtrl.externalErrors = {};
ngModelCtrl.removeAllExternalValidation = function () {
if (ngModelCtrl.externalErrors) {
var errorCollection = ngModelCtrl.$error || ngModelCtrl.$errors;
angular.forEach(ngModelCtrl.externalErrors, function (value, key) {
delete errorCollection[key];
});
validationManager.resetElement(element);
}
};
ngModelCtrl.externalErrors = {};
if (frmCtrl) {
frmCtrl.setExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].setExternalValidation(errorMsgKey, errorMessageOverride, addToModelErrors);
success = true;
}
validationManager.resetElement(element);
}
};
return success;
};
if (frmCtrl) {
frmCtrl.setExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].setExternalValidation(errorMsgKey, errorMessageOverride, addToModelErrors);
success = true;
}
frmCtrl.removeExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].removeExternalValidation(errorMsgKey, addToModelErrors);
success = true;
}
return success;
};
return success;
};
}
frmCtrl.removeExternalValidation = function (modelProperty, errorMsgKey, errorMessageOverride, addToModelErrors) {
var success = false;
if (frmCtrl[modelProperty]) {
frmCtrl[modelProperty].removeExternalValidation(errorMsgKey, addToModelErrors);
success = true;
}
return originalLink.pre ?
originalLink.pre.apply(this, arguments) :
this;
},
post: function (scope, element, attrs, ctrls) {
return originalLink.post ?
originalLink.post.apply(this, arguments) :
originalLink.apply(this, arguments);
}
};
};
return success;
};
}
};
};
return $delegate;
}
]);
}
return $delegate;
}
]);
}(angular));
}
]);

@@ -1,48 +0,78 @@

(function (angular) {
'use strict';
function SubmitDecorator($delegate, $parse, validationManager) {
$delegate[0].compile = function ($element, attrs) {
var fn = $parse(attrs.ngSubmit),
force = attrs.ngSubmitForce === 'true';
angular.module('jcs-autoValidate').config(['$provide',
function ($provide) {
$provide.decorator('ngSubmitDirective', [
'$delegate',
'$parse',
'validationManager',
function ($delegate, $parse, validationManager) {
$delegate[0].compile = function ($element, attrs) {
var fn = $parse(attrs.ngSubmit),
force = attrs.ngSubmitForce === 'true';
return function (scope, element) {
var formController = element.controller('form'),
resetListenerOffFn;
return function (scope, element) {
function handlerFn(event) {
scope.$apply(function () {
var formController = $element.controller('form');
if (formController !== undefined &&
formController !== null &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === true) {
fn(scope, {
$event: event
});
} else {
if (validationManager.validateForm(element) || force === true) {
fn(scope, {
$event: event
});
}
}
});
}
function handlerFn(event) {
scope.$apply(function () {
if (formController !== undefined &&
formController !== null &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === true) {
fn(scope, {
$event: event
});
} else {
if (formController.$setSubmitted === undefined) {
// we probably have angular <= 1.2
formController.$submitted = true;
}
element.on('submit', handlerFn);
scope.$on('$destroy', function () {
element.off('submit', handlerFn);
});
};
};
if (validationManager.validateForm(element) || force === true) {
fn(scope, {
$event: event
});
}
}
});
}
return $delegate;
}
]);
function resetFormFn() {
if (element[0].reset) {
element[0].reset();
} else {
validationManager.resetForm(element);
}
]);
}(angular));
}
if (formController && formController.autoValidateFormOptions) {
// allow the form to be reset programatically or via raising the event
// form:formName:reset
formController.autoValidateFormOptions.resetForm = resetFormFn;
if (formController.$name !== undefined && formController.$name !== '') {
resetListenerOffFn = scope.$on('form:' + formController.$name + ':reset', resetFormFn);
}
}
element.on('submit', handlerFn);
scope.$on('$destroy', function () {
element.off('submit', handlerFn);
if (resetListenerOffFn) {
resetListenerOffFn();
}
});
};
};
return $delegate;
}
SubmitDecorator.$inject = [
'$delegate',
'$parse',
'validationManager'
];
function ProviderFn($provide) {
$provide.decorator('ngSubmitDirective', SubmitDecorator);
}
ProviderFn.$inject = [
'$provide'
];
angular.module('jcs-autoValidate').config(ProviderFn);

@@ -1,55 +0,61 @@

(function (angular) {
'use strict';
function parseBooleanAttributeValue(val, defaultValue) {
if ((val === undefined || val === null) && defaultValue !== undefined) {
return defaultValue;
} else {
return val !== 'false';
}
}
function parseBooleanAttributeValue(val) {
return val !== undefined && val !== 'false';
}
function parseOptions(ctrl, validator, attrs) {
var opts = ctrl.autoValidateFormOptions = ctrl.autoValidateFormOptions || angular.copy(validator.defaultFormValidationOptions);
opts.formController = ctrl;
opts.forceValidation = false;
opts.disabled = !validator.isEnabled() || parseBooleanAttributeValue(attrs.disableDynamicValidation, opts.disabled);
opts.validateNonVisibleControls = parseBooleanAttributeValue(attrs.validateNonVisibleControls, opts.validateNonVisibleControls);
opts.validateOnFormSubmit = parseBooleanAttributeValue(attrs.validateOnFormSubmit, opts.validateOnFormSubmit);
opts.removeExternalValidationErrorsOnSubmit = attrs.removeExternalValidationErrorsOnSubmit === undefined ?
opts.removeExternalValidationErrorsOnSubmit :
parseBooleanAttributeValue(attrs.removeExternalValidationErrorsOnSubmit, opts.removeExternalValidationErrorsOnSubmit);
function parseOptions(ctrl, validator, attrs) {
var opts = ctrl.autoValidateFormOptions = ctrl.autoValidateFormOptions || angular.copy(validator.defaultFormValidationOptions);
opts.forceValidation = false;
opts.disabled = !validator.isEnabled() || parseBooleanAttributeValue(attrs.disableDynamicValidation);
opts.validateNonVisibleControls = parseBooleanAttributeValue(attrs.validateNonVisibleControls);
opts.removeExternalValidationErrorsOnSubmit = attrs.removeExternalValidationErrorsOnSubmit === undefined ? true : parseBooleanAttributeValue(attrs.removeExternalValidationErrorsOnSubmit);
// the library might be globally disabled but enabled on a particular form so check the
// disableDynamicValidation attribute is on the form
if (validator.isEnabled() === false && attrs.disableDynamicValidation === 'false') {
opts.disabled = false;
}
}
if (validator.isEnabled() === false && parseBooleanAttributeValue(attrs.disableDynamicValidation) === false) {
opts.disabled = false;
}
}
angular.module('jcs-autoValidate').directive('form', [
'validator',
function (validator) {
return {
restrict: 'E',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
angular.module('jcs-autoValidate').directive('form', [
'validator',
function (validator) {
return {
restrict: 'E',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
angular.module('jcs-autoValidate').directive('ngForm', [
'validator',
function (validator) {
return {
restrict: 'EA',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);
}(angular));
angular.module('jcs-autoValidate').directive('ngForm', [
'validator',
function (validator) {
return {
restrict: 'EA',
require: 'form',
priority: 9999,
compile: function () {
return {
pre: function (scope, element, attrs, ctrl) {
parseOptions(ctrl, validator, attrs);
}
};
}
};
}
]);

@@ -1,27 +0,35 @@

(function (angular) {
'use strict';
function FormResetDirectiveFn(validationManager) {
return {
restrict: 'E',
link: function (scope, el) {
var formController = el.controller('form');
angular.module('jcs-autoValidate').directive('form', [
'validationManager',
function (validationManager) {
return {
restrict: 'E',
link: function (scope, el) {
var formController = el.controller('form');
function resetFn() {
validationManager.resetForm(el);
if (formController.$setPristine) {
formController.$setPristine();
}
if (formController !== undefined &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === false) {
el.on('reset', function () {
validationManager.resetForm(el);
});
if (formController.$setUntouched) {
formController.$setUntouched();
}
}
scope.$on('$destroy', function () {
el.off('reset');
});
}
}
};
}
]);
}(angular));
if (formController !== undefined &&
formController.autoValidateFormOptions &&
formController.autoValidateFormOptions.disabled === false) {
el.on('reset', resetFn);
scope.$on('$destroy', function () {
el.off('reset', resetFn);
});
}
}
};
}
FormResetDirectiveFn.$inject = [
'validationManager'
];
angular.module('jcs-autoValidate').directive('form', FormResetDirectiveFn);

@@ -1,31 +0,27 @@

(function (angular) {
'use strict';
function RegisterCustomFormControlFn() {
var findParentForm = function (el) {
var parent = el;
for (var i = 0; i <= 50; i += 1) {
if (parent !== undefined && parent.nodeName.toLowerCase() === 'form') {
break;
} else if (parent !== undefined) {
parent = angular.element(parent).parent()[0];
}
}
angular.module('jcs-autoValidate').directive('registerCustomFormControl', [
function () {
var findParentForm = function (el) {
var parent = el;
for (var i = 0; i <= 50; i += 1) {
if (parent !== undefined && parent.nodeName.toLowerCase() === 'form') {
break;
} else if (parent !== undefined) {
parent = angular.element(parent).parent()[0];
}
}
return parent;
};
return parent;
};
return {
restrict: 'A',
link: function (scope, element) {
var frmEl = findParentForm(element.parent()[0]);
if (frmEl) {
frmEl.customHTMLFormControlsCollection = frmEl.customHTMLFormControlsCollection || [];
frmEl.customHTMLFormControlsCollection.push(element[0]);
}
}
};
}
return {
restrict: 'A',
link: function (scope, element) {
var frmEl = findParentForm(element.parent()[0]);
if (frmEl) {
frmEl.customHTMLFormControlsCollection = frmEl.customHTMLFormControlsCollection || [];
frmEl.customHTMLFormControlsCollection.push(element[0]);
}
}
};
}
]);
}(angular));
angular.module('jcs-autoValidate').directive('registerCustomFormControl', RegisterCustomFormControlFn);

@@ -1,17 +0,15 @@

(function (angular) {
'use strict';
function AutoValidateRunFn(validator, defaultErrorMessageResolver, bootstrap3ElementModifier, foundation5ElementModifier) {
validator.setErrorMessageResolver(defaultErrorMessageResolver.resolve);
validator.registerDomModifier(bootstrap3ElementModifier.key, bootstrap3ElementModifier);
validator.registerDomModifier(foundation5ElementModifier.key, foundation5ElementModifier);
validator.setDefaultElementModifier(bootstrap3ElementModifier.key);
}
angular.module('jcs-autoValidate')
.run([
'validator',
'defaultErrorMessageResolver',
'bootstrap3ElementModifier',
'foundation5ElementModifier',
function (validator, defaultErrorMessageResolver, bootstrap3ElementModifier, foundation5ElementModifier) {
validator.setErrorMessageResolver(defaultErrorMessageResolver.resolve);
validator.registerDomModifier(bootstrap3ElementModifier.key, bootstrap3ElementModifier);
validator.registerDomModifier(foundation5ElementModifier.key, foundation5ElementModifier);
validator.setDefaultElementModifier(bootstrap3ElementModifier.key);
}
]);
}(angular));
AutoValidateRunFn.$inject = [
'validator',
'defaultErrorMessageResolver',
'bootstrap3ElementModifier',
'foundation5ElementModifier'
];
angular.module('jcs-autoValidate').run(AutoValidateRunFn);

@@ -1,5 +0,1 @@

(function (angular) {
'use strict';
angular.module('jcs-autoValidate', []);
}(angular));
angular.module('jcs-autoValidate', []);

@@ -1,289 +0,285 @@

(function (angular) {
'use strict';
function ValidatorFn() {
var elementStateModifiers = {},
enableValidElementStyling = true,
enableInvalidElementStyling = true,
validationEnabled = true,
angular.module('jcs-autoValidate')
.provider('validator', [
function () {
var elementStateModifiers = {},
enableValidElementStyling = true,
enableInvalidElementStyling = true,
validationEnabled = true,
toBoolean = function (value) {
var v;
if (value && value.length !== 0) {
v = value.toLowerCase();
value = !(v === 'f' || v === '0' || v === 'false');
} else {
value = false;
}
toBoolean = function (value) {
var v;
if (value && value.length !== 0) {
v = value.toLowerCase();
value = !(v === 'f' || v === '0' || v === 'false');
} else {
value = false;
}
return value;
},
return value;
},
getAttributeValue = function (el, attrName) {
var val;
getAttributeValue = function (el, attrName) {
var val;
if (el !== undefined) {
val = el.attr(attrName) || el.attr('data-' + attrName);
}
if (el !== undefined) {
val = el.attr(attrName) || el.attr('data-' + attrName);
}
return val;
},
return val;
},
attributeExists = function (el, attrName) {
var exists;
attributeExists = function (el, attrName) {
var exists;
if (el !== undefined) {
exists = el.attr(attrName) !== undefined || el.attr('data-' + attrName) !== undefined;
}
if (el !== undefined) {
exists = el.attr(attrName) !== undefined || el.attr('data-' + attrName) !== undefined;
}
return exists;
},
return exists;
},
getBooleanAttributeValue = function (el, attrName) {
return toBoolean(getAttributeValue(el, attrName));
},
getBooleanAttributeValue = function (el, attrName) {
return toBoolean(getAttributeValue(el, attrName));
},
validElementStylingEnabled = function (el) {
return enableValidElementStyling && !getBooleanAttributeValue(el, 'disable-valid-styling');
},
validElementStylingEnabled = function (el) {
return enableValidElementStyling && !getBooleanAttributeValue(el, 'disable-valid-styling');
},
invalidElementStylingEnabled = function (el) {
return enableInvalidElementStyling && !getBooleanAttributeValue(el, 'disable-invalid-styling');
};
invalidElementStylingEnabled = function (el) {
return enableInvalidElementStyling && !getBooleanAttributeValue(el, 'disable-invalid-styling');
};
/**
* @ngdoc function
* @name validator#enable
* @methodOf validator
*
* @description
* By default auto validate will validate all forms and elements with an ngModel directive on. By
* setting enabled to false you will explicitly have to opt in to enable validation on forms and child
* elements.
*
* Note: this can be overridden by add the 'auto-validate-enabled="true/false' attribute to a form.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.enable(false);
* });
* </pre>
*
* @param {Boolean} isEnabled true to enable, false to disable.
*/
this.enable = function (isEnabled) {
validationEnabled = isEnabled;
};
/**
* @ngdoc function
* @name validator#enable
* @methodOf validator
*
* @description
* By default auto validate will validate all forms and elements with an ngModel directive on. By
* setting enabled to false you will explicitly have to opt in to enable validation on forms and child
* elements.
*
* Note: this can be overridden by add the 'auto-validate-enabled="true/false' attribute to a form.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.enable(false);
* });
* </pre>
*
* @param {Boolean} isEnabled true to enable, false to disable.
*/
this.enable = function (isEnabled) {
validationEnabled = isEnabled;
};
/**
* @ngdoc function
* @name validator#isEnabled
* @methodOf validator
*
* @description
* Returns true if the library is enabeld.
*
* @return {Boolean} true if enabled, otherwise false.
*/
this.isEnabled = function () {
return validationEnabled;
};
/**
* @ngdoc function
* @name validator#isEnabled
* @methodOf validator
*
* @description
* Returns true if the library is enabeld.
*
* @return {Boolean} true if enabled, otherwise false.
*/
this.isEnabled = function () {
return validationEnabled;
};
/**
* @ngdoc function
* @name validator#setDefaultElementModifier
* @methodOf validator
*
* @description
* Sets the default element modifier that will be used by the validator
* to change an elements UI state. Please ensure the modifier has been registered
* before setting it as default.
*
* Note: this can be changed by setting the
* element modifier attribute on the input element 'data-element-modifier="myCustomModifier"'
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setDefaultElementModifier('myCustomModifier');
* });
* </pre>
*
* @param {string} key The key name of the modifier.
*/
this.setDefaultElementModifier = function (key) {
if (elementStateModifiers[key] === undefined) {
throw new Error('Element modifier not registered: ' + key);
}
/**
* @ngdoc function
* @name validator#setDefaultElementModifier
* @methodOf validator
*
* @description
* Sets the default element modifier that will be used by the validator
* to change an elements UI state. Please ensure the modifier has been registered
* before setting it as default.
*
* Note: this can be changed by setting the
* element modifier attribute on the input element 'data-element-modifier="myCustomModifier"'
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setDefaultElementModifier('myCustomModifier');
* });
* </pre>
*
* @param {string} key The key name of the modifier.
*/
this.setDefaultElementModifier = function (key) {
if (elementStateModifiers[key] === undefined) {
throw new Error('Element modifier not registered: ' + key);
}
this.defaultElementModifier = key;
};
this.defaultElementModifier = key;
};
/**
* @ngdoc function
* @name validator#registerDomModifier
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.registerDomModifier('customDomModifier', {
* makeValid: function (el) {
* el.removeClass(el, 'invalid');
* el.addClass(el, 'valid');
* },
* makeInvalid: function (el, err, domManipulator) {
* el.removeClass(el, 'valid');
* el.addClass(el, 'invalid');
* }
* });
* });
* </pre>
*
* @param {string} key The key name of the modifier
* @param {object} modifier An object which implements the elementModifier interface
*/
this.registerDomModifier = function (key, modifier) {
elementStateModifiers[key] = modifier;
};
/**
* @ngdoc function
* @name validator#registerDomModifier
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.registerDomModifier('customDomModifier', {
* makeValid: function (el) {
* el.removeClass(el, 'invalid');
* el.addClass(el, 'valid');
* },
* makeInvalid: function (el, err, domManipulator) {
* el.removeClass(el, 'valid');
* el.addClass(el, 'invalid');
* }
* });
* });
* </pre>
*
* @param {string} key The key name of the modifier
* @param {object} modifier An object which implements the elementModifier interface
*/
this.registerDomModifier = function (key, modifier) {
elementStateModifiers[key] = modifier;
};
/**
* @ngdoc function
* @name validator#setErrorMessageResolver
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setErrorMessageResolver(function (errorKey, el) {
* var defer = $q.defer();
* // resolve the correct error from the given key and resolve the returned promise.
* return defer.promise();
* });
* });
* </pre>
*
* @param {function} resolver A method that returns a promise with the resolved error message in.
*/
this.setErrorMessageResolver = function (resolver) {
this.errorMessageResolver = resolver;
};
/**
* @ngdoc function
* @name validator#setErrorMessageResolver
* @methodOf validator
*
* @description
* Registers an object that adheres to the elementModifier interface and is
* able to modifier an elements dom so that appears valid / invalid for a specific
* scenario i.e. the Twitter Bootstrap css framework, Foundation CSS framework etc.
*
* Example:
* <pre>
* app.config(function (validator) {
* validator.setErrorMessageResolver(function (errorKey, el) {
* var defer = $q.defer();
* // resolve the correct error from the given key and resolve the returned promise.
* return defer.promise();
* });
* });
* </pre>
*
* @param {function} resolver A method that returns a promise with the resolved error message in.
*/
this.setErrorMessageResolver = function (resolver) {
this.errorMessageResolver = resolver;
};
/**
* @ngdoc function
* @name validator#getErrorMessage
* @methodOf validator
*
* @description
* Resolves the error message for the given error type.
*
* @param {String} errorKey The error type.
* @param {Element} el The UI element that is the focus of the error.
* It is provided as the error message may need information from the element i.e. ng-min (the min allowed value).
*/
this.getErrorMessage = function (errorKey, el) {
var defer;
if (this.errorMessageResolver === undefined) {
throw new Error('Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
}
/**
* @ngdoc function
* @name validator#getErrorMessage
* @methodOf validator
*
* @description
* Resolves the error message for the given error type.
*
* @param {String} errorKey The error type.
* @param {Element} el The UI element that is the focus of the error.
* It is provided as the error message may need information from the element i.e. ng-min (the min allowed value).
*/
this.getErrorMessage = function (errorKey, el) {
var defer;
if (this.errorMessageResolver === undefined) {
throw new Error('Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
}
if (attributeExists(el, 'disable-validation-message')) {
defer = angular.injector(['ng']).get('$q').defer();
defer.resolve('');
return defer.promise;
} else {
return this.errorMessageResolver(errorKey, el);
}
};
if (attributeExists(el, 'disable-validation-message')) {
defer = angular.injector(['ng']).get('$q').defer();
defer.resolve('');
return defer.promise;
} else {
return this.errorMessageResolver(errorKey, el);
}
};
/**
* @ngdoc function
* @name validator#setValidElementStyling
* @methodOf validator
*
* @description
* Globally enables valid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setValidElementStyling = function (enabled) {
enableValidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setValidElementStyling
* @methodOf validator
*
* @description
* Globally enables valid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setValidElementStyling = function (enabled) {
enableValidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setInvalidElementStyling
* @methodOf validator
*
* @description
* Globally enables invalid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setInvalidElementStyling = function (enabled) {
enableInvalidElementStyling = enabled;
};
/**
* @ngdoc function
* @name validator#setInvalidElementStyling
* @methodOf validator
*
* @description
* Globally enables invalid element visual styling. This is enabled by default.
*
* @param {Boolean} enabled True to enable style otherwise false.
*/
this.setInvalidElementStyling = function (enabled) {
enableInvalidElementStyling = enabled;
};
this.getDomModifier = function (el) {
var modifierKey = (el !== undefined ? el.attr('element-modifier') : this.defaultElementModifier) ||
(el !== undefined ? el.attr('data-element-modifier') : this.defaultElementModifier) ||
this.defaultElementModifier;
this.getDomModifier = function (el) {
var modifierKey = (el !== undefined ? el.attr('element-modifier') : this.defaultElementModifier) ||
(el !== undefined ? el.attr('data-element-modifier') : this.defaultElementModifier) ||
this.defaultElementModifier;
if (modifierKey === undefined) {
throw new Error('Please set a default dom modifier via the setDefaultElementModifier method on the validator class.');
}
if (modifierKey === undefined) {
throw new Error('Please set a default dom modifier via the setDefaultElementModifier method on the validator class.');
}
return elementStateModifiers[modifierKey];
};
return elementStateModifiers[modifierKey];
};
this.makeValid = function (el) {
if (validElementStylingEnabled(el)) {
this.getDomModifier(el).makeValid(el);
} else {
this.makeDefault(el);
}
};
this.makeValid = function (el) {
if (validElementStylingEnabled(el)) {
this.getDomModifier(el).makeValid(el);
} else {
this.makeDefault(el);
}
};
this.makeInvalid = function (el, errorMsg) {
if (invalidElementStylingEnabled(el)) {
this.getDomModifier(el).makeInvalid(el, errorMsg);
} else {
this.makeDefault(el);
}
};
this.makeInvalid = function (el, errorMsg) {
if (invalidElementStylingEnabled(el)) {
this.getDomModifier(el).makeInvalid(el, errorMsg);
} else {
this.makeDefault(el);
}
};
this.makeDefault = function (el) {
var dm = this.getDomModifier(el);
if (dm.makeDefault) {
dm.makeDefault(el);
}
};
this.makeDefault = function (el) {
var dm = this.getDomModifier(el);
if (dm.makeDefault) {
dm.makeDefault(el);
}
};
this.defaultFormValidationOptions = {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false,
removeExternalValidationErrorsOnSubmit: true,
validateOnFormSubmit: false
};
this.defaultFormValidationOptions = {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false,
removeExternalValidationErrorsOnSubmit: true
};
this.$get = [
function () {
return this;
}
];
}
this.$get = [
function () {
return this;
}
];
}
]);
}(angular));
angular.module('jcs-autoValidate').provider('validator', ValidatorFn);

@@ -1,183 +0,181 @@

(function (angular) {
'use strict';
function Bootstrap3ElementModifierFn($log) {
var reset = function (el) {
angular.forEach(el.find('span'), function (spanEl) {
spanEl = angular.element(spanEl);
if (spanEl.hasClass('error-msg') || spanEl.hasClass('form-control-feedback') || spanEl.hasClass('control-feedback')) {
spanEl.remove();
}
});
angular.module('jcs-autoValidate')
.factory('bootstrap3ElementModifier', [
'$log',
function ($log) {
var reset = function (el) {
angular.forEach(el.find('span'), function (spanEl) {
spanEl = angular.element(spanEl);
if (spanEl.hasClass('error-msg') || spanEl.hasClass('form-control-feedback') || spanEl.hasClass('control-feedback')) {
spanEl.remove();
}
});
el.removeClass('has-success has-error has-feedback');
},
findWithClassElementAsc = function (el, klass) {
var returnEl,
parent = el;
for (var i = 0; i <= 10; i += 1) {
if (parent !== undefined && parent.hasClass(klass)) {
returnEl = parent;
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
el.removeClass('has-success has-error has-feedback');
},
findWithClassElementAsc = function (el, klass) {
var returnEl,
parent = el;
for (var i = 0; i <= 10; i += 1) {
if (parent !== undefined && parent.hasClass(klass)) {
returnEl = parent;
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
return returnEl;
},
return returnEl;
},
findWithClassElementDesc = function (el, klass) {
var child;
for (var i = 0; i < el.children.length; i += 1) {
child = el.children[i];
if (child !== undefined && angular.element(child).hasClass(klass)) {
break;
} else if (child.children !== undefined) {
child = findWithClassElementDesc(child, klass);
if (child.length > 0) {
break;
}
}
}
findWithClassElementDesc = function (el, klass) {
var child;
for (var i = 0; i < el.children.length; i += 1) {
child = el.children[i];
if (child !== undefined && angular.element(child).hasClass(klass)) {
break;
} else if (child.children !== undefined) {
child = findWithClassElementDesc(child, klass);
if (child.length > 0) {
break;
}
}
}
return angular.element(child);
},
return angular.element(child);
},
findFormGroupElement = function (el) {
return findWithClassElementAsc(el, 'form-group');
},
findFormGroupElement = function (el) {
return findWithClassElementAsc(el, 'form-group');
},
findInputGroupElement = function (el) {
return findWithClassElementDesc(el, 'input-group');
},
findInputGroupElement = function (el) {
return findWithClassElementDesc(el, 'input-group');
},
insertAfter = function (referenceNode, newNode) {
referenceNode[0].parentNode.insertBefore(newNode[0], referenceNode[0].nextSibling);
},
insertAfter = function (referenceNode, newNode) {
referenceNode[0].parentNode.insertBefore(newNode[0], referenceNode[0].nextSibling);
},
/**
* @ngdoc property
* @name bootstrap3ElementModifier#addValidationStateIcons
* @propertyOf bootstrap3ElementModifier
* @returns {bool} True if an state icon will be added to the element in the valid and invalid control
* states. The default is false.
*/
addValidationStateIcons = false,
/**
* @ngdoc property
* @name bootstrap3ElementModifier#addValidationStateIcons
* @propertyOf bootstrap3ElementModifier
* @returns {bool} True if an state icon will be added to the element in the valid and invalid control
* states. The default is false.
*/
addValidationStateIcons = false,
/**
* @ngdoc function
* @name bootstrap3ElementModifier#enableValidationStateIcons
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply an icon to the input element.
*
* @param {bool} enable - True to enable the icon otherwise false.
*/
enableValidationStateIcons = function (enable) {
addValidationStateIcons = enable;
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#enableValidationStateIcons
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply an icon to the input element.
*
* @param {bool} enable - True to enable the icon otherwise false.
*/
enableValidationStateIcons = function (enable) {
addValidationStateIcons = enable;
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeValid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear valid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var frmGroupEl = findFormGroupElement(el),
inputGroupEl;
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeValid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear valid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var frmGroupEl = findFormGroupElement(el),
inputGroupEl;
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-success ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-ok form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-success ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-ok form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeInvalid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var frmGroupEl = findFormGroupElement(el),
helpTextEl = angular.element('<span class="help-block has-error error-msg">' + errorMsg + '</span>'),
inputGroupEl;
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeInvalid
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear invalid by apply bootstrap 3 specific styles and child elements. If the service
* property 'addValidationStateIcons' is true it will also append validation glyphicon to the element.
* See: http://getbootstrap.com/css/#forms-control-validation
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var frmGroupEl = findFormGroupElement(el),
helpTextEl = angular.element('<span class="help-block has-error error-msg">' + errorMsg + '</span>'),
inputGroupEl;
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-error ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
insertAfter(inputGroupEl.length > 0 ? inputGroupEl : el, helpTextEl);
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-remove form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
if (frmGroupEl) {
reset(frmGroupEl);
inputGroupEl = findInputGroupElement(frmGroupEl[0]);
frmGroupEl.addClass('has-error ' + (inputGroupEl.length > 0 ? '' : 'has-feedback'));
insertAfter(inputGroupEl.length > 0 ? inputGroupEl : el, helpTextEl);
if (addValidationStateIcons) {
var iconElText = '<span class="glyphicon glyphicon-remove form-control-feedback"></span>';
if (inputGroupEl.length > 0) {
iconElText = iconElText.replace('form-', '');
iconElText = '<span class="input-group-addon control-feedback">' + iconElText + '</span';
}
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
insertAfter(el, angular.element(iconElText));
}
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
},
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeDefault
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply bootstrap 3 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
var frmGroupEl = findFormGroupElement(el);
if (frmGroupEl) {
reset(frmGroupEl);
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
};
/**
* @ngdoc function
* @name bootstrap3ElementModifier#makeDefault
* @methodOf bootstrap3ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply bootstrap 3 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
var frmGroupEl = findFormGroupElement(el);
if (frmGroupEl) {
reset(frmGroupEl);
} else {
$log.error('Angular-auto-validate: invalid bs3 form structure elements must be wrapped by a form-group class');
}
};
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
enableValidationStateIcons: enableValidationStateIcons,
key: 'bs3'
};
}
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
enableValidationStateIcons: enableValidationStateIcons,
key: 'bs3'
};
}
]);
}(angular));
Bootstrap3ElementModifierFn.$inject = [
'$log'
];
angular.module('jcs-autoValidate').factory('bootstrap3ElementModifier', Bootstrap3ElementModifierFn);

@@ -1,35 +0,34 @@

(function (angular) {
'use strict';
/*
* Taken from https://github.com/angular/angular.js/issues/2690#issue-14462164 (with added tests of course!)
*/
function JCSDebounceFn($timeout) {
var debounce = function (fn, timeout, apply) {
timeout = angular.isUndefined(timeout) ? 0 : timeout;
apply = angular.isUndefined(apply) ? true : apply; // !!default is true! most suitable to my experience
var nthCall = 0;
return function () { // intercepting fn
var that = this;
var argz = arguments;
nthCall += 1;
var later = (function (version) {
return function () {
if (version === nthCall) {
return fn.apply(that, argz);
}
};
})(nthCall);
/*
* Taken from https://github.com/angular/angular.js/issues/2690#issue-14462164 (with added tests of course!)
*/
angular.module('jcs-autoValidate').factory('jcs-debounce', [
'$timeout',
function ($timeout) {
var debounce = function (fn, timeout, apply) {
timeout = angular.isUndefined(timeout) ? 0 : timeout;
apply = angular.isUndefined(apply) ? true : apply; // !!default is true! most suitable to my experience
var nthCall = 0;
return function () { // intercepting fn
var that = this;
var argz = arguments;
nthCall += 1;
var later = (function (version) {
return function () {
if (version === nthCall) {
return fn.apply(that, argz);
}
};
})(nthCall);
return $timeout(later, timeout, apply);
};
};
return $timeout(later, timeout, apply);
};
};
return {
debounce: debounce
};
}
return {
debounce: debounce
};
}
]);
}(angular));
JCSDebounceFn.$inject = [
'$timeout'
];
angular.module('jcs-autoValidate').factory('jcs-debounce', JCSDebounceFn);

@@ -1,202 +0,200 @@

(function (String, angular) {
'use strict';
/**
* Replaces string placeholders with corresponding template string
*/
if (!('format' in String.prototype)) {
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] !== undefined ? args[number] : match;
});
};
}
/**
* Replaces string placeholders with corresponding template string
*/
if (!('format' in String.prototype)) {
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] !== undefined ? args[number] : match;
});
};
}
angular.autoValidate = angular.autoValidate || {
errorMessages: {}
};
angular.autoValidate = angular.autoValidate || {
errorMessages: {}
};
angular.autoValidate.errorMessages['en-us'] = angular.autoValidate.errorMessages['en-gb'] = {
defaultMsg: 'Please add error message for {0}',
email: 'Please enter a valid email address',
minlength: 'Please enter at least {0} characters',
maxlength: 'You have entered more than the maximum {0} characters',
min: 'Please enter the minimum number of {0}',
max: 'Please enter the maximum number of {0}',
required: 'This field is required',
date: 'Please enter a valid date',
pattern: 'Please ensure the entered information adheres to this pattern {0}',
number: 'Please enter a valid number',
url: 'Please enter a valid URL in the format of http(s)://www.google.com'
};
angular.autoValidate.errorMessages['en-us'] = angular.autoValidate.errorMessages['en-gb'] = {
defaultMsg: 'Please add error message for {0}',
email: 'Please enter a valid email address',
minlength: 'Please enter at least {0} characters',
maxlength: 'You have entered more than the maximum {0} characters',
min: 'Please enter the minimum number of {0}',
max: 'Please enter the maximum number of {0}',
required: 'This field is required',
date: 'Please enter a valid date',
pattern: 'Please ensure the entered information adheres to this pattern {0}',
number: 'Please enter a valid number',
url: 'Please enter a valid URL in the format of http(s)://www.google.com'
};
function DefaultErrorMessageResolverFn($q, $http) {
var currentCulture = 'en-gb',
angular.module('jcs-autoValidate')
.factory('defaultErrorMessageResolver', [
'$q',
'$http',
function ($q, $http) {
var currentCulture = 'en-gb',
i18nFileRootPath = 'js/angular-auto-validate/dist/lang',
i18nFileRootPath = 'js/angular-auto-validate/dist/lang',
cultureRetrievalPromise,
cultureRetrievalPromise,
loadRemoteCulture = function (culture) {
cultureRetrievalPromise = $http.get('{0}/jcs-auto-validate_{1}.json'.format(i18nFileRootPath, culture.toLowerCase()));
return cultureRetrievalPromise;
},
loadRemoteCulture = function (culture) {
cultureRetrievalPromise = $http.get('{0}/jcs-auto-validate_{1}.json'.format(i18nFileRootPath, culture.toLowerCase()));
return cultureRetrievalPromise;
},
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setI18nFileRootPath
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the root path to the il8n files on the server
*
* @param {String} rootPath - The root path on the server to the il8n file - this defaults
* to 'js/angular-auto-validate/lang/'
*/
setI18nFileRootPath = function (rootPath) {
i18nFileRootPath = rootPath;
},
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setI18nFileRootPath
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the root path to the il8n files on the server
*
* @param {String} rootPath - The root path on the server to the il8n file - this defaults
* to 'js/angular-auto-validate/lang/'
*/
setI18nFileRootPath = function (rootPath) {
i18nFileRootPath = rootPath;
},
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setCulture
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the culture for the error messages by loading an the correct culture resource file.
*
* @param {String} culture - The new culture in the format of 'en-gb' etc.
* @param {Function} cultureLoadingFn - A optional function to load the culture resolve which should
* return a promise which is resolved with the culture errorMessage object. If a function is not specified
* the culture file is loaded from the **i18nFileRootPath**.
* @returns {Promise} - A promise which is resolved with the loaded culture error messages object.
*/
setCulture = function (culture, cultureLoadingFn) {
var defer = $q.defer();
cultureLoadingFn = cultureLoadingFn || loadRemoteCulture;
currentCulture = culture.toLowerCase();
if (angular.autoValidate.errorMessages[currentCulture] === undefined) {
cultureRetrievalPromise = cultureLoadingFn(culture);
cultureRetrievalPromise.then(function (response) {
cultureRetrievalPromise = undefined;
angular.autoValidate.errorMessages[currentCulture] = response.data;
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}, function (err) {
angular.autoValidate.errorMessages[currentCulture] = {
defaultMsg: 'Loading culture failed!'
};
cultureRetrievalPromise = null;
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}
/**
* @ngdoc function
* @name defaultErrorMessageResolver#setCulture
* @methodOf defaultErrorMessageResolver
*
* @description
* Set the culture for the error messages by loading an the correct culture resource file.
*
* @param {String} culture - The new culture in the format of 'en-gb' etc.
* @param {Function} cultureLoadingFn - A optional function to load the culture resolve which should
* return a promise which is resolved with the culture errorMessage object. If a function is not specified
* the culture file is loaded from the **i18nFileRootPath**.
* @returns {Promise} - A promise which is resolved with the loaded culture error messages object.
*/
setCulture = function (culture, cultureLoadingFn) {
var defer = $q.defer();
cultureLoadingFn = cultureLoadingFn || loadRemoteCulture;
currentCulture = culture.toLowerCase();
if (angular.autoValidate.errorMessages[currentCulture] === undefined) {
cultureRetrievalPromise = cultureLoadingFn(culture);
cultureRetrievalPromise.then(function (response) {
cultureRetrievalPromise = undefined;
angular.autoValidate.errorMessages[currentCulture] = response.data;
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}, function (err) {
angular.autoValidate.errorMessages[currentCulture] = {
defaultMsg: 'Loading culture failed!'
};
cultureRetrievalPromise = null;
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[currentCulture]);
}
return defer.promise;
},
return defer.promise;
},
getErrorMessages = function (culture) {
var defer = $q.defer();
culture = culture === undefined ? currentCulture : culture.toLowerCase();
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}, function (err) {
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}
return defer.promise;
},
getErrorMessages = function (culture) {
var defer = $q.defer();
culture = culture === undefined ? currentCulture : culture.toLowerCase();
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}, function (err) {
defer.reject(err);
});
} else {
defer.resolve(angular.autoValidate.errorMessages[culture]);
}
return defer.promise;
},
getMessageTypeOverride = function (errorType, el) {
var overrideKey;
getMessageTypeOverride = function (errorType, el) {
var overrideKey;
if (el) {
// try and find an attribute which overrides the given error type in the form of errorType-err-type="someMsgKey"
errorType += '-err-type';
if (el) {
// try and find an attribute which overrides the given error type in the form of errorType-err-type="someMsgKey"
errorType += '-err-type';
overrideKey = el.attr('ng-' + errorType);
if (overrideKey === undefined) {
overrideKey = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
overrideKey = el.attr('ng-' + errorType);
if (overrideKey === undefined) {
overrideKey = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
if (overrideKey) {
overrideKey = overrideKey.replace(/[\W]/g, '');
}
}
if (overrideKey) {
overrideKey = overrideKey.replace(/[\W]/g, '');
}
}
return overrideKey;
},
return overrideKey;
},
/**
* @ngdoc function
* @name defaultErrorMessageResolver#resolve
* @methodOf defaultErrorMessageResolver
*
* @description
* Resolves a validate error type into a user validation error message
*
* @param {String} errorType - The type of validation error that has occurred.
* @param {Element} el - The input element that is the source of the validation error.
* @returns {Promise} A promise that is resolved when the validation message has been produced.
*/
resolve = function (errorType, el) {
var defer = $q.defer(),
errMsg,
parameters = [],
parameter,
messageTypeOverride;
/**
* @ngdoc function
* @name defaultErrorMessageResolver#resolve
* @methodOf defaultErrorMessageResolver
*
* @description
* Resolves a validate error type into a user validation error message
*
* @param {String} errorType - The type of validation error that has occurred.
* @param {Element} el - The input element that is the source of the validation error.
* @returns {Promise} A promise that is resolved when the validation message has been produced.
*/
resolve = function (errorType, el) {
var defer = $q.defer(),
errMsg,
parameters = [],
parameter,
messageTypeOverride;
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
resolve(errorType, el).then(function (msg) {
defer.resolve(msg);
});
});
} else {
errMsg = angular.autoValidate.errorMessages[currentCulture][errorType];
messageTypeOverride = getMessageTypeOverride(errorType, el);
if (messageTypeOverride) {
errMsg = angular.autoValidate.errorMessages[currentCulture][messageTypeOverride];
}
if (cultureRetrievalPromise !== undefined) {
cultureRetrievalPromise.then(function () {
resolve(errorType, el).then(function (msg) {
defer.resolve(msg);
});
});
} else {
errMsg = angular.autoValidate.errorMessages[currentCulture][errorType];
messageTypeOverride = getMessageTypeOverride(errorType, el);
if (messageTypeOverride) {
errMsg = angular.autoValidate.errorMessages[currentCulture][messageTypeOverride];
}
if (errMsg === undefined) {
errMsg = angular.autoValidate.errorMessages[currentCulture].defaultMsg.format(errorType);
}
if (errMsg === undefined) {
errMsg = angular.autoValidate.errorMessages[currentCulture].defaultMsg.format(errorType);
}
if (el && el.attr) {
try {
parameter = el.attr('ng-' + errorType);
if (parameter === undefined) {
parameter = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
if (el && el.attr) {
try {
parameter = el.attr('ng-' + errorType);
if (parameter === undefined) {
parameter = el.attr('data-ng-' + errorType) || el.attr(errorType);
}
parameters.push(parameter || '');
parameters.push(parameter || '');
errMsg = errMsg.format(parameters);
} catch (e) {}
}
errMsg = errMsg.format(parameters);
} catch (e) {}
}
defer.resolve(errMsg);
}
defer.resolve(errMsg);
}
return defer.promise;
};
return defer.promise;
};
return {
setI18nFileRootPath: setI18nFileRootPath,
setCulture: setCulture,
getErrorMessages: getErrorMessages,
resolve: resolve
};
}
return {
setI18nFileRootPath: setI18nFileRootPath,
setCulture: setCulture,
getErrorMessages: getErrorMessages,
resolve: resolve
};
}
]);
}(String, angular));
DefaultErrorMessageResolverFn.$inject = [
'$q',
'$http'
];
angular.module('jcs-autoValidate').factory('defaultErrorMessageResolver', DefaultErrorMessageResolverFn);

@@ -1,90 +0,84 @@

(function (angular) {
'use strict';
function Foundation5ElementModifierFn() {
var reset = function (el, inputEl) {
angular.forEach(el.find('small'), function (smallEl) {
if (angular.element(smallEl).hasClass('error')) {
angular.element(smallEl).remove();
}
});
angular.module('jcs-autoValidate')
.factory('foundation5ElementModifier', [
inputEl.removeClass('error');
},
findParentColumn = function (el) {
var parent = el;
for (var i = 0; i <= 3; i += 1) {
if (parent !== undefined && parent.hasClass('columns')) {
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
function () {
var reset = function (el, inputEl) {
angular.forEach(el.find('small'), function (smallEl) {
if (angular.element(smallEl).hasClass('error')) {
angular.element(smallEl).remove();
}
});
return parent;
},
inputEl.removeClass('error');
},
findParentColumn = function (el) {
var parent = el;
for (var i = 0; i <= 3; i += 1) {
if (parent !== undefined && parent.hasClass('columns')) {
break;
} else if (parent !== undefined) {
parent = parent.parent();
}
}
/**
* @ngdoc function
* @name foundation5ElementModifier#makeValid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear valid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var parentColumn = findParentColumn(el);
reset(parentColumn && parentColumn.length > 0 ? parentColumn : el, el);
},
return parent;
},
/**
* @ngdoc function
* @name foundation5ElementModifier#makeInvalid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear invalid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var parentColumn = findParentColumn(el),
helpTextEl;
reset(parentColumn || el, el);
el.addClass('error');
if (parentColumn) {
helpTextEl = angular.element('<small class="error">' + errorMsg + '</small>');
parentColumn.append(helpTextEl);
}
},
/**
* @ngdoc function
* @name foundation5ElementModifier#makeValid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear valid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeValid = function (el) {
var parentColumn = findParentColumn(el);
reset(parentColumn && parentColumn.length > 0 ? parentColumn : el, el);
},
/**
* @ngdoc function
* @name foundation5ElementModifier#makeDefault
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply foundation 5 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
makeValid(el);
};
/**
* @ngdoc function
* @name foundation5ElementModifier#makeInvalid
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear invalid by apply Foundation 5 specific styles and child elements.
* See: http://foundation.zurb.com/docs/components/forms.html
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeInvalid = function (el, errorMsg) {
var parentColumn = findParentColumn(el),
helpTextEl;
reset(parentColumn || el, el);
el.addClass('error');
if (parentColumn) {
helpTextEl = angular.element('<small class="error">' + errorMsg + '</small>');
parentColumn.append(helpTextEl);
}
},
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
key: 'foundation5'
};
}
/**
* @ngdoc function
* @name foundation5ElementModifier#makeDefault
* @methodOf foundation5ElementModifier
*
* @description
* Makes an element appear in its default visual state by apply foundation 5 specific styles and child elements.
*
* @param {Element} el - The input control element that is the target of the validation.
*/
makeDefault = function (el) {
makeValid(el);
};
return {
makeValid: makeValid,
makeInvalid: makeInvalid,
makeDefault: makeDefault,
key: 'foundation5'
};
}
]);
}(angular));
angular.module('jcs-autoValidate').factory('foundation5ElementModifier', Foundation5ElementModifierFn);

@@ -1,209 +0,229 @@

(function (angular) {
'use strict';
function ElementUtilsFn() {
var isElementVisible = function (el) {
return el[0].offsetWidth > 0 && el[0].offsetHeight > 0;
};
angular.module('jcs-autoValidate')
.factory('jcs-elementUtils', [
function () {
var isElementVisible = function (el) {
return el[0].offsetWidth > 0 && el[0].offsetHeight > 0;
};
return {
isElementVisible: isElementVisible
};
}
return {
isElementVisible: isElementVisible
};
}
]);
function ValidationManagerFn(validator, elementUtils) {
var elementTypesToValidate = ['input', 'textarea', 'select', 'form'],
angular.module('jcs-autoValidate')
.factory('validationManager', [
'validator',
'jcs-elementUtils',
function (validator, elementUtils) {
var elementTypesToValidate = ['input', 'textarea', 'select', 'form'],
elementIsVisible = function (el) {
return elementUtils.isElementVisible(el);
},
elementIsVisible = function (el) {
return elementUtils.isElementVisible(el);
},
getFormOptions = function (el) {
var frmCtrl = angular.element(el).controller('form'),
options;
getFormOptions = function (el) {
var frmCtrl = angular.element(el).controller('form');
return frmCtrl !== undefined && frmCtrl !== null ? frmCtrl.autoValidateFormOptions : validator.defaultFormValidationOptions;
},
if (frmCtrl !== undefined && frmCtrl !== null) {
options = frmCtrl.autoValidateFormOptions;
} else {
options = validator.defaultFormValidationOptions;
}
/**
* Only validate if the element is present, it is visible
* it is either a valid user input control (input, select, textare, form) or
* it is a custom control register by the developer.
* @param el
* @param formOptions The validation options of the parent form
* @returns {boolean} true to indicate it should be validated
*/
shouldValidateElement = function (el, formOptions) {
var result = el &&
el.length > 0 &&
(elementIsVisible(el) || formOptions.validateNonVisibleControls) &&
(elementTypesToValidate.indexOf(el[0].nodeName.toLowerCase()) > -1 ||
el[0].hasAttribute('register-custom-form-control'));
return result;
},
return options;
},
/**
* @ngdoc validateElement
* @name validation#validateElement
* @param {object} modelCtrl holds the information about the element e.g. $invalid, $valid
* @param {options}
* - forceValidation if set to true forces the validation even if the element is pristine
* - disabled if set to true forces the validation is disabled and will return true
* - validateNonVisibleControls if set to true forces the validation of non visible element i.e. display:block
* @description
* Validate the form element and make invalid/valid element model status.
*
* As of v1.17.22:
* BREAKING CHANGE to validateElement on the validationManger. The third parameter is now the parent form's
* autoValidateFormOptions object on the form controller. This can be left blank and will be found by the
* validationManager.
*/
validateElement = function (modelCtrl, el, options) {
var isValid = true,
frmOptions = options || getFormOptions(el),
needsValidation = modelCtrl.$pristine === false || frmOptions.forceValidation,
errorType,
findErrorType = function ($errors) {
var keepGoing = true,
errorTypeToReturn;
angular.forEach($errors, function (status, errortype) {
if (keepGoing && status) {
keepGoing = false;
errorTypeToReturn = errortype;
}
});
/**
* Only validate if the element is present, it is visible
* it is either a valid user input control (input, select, textare, form) or
* it is a custom control register by the developer.
* @param el
* @param formOptions The validation options of the parent form
* @returns {boolean} true to indicate it should be validated
*/
shouldValidateElement = function (el, formOptions, formSubmitted) {
var elementExists = el && el.length > 0,
correctVisibilityToValidate,
correctTypeToValidate,
correctPhaseToValidate;
return errorTypeToReturn;
};
if (elementExists) {
correctVisibilityToValidate = elementIsVisible(el) || formOptions.validateNonVisibleControls;
correctTypeToValidate = elementTypesToValidate.indexOf(el[0].nodeName.toLowerCase()) > -1 ||
el[0].hasAttribute('register-custom-form-control');
correctPhaseToValidate = formOptions.validateOnFormSubmit === false ||
(formOptions.validateOnFormSubmit === true && formSubmitted === true);
}
if (frmOptions.disabled === false) {
if ((frmOptions.forceValidation || (shouldValidateElement(el, frmOptions) && modelCtrl && needsValidation))) {
isValid = !modelCtrl.$invalid;
return elementExists && correctVisibilityToValidate && correctTypeToValidate && correctPhaseToValidate;
if (frmOptions.removeExternalValidationErrorsOnSubmit && modelCtrl.removeAllExternalValidation) {
modelCtrl.removeAllExternalValidation();
}
},
if (isValid) {
validator.makeValid(el);
} else {
errorType = findErrorType(modelCtrl.$errors || modelCtrl.$error);
if (errorType === undefined) {
/**
* @ngdoc validateElement
* @name validation#validateElement
* @param {object} modelCtrl holds the information about the element e.g. $invalid, $valid
* @param {options}
* - forceValidation if set to true forces the validation even if the element is pristine
* - disabled if set to true forces the validation is disabled and will return true
* - validateNonVisibleControls if set to true forces the validation of non visible element i.e. display:block
* @description
* Validate the form element and make invalid/valid element model status.
*
* As of v1.17.22:
* BREAKING CHANGE to validateElement on the validationManger. The third parameter is now the parent form's
* autoValidateFormOptions object on the form controller. This can be left blank and will be found by the
* validationManager.
*/
validateElement = function (modelCtrl, el, options) {
var isValid = true,
frmOptions = options || getFormOptions(el),
needsValidation = modelCtrl.$pristine === false || frmOptions.forceValidation,
errorType,
findErrorType = function ($errors) {
var keepGoing = true,
errorTypeToReturn;
angular.forEach($errors, function (status, errortype) {
if (keepGoing && status) {
keepGoing = false;
errorTypeToReturn = errortype;
}
});
// we have a weird situation some users are encountering where a custom control
// is valid but the ngModel is report it isn't and thus no valid error type can be found
isValid = true;
} else {
validator.getErrorMessage(errorType, el).then(function (errorMsg) {
validator.makeInvalid(el, errorMsg);
});
}
}
}
}
return errorTypeToReturn;
};
return isValid;
},
if (frmOptions.disabled === false) {
if ((frmOptions.forceValidation ||
(shouldValidateElement(el, frmOptions, frmOptions.formController.$submitted) &&
modelCtrl &&
needsValidation))) {
isValid = !modelCtrl.$invalid;
resetElement = function (element) {
validator.makeDefault(element);
},
if (frmOptions.removeExternalValidationErrorsOnSubmit && modelCtrl.removeAllExternalValidation) {
modelCtrl.removeAllExternalValidation();
}
resetForm = function (frmElement) {
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (element) {
var controller,
ctrlElement = angular.element(element);
controller = ctrlElement.controller('ngModel');
if (isValid) {
validator.makeValid(el);
} else {
errorType = findErrorType(modelCtrl.$errors || modelCtrl.$error);
if (errorType === undefined) {
// we have a weird situation some users are encountering where a custom control
// is valid but the ngModel is report it isn't and thus no valid error type can be found
isValid = true;
} else {
validator.getErrorMessage(errorType, el).then(function (errorMsg) {
validator.makeInvalid(el, errorMsg);
});
}
}
}
}
if (controller !== undefined) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
resetForm(ctrlElement);
} else {
controller.$setPristine();
}
}
});
},
return isValid;
},
validateForm = function (frmElement) {
var frmValid = true,
frmCtrl = frmElement ? angular.element(frmElement).controller('form') : undefined,
processElement = function (ctrlElement, force, formOptions) {
var controller, isValid, ctrlFormOptions;
resetElement = function (element) {
validator.makeDefault(element);
},
ctrlElement = angular.element(ctrlElement);
controller = ctrlElement.controller('ngModel');
resetForm = function (frmElement) {
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (element) {
var controller,
ctrlElement = angular.element(element);
controller = ctrlElement.controller('ngModel');
if (controller !== undefined && (force || shouldValidateElement(ctrlElement, formOptions))) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
validateForm(ctrlElement);
} else {
// we need to get the options for the element rather than use the passed in as the
// element could be an ng-form and have different options to the parent form.
ctrlFormOptions = getFormOptions(ctrlElement);
ctrlFormOptions.forceValidation = force;
isValid = validateElement(controller, ctrlElement, ctrlFormOptions);
frmValid = frmValid && isValid;
}
}
},
clonedOptions;
if (controller !== undefined) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
resetForm(ctrlElement);
} else {
controller.$setPristine();
}
}
});
},
if (frmElement === undefined || (frmCtrl !== undefined && frmCtrl.autoValidateFormOptions.disabled)) {
return frmElement !== undefined;
}
validateForm = function (frmElement) {
var frmValid = true,
frmCtrl = frmElement ? angular.element(frmElement).controller('form') : undefined,
processElement = function (ctrlElement, force, formOptions) {
var controller, isValid, ctrlFormOptions, originalForceValue;
//force the validation of controls
clonedOptions = angular.copy(frmCtrl.autoValidateFormOptions);
clonedOptions.forceValidation = true;
ctrlElement = angular.element(ctrlElement);
controller = ctrlElement.controller('ngModel');
// IE8 holds the child controls collection in the all property
// Firefox in the elements and chrome as a child iterator
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (ctrlElement) {
processElement(ctrlElement, true, clonedOptions);
});
if (controller !== undefined && (force || shouldValidateElement(ctrlElement, formOptions, frmCtrl.$submitted))) {
if (ctrlElement[0].nodeName.toLowerCase() === 'form') {
// we probably have a sub form
validateForm(ctrlElement);
} else {
// we need to get the options for the element rather than use the passed in as the
// element could be an ng-form and have different options to the parent form.
ctrlFormOptions = getFormOptions(ctrlElement);
originalForceValue = ctrlFormOptions.forceValidation;
ctrlFormOptions.forceValidation = force;
try {
isValid = validateElement(controller, ctrlElement, ctrlFormOptions);
frmValid = frmValid && isValid;
} finally {
ctrlFormOptions.forceValidation = originalForceValue;
}
}
}
},
clonedOptions;
// If you have a custom form control that should be validated i.e.
// <my-custom-element>...</my-custom-element> it will not be part of the forms
// HTMLFormControlsCollection and thus won't be included in the above element iteration although
// it will be on the Angular FormController (if it has a name attribute). So adding the directive
// register-custom-form-control="" to the control root and autoValidate will include it in this
// iteration.
if (frmElement[0].customHTMLFormControlsCollection) {
angular.forEach(frmElement[0].customHTMLFormControlsCollection, function (ctrlElement) {
// need to force the validation as the element might not be a known form input type
// so the normal validation process will ignore it.
processElement(ctrlElement, true, clonedOptions);
});
}
if (frmElement === undefined || (frmCtrl !== undefined && frmCtrl.autoValidateFormOptions.disabled)) {
return frmElement !== undefined;
}
return frmValid;
},
//force the validation of controls
clonedOptions = angular.copy(frmCtrl.autoValidateFormOptions);
clonedOptions.forceValidation = true;
setElementValidationError = function (element, errorMsgKey, errorMsg) {
if (errorMsgKey) {
validator.getErrorMessage(errorMsgKey, element).then(function (msg) {
validator.makeInvalid(element, msg);
});
} else {
validator.makeInvalid(element, errorMsg);
}
};
// IE8 holds the child controls collection in the all property
// Firefox in the elements and chrome as a child iterator
angular.forEach((frmElement[0].all || frmElement[0].elements) || frmElement[0], function (ctrlElement) {
processElement(ctrlElement, true, clonedOptions);
});
return {
setElementValidationError: setElementValidationError,
validateElement: validateElement,
validateForm: validateForm,
resetElement: resetElement,
resetForm: resetForm
};
}
]);
}(angular));
// If you have a custom form control that should be validated i.e.
// <my-custom-element>...</my-custom-element> it will not be part of the forms
// HTMLFormControlsCollection and thus won't be included in the above element iteration although
// it will be on the Angular FormController (if it has a name attribute). So adding the directive
// register-custom-form-control="" to the control root and autoValidate will include it in this
// iteration.
if (frmElement[0].customHTMLFormControlsCollection) {
angular.forEach(frmElement[0].customHTMLFormControlsCollection, function (ctrlElement) {
// need to force the validation as the element might not be a known form input type
// so the normal validation process will ignore it.
processElement(ctrlElement, true, clonedOptions);
});
}
return frmValid;
},
setElementValidationError = function (element, errorMsgKey, errorMsg) {
if (errorMsgKey) {
validator.getErrorMessage(errorMsgKey, element).then(function (msg) {
validator.makeInvalid(element, msg);
});
} else {
validator.makeInvalid(element, errorMsg);
}
};
return {
setElementValidationError: setElementValidationError,
validateElement: validateElement,
validateForm: validateForm,
resetElement: resetElement,
resetForm: resetForm
};
}
ValidationManagerFn.$inject = [
'validator',
'jcs-elementUtils'
];
angular.module('jcs-autoValidate').factory('jcs-elementUtils', ElementUtilsFn);
angular.module('jcs-autoValidate').factory('validationManager', ValidationManagerFn);
(function (angular, sinon) {
'use strict';
'use strict';
/**
* Since Angular 1.3 SetValidity on the ngModelController is called 2-3 times
* because of the inclusion of async validators hence now the tests only assert the
* methods were called
*/
/**
* Since Angular 1.3 SetValidity on the ngModelController is called 2-3 times
* because of the inclusion of async validators hence now the tests only assert the
* methods were called
*/
describe('ngModelDirective decorator', function () {
var sandbox, $rootScope, $q, validationManager, $timeout,
element, $compile, debounce, debounceStub,
compileElement = function (html, includesForm) {
html = includesForm ? html : '<form ng-submit="">' + html + '</form>';
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
element = includesForm ? element : angular.element(element[0].children[0]);
},
setNgOptionsNotSupported = function () {
sandbox.stub(angular, 'version', {
major: angular.version.major,
minor: angular.version.minor
});
};
describe('ngModelDirective decorator', function () {
var sandbox, $rootScope, $q, validationManager, $timeout,
element, $compile, debounce, debounceStub,
compileElement = function (html, includesForm) {
html = includesForm ? html : '<form ng-submit="">' + html + '</form>';
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
element = includesForm ? element : angular.element(element[0].children[0]);
},
setNgOptionsNotSupported = function () {
sandbox.stub(angular, 'version', {
major: angular.version.major,
minor: angular.version.minor
});
};
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('ngModelDirective', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
$timeout = $injector.get('$timeout');
debounce = $injector.get('jcs-debounce');
validationManager = $injector.get('validationManager');
describe('ngModelDirective', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
$timeout = $injector.get('$timeout');
debounce = $injector.get('jcs-debounce');
validationManager = $injector.get('validationManager');
debounceStub = sandbox.stub();
debounceStub = sandbox.stub();
sandbox.stub(validationManager, 'validateElement');
sandbox.stub(debounce, 'debounce').returns(debounceStub);
}));
sandbox.stub(validationManager, 'validateElement');
sandbox.stub(debounce, 'debounce').returns(debounceStub);
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
compileElement('<input ng-model="model" />');
expect(element).to.exist;
var ctrl = element.controller('ngModel');
expect(ctrl.autoValidated).to.equal(true);
});
it('should be defined', function () {
compileElement('<input ng-model="model" />');
expect(element).to.exist;
var ctrl = element.controller('ngModel');
expect(ctrl.autoValidated).to.equal(true);
});
it('should not be autoValidated it the formnovalidate attribute is present on the element', function () {
compileElement('<input ng-model="model" formnovalidate />');
var ctrl = element.controller('ngModel');
expect(ctrl.autoValidated).to.equal(undefined);
});
it('should not be autoValidated it the formnovalidate attribute is present on the element', function () {
compileElement('<input ng-model="model" formnovalidate />');
var ctrl = element.controller('ngModel');
expect(ctrl.autoValidated).to.equal(undefined);
});
it('should not be autoValidated it the disable-dynamic-validation attribute is on the parent form', function () {
compileElement('<form disable-dynamic-validation="true"><input ng-model="model" formnovalidate /></form>', true);
var ctrl = angular.element(element.children()[0]).controller('ngModel');
expect(ctrl.autoValidated).to.equal(undefined);
});
it('should not be autoValidated it the disable-dynamic-validation attribute is on the parent form', function () {
compileElement('<form disable-dynamic-validation="true"><input ng-model="model" formnovalidate /></form>', true);
var ctrl = angular.element(element.children()[0]).controller('ngModel');
expect(ctrl.autoValidated).to.equal(undefined);
});
it('should called debounced method when $setValidity invoked if angular version in 1.3 and thus supports ngModelOptions', function () {
// As of the changes needed for angular 1.3 RC release this test will no longer pass in angular 1.2x
// setNgOptionsSupported();
// compileElement('<input ng-model="model" />');
// var ctrl = element.controller('ngModel');
// ctrl.$setValidity('error', true);
//
// expect(debounceStub.called).to.equal(true);
});
it('should called debounced method when $setValidity invoked if angular version in 1.3 and thus supports ngModelOptions', function () {
// As of the changes needed for angular 1.3 RC release this test will no longer pass in angular 1.2x
// setNgOptionsSupported();
// compileElement('<input ng-model="model" />');
// var ctrl = element.controller('ngModel');
// ctrl.$setValidity('error', true);
//
// expect(debounceStub.called).to.equal(true);
});
it('should called debounced method when $setValidity invoked if ngModelOptions is not defined', function () {
compileElement('<input ng-model="model" />');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
it('should called debounced method when $setValidity invoked if ngModelOptions is not defined', function () {
compileElement('<input ng-model="model" />');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
expect(debounceStub.called).to.equal(true);
});
expect(debounceStub.called).to.equal(true);
});
it('should called debounced method when $setValidity invoked if ngModelOptions is defined but updateOn is not defined', function () {
compileElement('<input ng-model="model" data-ng-model-options="{}"/>');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
it('should called debounced method when $setValidity invoked if ngModelOptions is defined but updateOn is not defined', function () {
compileElement('<input ng-model="model" data-ng-model-options="{}"/>');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
expect(debounceStub.called).to.equal(true);
});
expect(debounceStub.called).to.equal(true);
});
it('should called debounced method when $setValidity invoked if ngModelOptions is defined but updateOn is not empty', function () {
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'\'}"/>');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
it('should called debounced method when $setValidity invoked if ngModelOptions is defined but updateOn is not empty', function () {
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'\'}"/>');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
expect(debounceStub.called).to.equal(true);
});
expect(debounceStub.called).to.equal(true);
});
it('invoking the debounced method should call validateElement on the validationManager', function () {
compileElement('<input ng-model="model" />');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
it('invoking the debounced method should call validateElement on the validationManager', function () {
compileElement('<input ng-model="model" />');
var ctrl = element.controller('ngModel');
ctrl.$setValidity('error', false);
expect(debounce.debounce.args[0][0]).to.not.equal(undefined);
expect(debounce.debounce.args[0][1]).to.equal(100);
debounce.debounce.args[0][0]();
expect(validationManager.validateElement.calledOnce).to.equal(true);
});
expect(debounce.debounce.args[0][0]).to.not.equal(undefined);
expect(debounce.debounce.args[0][1]).to.equal(100);
debounce.debounce.args[0][0]();
expect(validationManager.validateElement.calledOnce).to.equal(true);
});
it('should call validate element when element blur event is raised', function () {
if (angular.version.major === 1 && angular.version.minor < 3) {
setNgOptionsNotSupported();
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
element.triggerHandler('blur');
it('should call validate element when element blur event is raised', function () {
if (angular.version.major === 1 && angular.version.minor < 3) {
setNgOptionsNotSupported();
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
element.triggerHandler('blur');
expect(debounce.debounce.args[0][0]).to.not.equal(undefined);
expect(debounce.debounce.args[0][1]).to.equal(100);
debounce.debounce.args[0][0]();
expect(validationManager.validateElement.calledOnce).to.equal(true);
}
});
expect(debounce.debounce.args[0][0]).to.not.equal(undefined);
expect(debounce.debounce.args[0][1]).to.equal(100);
debounce.debounce.args[0][0]();
expect(validationManager.validateElement.calledOnce).to.equal(true);
}
});
it('should remove element event listener when scope is destroyed', function () {
if (angular.version.major === 1 && angular.version.minor < 3) {
setNgOptionsNotSupported();
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
it('should remove element event listener when scope is destroyed', function () {
if (angular.version.major === 1 && angular.version.minor < 3) {
setNgOptionsNotSupported();
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
$rootScope.$destroy();
$rootScope.$destroy();
// How do I mock out the off method of the element?
//expect(element.off.calledOnce).to.equal(true);
}
});
// How do I mock out the off method of the element?
//expect(element.off.calledOnce).to.equal(true);
}
});
describe('$setPristine', function () {
it('should override the default $setPristine function and when invoked should call the default method and the validationManager resetElement method', function () {
var ngModelController;
describe('$setPristine', function () {
it('should override the default $setPristine function and when invoked should call the default method and the validationManager resetElement method', function () {
var ngModelController;
sandbox.stub(validationManager, 'resetElement');
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
sandbox.stub(validationManager, 'resetElement');
compileElement('<input ng-model="model" data-ng-model-options="{updateOn: \'blur\'}" />');
ngModelController = element.controller('ngModel');
ngModelController.$setPristine();
ngModelController = element.controller('ngModel');
ngModelController.$setPristine();
expect(validationManager.resetElement.calledOnce).to.equal(true);
});
});
expect(validationManager.resetElement.calledOnce).to.equal(true);
});
});
describe('setExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
describe('setExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
expect(ngModelController.setExternalValidation).to.not.equal(undefined);
});
expect(ngModelController.setExternalValidation).to.not.equal(undefined);
});
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
});
});
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
});
});
describe('removeExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
describe('removeExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
expect(ngModelController.removeExternalValidation).to.not.equal(undefined);
});
expect(ngModelController.removeExternalValidation).to.not.equal(undefined);
});
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
ngModelController.removeExternalValidation(errorKey, true);
ngModelController.removeExternalValidation(errorKey, true);
expect(ngModelController.$error[errorKey]).to.equal(true);
expect(ngModelController.externalErrors[errorKey]).to.equal(undefined);
});
});
expect(ngModelController.$error[errorKey]).to.equal(undefined);
expect(ngModelController.externalErrors[errorKey]).to.equal(undefined);
});
});
describe('removeAllExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
describe('removeAllExternalValidation', function () {
it('should be defined on the ngModelCtrl', function () {
var ngModelController;
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
expect(ngModelController.removeAllExternalValidation).to.not.equal(undefined);
});
expect(ngModelController.removeAllExternalValidation).to.not.equal(undefined);
});
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
it('should set a key in the errors collection', function () {
var ngModelController,
errorKey = 'errorKey';
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
compileElement('<input ng-model="model" />');
ngModelController = element.controller('ngModel');
ngModelController.setExternalValidation(errorKey, 'msgKey', true);
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
expect(ngModelController.$error[errorKey]).to.equal(false);
expect(ngModelController.externalErrors[errorKey]).to.equal(false);
ngModelController.removeAllExternalValidation();
ngModelController.removeAllExternalValidation();
expect(ngModelController.$error[errorKey]).to.equal(true);
expect(ngModelController.externalErrors[errorKey]).to.equal(undefined);
});
});
expect(ngModelController.$error[errorKey]).to.equal(undefined);
expect(ngModelController.externalErrors[errorKey]).to.equal(undefined);
});
});
});
});
}(angular, sinon));
(function (window, angular, sinon) {
'use strict';
'use strict';
describe('ngModelDirective decorator', function () {
var sandbox, $rootScope, $q, validationManager,
element, $compile, submitFnCalled = false,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
};
describe('ngModelDirective decorator', function () {
var sandbox, $rootScope, $q, validationManager,
element, $compile, submitFnCalled = false,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
};
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('ngSubmitDirective', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
validationManager = $injector.get('validationManager');
describe('ngSubmitDirective', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
validationManager = $injector.get('validationManager');
$rootScope.submitFn = function () {
submitFnCalled = true;
};
}));
$rootScope.submitFn = function () {
submitFnCalled = true;
};
}));
afterEach(function () {
submitFnCalled = false;
sandbox.restore();
});
afterEach(function () {
submitFnCalled = false;
sandbox.restore();
});
it('should be defined', function () {
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
});
it('should be defined', function () {
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
});
it('should call validate form on the validationManager when the form submit event is raised', function () {
sandbox.stub(validationManager, 'validateForm').returns(true);
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
it('should call validate form on the validationManager when the form submit event is raised', function () {
sandbox.stub(validationManager, 'validateForm').returns(true);
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
window.browserTrigger(element, 'submit');
window.browserTrigger(element, 'submit');
expect(validationManager.validateForm.calledOnce).to.equal(true);
});
expect(validationManager.validateForm.calledOnce).to.equal(true);
});
it('should call the submit function on ngSubmit when the form is submitted and is valid', function () {
sandbox.stub(validationManager, 'validateForm').returns(true);
compileElement('<form name="frmOne2" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
it('should call the submit function on ngSubmit when the form is submitted and is valid', function () {
sandbox.stub(validationManager, 'validateForm').returns(true);
compileElement('<form name="frmOne2" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
window.browserTrigger(element, 'submit');
$rootScope.$apply();
window.browserTrigger(element, 'submit');
$rootScope.$apply();
expect(submitFnCalled).to.equal(true);
});
expect(submitFnCalled).to.equal(true);
});
it('should call the submit function on ngSubmit when the form is submitted, is invalid but the ngSubmitForce attribute is true', function () {
sandbox.stub(validationManager, 'validateForm').returns(false);
compileElement('<form name="frmOne2" ng-submit="submitFn()" ng-submit-force="true"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
it('should call the submit function on ngSubmit when the form is submitted, is invalid but the ngSubmitForce attribute is true', function () {
sandbox.stub(validationManager, 'validateForm').returns(false);
compileElement('<form name="frmOne2" ng-submit="submitFn()" ng-submit-force="true"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
window.browserTrigger(element, 'submit');
$rootScope.$apply();
window.browserTrigger(element, 'submit');
$rootScope.$apply();
expect(submitFnCalled).to.equal(true);
});
expect(submitFnCalled).to.equal(true);
});
it('should not call the submit function on ngSubmit when the form is submitted and is valid', function () {
sandbox.stub(validationManager, 'validateForm').returns(false);
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
it('should not call the submit function on ngSubmit when the form is submitted and is valid', function () {
sandbox.stub(validationManager, 'validateForm').returns(false);
compileElement('<form name="frmOne" ng-submit="submitFn()"><input type="text" ng-model="name"/></form>');
expect(element).to.exist;
window.browserTrigger(element, 'submit');
$rootScope.$apply();
window.browserTrigger(element, 'submit');
$rootScope.$apply();
expect(submitFnCalled).to.equal(false);
});
});
expect(submitFnCalled).to.equal(false);
});
});
});
}(window, angular, sinon));
(function (document, angular, sinon) {
'use strict';
var sandbox, $rootScope,
element, $compile, validator,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
};
'use strict';
var sandbox, $rootScope,
element, $compile, validator,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
};
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('autoValidateFormOptions', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
validator = $injector.get('validator');
}));
describe('autoValidateFormOptions', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
validator = $injector.get('validator');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
compileElement('<form name="test""></form>');
it('should be defined', function () {
compileElement('<form name="test""></form>');
expect(element.controller('form').autoValidateFormOptions).to.exist;
expect(element.controller('form').autoValidateFormOptions).to.exist;
});
describe('disableDynamicValidation', function () {
it('should set the default value if config properties are not on form', function () {
sandbox.stub(validator, 'defaultFormValidationOptions', {
validateNonVisibleControls: 2,
removeExternalValidationErrorsOnSubmit: 3,
validateOnFormSubmit: 4
});
describe('disableDynamicValidation', function () {
it('should set the property "disableDynamicValidation" on the form controller to true', function () {
compileElement('<form name="test" disable-dynamic-validation="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.disabled).to.equal(true);
});
compileElement('<form name="test"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.validateNonVisibleControls).to.equal(2);
expect(controller.autoValidateFormOptions.removeExternalValidationErrorsOnSubmit).to.equal(3);
expect(controller.autoValidateFormOptions.validateOnFormSubmit).to.equal(4);
});
it('should set the property "disableDynamicValidation" on the form controller to true', function () {
compileElement('<form name="test" data-disable-dynamic-validation="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.disabled).to.equal(true);
});
it('should set the property "disableDynamicValidation" on the form controller to true', function () {
compileElement('<form name="test" disable-dynamic-validation="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.disabled).to.equal(true);
});
it('should set the property "disableDynamicValidation" on the form controller to true if it is used as a boolean attribute', function () {
compileElement('<form name="test" disable-dynamic-validation></form>');
it('should set the property "disableDynamicValidation" on the form controller to true', function () {
compileElement('<form name="test" data-disable-dynamic-validation="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.disabled).to.equal(true);
});
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(true);
});
it('should set the property "disableDynamicValidation" on the form controller to true if it is used as a boolean attribute', function () {
compileElement('<form name="test" disable-dynamic-validation></form>');
it('should set the property "disableDynamicValidation" on the form controller to false', function () {
compileElement('<form name="test" disable-dynamic-validation="false"></form>');
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(true);
});
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
it('should set the property "disableDynamicValidation" on the form controller to false', function () {
compileElement('<form name="test" disable-dynamic-validation="false"></form>');
it('should set the property "disableDynamicValidation" on the form controller to false', function () {
sandbox.stub(validator, 'isEnabled').returns(false);
compileElement('<form name="test" disable-dynamic-validation="false"></form>');
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
it('should set the property "disableDynamicValidation" on the form controller to false when validator is disabled', function () {
sandbox.stub(validator, 'isEnabled').returns(false);
compileElement('<form name="test" disable-dynamic-validation="false"></form>');
it('should set the property "disableDynamicValidation" on the form controller to false if the attribute is not there', function () {
compileElement('<form name="test"></form>');
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
});
it('should set the property "disableDynamicValidation" on the form controller to false if the attribute is not there', function () {
compileElement('<form name="test"></form>');
describe('validateNonVisibleControls', function () {
it('should set the property "validateNonVisibleControls" on the form controller to true', function () {
compileElement('<form name="test" validate-non-visible-controls="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
});
it('should set the property "validateNonVisibleControls" on the form controller to true', function () {
compileElement('<form name="test" validate-non-visible-controls="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
it('should set the property "disableDynamicValidation" on the form controller to true if the library is disabled', function () {
validator.enable(false);
compileElement('<form name="test"></form>');
it('should set the property "validateNonVisibleControls" on the form controller to true if it is used as a boolean attribute', function () {
compileElement('<form name="test" validate-non-visible-controls></form>');
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(true);
validator.enable(true);
});
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
it('should set the property "disableDynamicValidation" on the form controller to false if the library is disabled but the form is enabled', function () {
validator.enable(false);
compileElement('<form name="test" disable-dynamic-validation="false"></form>');
it('should set the property "validateNonVisibleControls" on the form controller to false', function () {
compileElement('<form name="test" validate-non-visible-controls="false"></form>');
expect(element.controller('form').autoValidateFormOptions.disabled).to.equal(false);
validator.enable(true);
});
});
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(false);
});
describe('validateNonVisibleControls', function () {
it('should set the property "validateNonVisibleControls" on the form controller to true', function () {
compileElement('<form name="test" validate-non-visible-controls="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
it('should set the property "validateNonVisibleControls" on the form controller to false if the attribute is not there', function () {
compileElement('<form name="test"></form>');
it('should set the property "validateNonVisibleControls" on the form controller to true', function () {
compileElement('<form name="test" validate-non-visible-controls="true"></form>');
var controller = element.controller('form');
expect(controller.autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(false);
});
});
it('should set the property "validateNonVisibleControls" on the form controller to true if it is used as a boolean attribute', function () {
compileElement('<form name="test" validate-non-visible-controls></form>');
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(true);
});
it('should set the property "validateNonVisibleControls" on the form controller to false', function () {
compileElement('<form name="test" validate-non-visible-controls="false"></form>');
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(false);
});
it('should set the property "validateNonVisibleControls" on the form controller to false if the attribute is not there', function () {
compileElement('<form name="test"></form>');
expect(element.controller('form').autoValidateFormOptions.validateNonVisibleControls).to.equal(false);
});
});
});
}(document, angular, sinon));
(function (document, angular, sinon) {
'use strict';
var sandbox, $rootScope, $timeout,
element, $compile, validationManager,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
angular.element(document.body).append(element);
$rootScope.$digest();
};
'use strict';
var sandbox, $rootScope, $timeout,
element, $compile, validationManager,
compileElement = function (html) {
element = angular.element(html);
$compile(element)($rootScope);
angular.element(document.body).append(element);
$rootScope.$digest();
};
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('formReset', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$timeout = $injector.get('$timeout');
$compile = $injector.get('$compile');
validationManager = $injector.get('validationManager');
}));
describe('formReset', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$timeout = $injector.get('$timeout');
$compile = $injector.get('$compile');
validationManager = $injector.get('validationManager');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
compileElement('<form mame="test"></form>');
it('should be defined', function () {
compileElement('<form mame="test"></form>');
expect(element).to.exist;
});
expect(element).to.exist;
});
it('should add an event listener to the forms reset event which calls the resetForm on the validationManager', function () {
sandbox.stub(validationManager, 'resetForm');
compileElement('<form mame="test"></form>');
it('should add an event listener to the forms reset event which calls the resetForm on the validationManager', function () {
sandbox.stub(validationManager, 'resetForm');
compileElement('<form mame="test"></form>');
element.triggerHandler('reset');
element.triggerHandler('reset');
expect(validationManager.resetForm.calledOnce).to.equal(true);
});
expect(validationManager.resetForm.calledOnce).to.equal(true);
});
it('should add an event listener to the scope $destroy event', function () {
sandbox.stub($rootScope, '$on');
compileElement('<form mame="test"></form>');
it('should add an event listener to the scope $destroy event', function () {
sandbox.stub($rootScope, '$on');
compileElement('<form mame="test"></form>');
expect($rootScope.$on.calledOnce).to.equal(true);
expect($rootScope.$on.getCall(0).args[0]).to.equal('$destroy');
});
expect($rootScope.$on.calledOnce).to.equal(true);
expect($rootScope.$on.getCall(0).args[0]).to.equal('$destroy');
});
});
}(document, angular, sinon));

@@ -76,3 +76,14 @@ var shared = function (config) {

'src/jcs-auto-validate.js',
'src/**/*.js',
'src/providers/validator.js',
'src/services/bootstrap3ElementModifier.js',
'src/services/debounce.js',
'src/services/defaultErrorMessageResolver.js',
'src/services/foundation5ElementModifier.js',
'src/services/validationManager.js',
'src/directives/autoValidateFormOptions.js',
'src/directives/formReset.js',
'src/directives/registerCustomFormControl.js',
'src/config/ngSubmitDecorator.js',
'src/config/ngModelDecorator.js',
'src/jcs-auto-validate-run.js',

@@ -79,0 +90,0 @@ 'src/jcs-auto-validate-run.js'

(function (angular, sinon) {
'use strict';
describe('jcs-autoValidator validator', function () {
var sandbox, $rootScope, $q, validator;
'use strict';
describe('jcs-autoValidator validator', function () {
var sandbox, $rootScope, $q, validator;
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('validator', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$q = $injector.get('$q');
validator = $injector.get('validator');
}));
describe('validator', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$q = $injector.get('$q');
validator = $injector.get('validator');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
expect(validator).to.exist;
});
it('should be defined', function () {
expect(validator).to.exist;
});
describe('setDefaultElementModifier', function () {
it('should throw an error when a default modifier is set which does not exist', function () {
expect(function () {
validator.setDefaultElementModifier('missing_key');
}).to.throws(Error, 'Element modifier not registered: missing_key');
});
describe('setDefaultElementModifier', function () {
it('should throw an error when a default modifier is set which does not exist', function () {
expect(function () {
validator.setDefaultElementModifier('missing_key');
}).to.throws(Error, 'Element modifier not registered: missing_key');
});
it('should set default dom modifier when modifier is present', function () {
var key = 'key';
validator.registerDomModifier(key, {});
expect(function () {
validator.setDefaultElementModifier(key);
}).to.not.throws(Error);
expect(validator.defaultElementModifier).to.equal(key);
});
});
it('should set default dom modifier when modifier is present', function () {
var key = 'key';
validator.registerDomModifier(key, {});
expect(function () {
validator.setDefaultElementModifier(key);
}).to.not.throws(Error);
expect(validator.defaultElementModifier).to.equal(key);
});
});
describe('getErrorMessage', function () {
it('should throw an error an error message resolver has not been set', function () {
validator.setErrorMessageResolver(undefined);
expect(function () {
validator.getErrorMessage('error_key');
}).to.throws(Error, 'Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
});
describe('getErrorMessage', function () {
it('should throw an error an error message resolver has not been set', function () {
validator.setErrorMessageResolver(undefined);
expect(function () {
validator.getErrorMessage('error_key');
}).to.throws(Error, 'Please set an error message resolver via the setErrorMessageResolver function before attempting to resolve an error message.');
});
it('should call get error message on the set error message resolver', function (done) {
var errorMessage = 'error message',
defer = $q.defer(),
invocationCount = 0,
resolverFunc = function () {
invocationCount += 1;
return defer.promise;
};
it('should call get error message on the set error message resolver', function (done) {
var errorMessage = 'error message',
defer = $q.defer(),
invocationCount = 0,
resolverFunc = function () {
invocationCount += 1;
return defer.promise;
};
validator.setErrorMessageResolver(resolverFunc);
defer.resolve(errorMessage);
validator.setErrorMessageResolver(resolverFunc);
defer.resolve(errorMessage);
validator.getErrorMessage('error_key').then(function (msg) {
expect(invocationCount).to.equal(1);
expect(msg).to.equal(errorMessage);
done();
});
validator.getErrorMessage('error_key').then(function (msg) {
expect(invocationCount).to.equal(1);
expect(msg).to.equal(errorMessage);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should not call get error message on the set error message resolver it validation message is disabled', function (done) {
var errorMessage = '',
defer = $q.defer(),
invocationCount = 0,
resolverFunc = function () {
invocationCount += 1;
return defer.promise;
},
el = angular.element('<input type="text" required="" disable-validation-message=""/>');
it('should not call get error message on the set error message resolver it validation message is disabled', function (done) {
var errorMessage = '',
defer = $q.defer(),
invocationCount = 0,
resolverFunc = function () {
invocationCount += 1;
return defer.promise;
},
el = angular.element('<input type="text" required="" disable-validation-message=""/>');
validator.setErrorMessageResolver(resolverFunc);
defer.resolve(errorMessage);
validator.setErrorMessageResolver(resolverFunc);
defer.resolve(errorMessage);
validator.getErrorMessage('error_key', el).then(function (msg) {
expect(invocationCount).to.equal(0);
expect(msg).to.equal(errorMessage);
done();
});
validator.getErrorMessage('error_key', el).then(function (msg) {
expect(invocationCount).to.equal(0);
expect(msg).to.equal(errorMessage);
done();
});
$rootScope.$apply();
});
});
$rootScope.$apply();
});
});
describe('getDomModifier', function () {
var bs3 = 'bs3',
custom = 'custom',
custom1 = 'custom1';
describe('getDomModifier', function () {
var bs3 = 'bs3',
custom = 'custom',
custom1 = 'custom1';
beforeEach(inject(function ($injector) {
validator.registerDomModifier(bs3, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: bs3
});
validator.registerDomModifier(custom, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: custom
});
validator.registerDomModifier(custom1, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: custom1
});
validator.setDefaultElementModifier(bs3);
}));
beforeEach(inject(function ($injector) {
validator.registerDomModifier(bs3, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: bs3
});
validator.registerDomModifier(custom, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: custom
});
validator.registerDomModifier(custom1, {
makeValid: angular.noop,
makeInvalid: angular.noop,
name: custom1
});
validator.setDefaultElementModifier(bs3);
}));
it('should return the default dom modifier if the element has not specify a variant', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" />'));
it('should return the default dom modifier if the element has not specify a variant', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" />'));
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
it('should return the custom dom modifier as defined on the element via the attribute data-element-modifier', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" data-element-modifier="custom" />'));
it('should return the custom dom modifier as defined on the element via the attribute data-element-modifier', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" data-element-modifier="custom" />'));
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(custom);
});
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(custom);
});
it('should return the default dom modifier if the defined modifier key on the element attribute data-element-modifier is empty', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" data-element-modifier="" />'));
it('should return the default dom modifier if the defined modifier key on the element attribute data-element-modifier is empty', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" data-element-modifier="" />'));
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
it('should return the default dom modifier if the defined modifer key on the element attribute element-modifier is empty', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" element-modifier="" />'));
it('should return the default dom modifier if the defined modifer key on the element attribute element-modifier is empty', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" element-modifier="" />'));
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(bs3);
});
it('should return the custom dom modifier as defined on the element via the attribute element-modifier', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" element-modifier="custom1" />'));
it('should return the custom dom modifier as defined on the element via the attribute element-modifier', function () {
var modifier = validator.getDomModifier(angular.element('<input type="text" element-modifier="custom1" />'));
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(custom1);
});
});
expect(modifier).to.be.defined;
expect(modifier.name).to.be.equal(custom1);
});
});
describe('setDefaultDomModifier', function () {
it('should throw error as no default modifier has been set', function () {
var wrappingFunc = function () {
validator.makeInvalid(angular.element('<input type="text"/>'));
};
describe('setDefaultDomModifier', function () {
it('should throw error as no default modifier has been set', function () {
var wrappingFunc = function () {
validator.makeInvalid(angular.element('<input type="text"/>'));
};
validator.defaultElementModifier = undefined;
expect(wrappingFunc).to.throws(Error);
});
});
validator.defaultElementModifier = undefined;
expect(wrappingFunc).to.throws(Error);
});
});
describe('makeValid', function () {
var bs3 = 'bs3',
makeValidInvocationCount = 0,
domModifier = {
makeValid: function () {
makeValidInvocationCount += 1;
},
makeInvalid: angular.noop,
name: bs3
};
describe('makeValid', function () {
var bs3 = 'bs3',
makeValidInvocationCount = 0,
domModifier = {
makeValid: function () {
makeValidInvocationCount += 1;
},
makeInvalid: angular.noop,
name: bs3
};
beforeEach(inject(function ($injector) {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
}));
beforeEach(inject(function ($injector) {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
}));
afterEach(function () {
makeValidInvocationCount = 0;
});
afterEach(function () {
makeValidInvocationCount = 0;
});
it('should call makeValid on the dom modifier once', function () {
validator.makeValid(angular.element('<input type="text"/>'));
expect(makeValidInvocationCount).to.equal(1);
});
it('should call makeValid on the dom modifier once', function () {
validator.makeValid(angular.element('<input type="text"/>'));
expect(makeValidInvocationCount).to.equal(1);
});
it('should not call makeValid on the dom modifier if enableValidElementStyling is false', function () {
validator.setValidElementStyling(false);
validator.makeValid(angular.element('<input type="text"/>'));
expect(makeValidInvocationCount).to.equal(0);
});
it('should not call makeValid on the dom modifier if enableValidElementStyling is false', function () {
validator.setValidElementStyling(false);
validator.makeValid(angular.element('<input type="text"/>'));
expect(makeValidInvocationCount).to.equal(0);
});
it('should not call makeValid on the dom modifier if the element has disabled valid element styling', function () {
validator.makeValid(angular.element('<input type="text" disable-valid-styling="true"/>'));
expect(makeValidInvocationCount).to.equal(0);
});
it('should not call makeValid on the dom modifier if the element has disabled valid element styling', function () {
validator.makeValid(angular.element('<input type="text" disable-valid-styling="true"/>'));
expect(makeValidInvocationCount).to.equal(0);
});
it('should call makeDefault on the dom modifier if the element has disabled valid element styling', function () {
sandbox.stub(validator, 'makeDefault');
validator.makeValid(angular.element('<input type="text" disable-valid-styling="true"/>'));
it('should call makeDefault on the dom modifier if the element has disabled valid element styling', function () {
sandbox.stub(validator, 'makeDefault');
validator.makeValid(angular.element('<input type="text" disable-valid-styling="true"/>'));
expect(validator.makeDefault.calledOnce).to.equal(true);
});
expect(validator.makeDefault.calledOnce).to.equal(true);
});
it('should call makeValid on the dom modifier if the element has not disabled valid element styling', function () {
validator.makeValid(angular.element('<input type="text" disable-valid-styling="false"/>'));
expect(makeValidInvocationCount).to.equal(1);
});
});
it('should call makeValid on the dom modifier if the element has not disabled valid element styling', function () {
validator.makeValid(angular.element('<input type="text" disable-valid-styling="false"/>'));
expect(makeValidInvocationCount).to.equal(1);
});
});
describe('makeInvalid', function () {
var bs3 = 'bs3',
makeInvalidInvocationCount = 0,
domModifier = {
makeValid: angular.noop,
makeInvalid: function () {
makeInvalidInvocationCount += 1;
},
name: bs3
};
describe('makeInvalid', function () {
var bs3 = 'bs3',
makeInvalidInvocationCount = 0,
domModifier = {
makeValid: angular.noop,
makeInvalid: function () {
makeInvalidInvocationCount += 1;
},
name: bs3
};
beforeEach(function () {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
});
beforeEach(function () {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
});
afterEach(function () {
makeInvalidInvocationCount = 0;
});
afterEach(function () {
makeInvalidInvocationCount = 0;
});
it('should call makeInvalid on the dom modifier once', function () {
validator.makeInvalid(angular.element('<input type="text"/>'));
expect(makeInvalidInvocationCount).to.equal(1);
});
it('should call makeInvalid on the dom modifier once', function () {
validator.makeInvalid(angular.element('<input type="text"/>'));
expect(makeInvalidInvocationCount).to.equal(1);
});
it('should not call makeInvalid on the dom modifier if enableInvalidElementStyling is false', function () {
validator.setInvalidElementStyling(false);
validator.makeInvalid(angular.element('<input type="text"/>'));
expect(makeInvalidInvocationCount).to.equal(0);
});
it('should not call makeInvalid on the dom modifier if enableInvalidElementStyling is false', function () {
validator.setInvalidElementStyling(false);
validator.makeInvalid(angular.element('<input type="text"/>'));
expect(makeInvalidInvocationCount).to.equal(0);
});
it('should not call makeInvalid on the dom modifier if the element has disabled invalid element styling', function () {
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="true"/>'));
expect(makeInvalidInvocationCount).to.equal(0);
});
it('should not call makeInvalid on the dom modifier if the element has disabled invalid element styling', function () {
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="true"/>'));
expect(makeInvalidInvocationCount).to.equal(0);
});
it('should call makeDefault on the dom modifier if the element has disabled invalid element styling', function () {
sandbox.stub(validator, 'makeDefault');
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="true"/>'));
it('should call makeDefault on the dom modifier if the element has disabled invalid element styling', function () {
sandbox.stub(validator, 'makeDefault');
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="true"/>'));
expect(validator.makeDefault.calledOnce).to.equal(true);
});
expect(validator.makeDefault.calledOnce).to.equal(true);
});
it('should call makeInvalid on the dom modifier if the element has not disabled invalid element styling', function () {
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="false"/>'));
expect(makeInvalidInvocationCount).to.equal(1);
});
});
it('should call makeInvalid on the dom modifier if the element has not disabled invalid element styling', function () {
validator.makeInvalid(angular.element('<input type="text" disable-invalid-styling="false"/>'));
expect(makeInvalidInvocationCount).to.equal(1);
});
});
describe('makeDefault', function () {
var bs3 = 'bs3',
makeDefaultInvocationCount = 0,
domModifier = {
makeValid: angular.noop,
makeInvalid: angular.noop,
makeDefault: function () {
makeDefaultInvocationCount += 1;
},
name: bs3
};
describe('makeDefault', function () {
var bs3 = 'bs3',
makeDefaultInvocationCount = 0,
domModifier = {
makeValid: angular.noop,
makeInvalid: angular.noop,
makeDefault: function () {
makeDefaultInvocationCount += 1;
},
name: bs3
};
beforeEach(function () {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
});
beforeEach(function () {
validator.registerDomModifier(bs3, domModifier);
validator.setDefaultElementModifier(bs3);
});
afterEach(function () {
makeDefaultInvocationCount = 0;
});
afterEach(function () {
makeDefaultInvocationCount = 0;
});
it('should call makeDefault on the dom modifier once', function () {
validator.makeDefault(angular.element('<input type="text"/>'));
expect(makeDefaultInvocationCount).to.equal(1);
});
});
it('should call makeDefault on the dom modifier once', function () {
validator.makeDefault(angular.element('<input type="text"/>'));
expect(makeDefaultInvocationCount).to.equal(1);
});
});
});
});
}(angular, sinon));
(function (angular, sinon) {
'use strict';
'use strict';
describe('jcs.autoValidate bootstrap3ElementModifier', function () {
var sandbox, $rootScope, bootstrap3ElementModifier;
describe('jcs.autoValidate bootstrap3ElementModifier', function () {
var sandbox, $rootScope, bootstrap3ElementModifier;
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('bootstrap3ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
bootstrap3ElementModifier = $injector.get('bootstrap3ElementModifier');
}));
describe('bootstrap3ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
bootstrap3ElementModifier = $injector.get('bootstrap3ElementModifier');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
expect(bootstrap3ElementModifier).to.not.equal(undefined);
});
it('should be defined', function () {
expect(bootstrap3ElementModifier).to.not.equal(undefined);
});
describe('makeDefault', function () {
it('should remove the .has-error class, .has-success and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-error has-success has-feedback"><input type="text"/></div>');
describe('makeDefault', function () {
it('should remove the .has-error class, .has-success and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-error has-success has-feedback"><input type="text"/></div>');
bootstrap3ElementModifier.makeDefault(element);
bootstrap3ElementModifier.makeDefault(element);
expect(element.hasClass('has-error')).to.equal(false);
expect(element.hasClass('has-success')).to.equal(false);
expect(element.hasClass('has-feedback')).to.equal(false);
});
expect(element.hasClass('has-error')).to.equal(false);
expect(element.hasClass('has-success')).to.equal(false);
expect(element.hasClass('has-feedback')).to.equal(false);
});
it('should remove the .error-msg element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el9" type="email" class="form-control" required="required" ng-model="model.email"><span class="help-block error-msg">help text</span></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
it('should remove the .error-msg element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el9" type="email" class="form-control" required="required" ng-model="model.email"><span class="help-block error-msg">help text</span></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
bootstrap3ElementModifier.makeDefault(element.find('#el9'));
bootstrap3ElementModifier.makeDefault(element.find('#el9'));
expect(element.find('.help-block').length).to.equal(0);
});
});
expect(element.find('.help-block').length).to.equal(0);
});
});
describe('makeInvalid', function () {
it('should remove the .has-success class and add the .has-error and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-success"><input type="text"/></div>');
describe('makeInvalid', function () {
it('should remove the .has-success class and add the .has-error and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-success"><input type="text"/></div>');
bootstrap3ElementModifier.makeInvalid(element);
bootstrap3ElementModifier.makeInvalid(element);
expect(element.hasClass('has-success')).to.equal(false);
expect(element.hasClass('has-error')).to.equal(true);
expect(element.hasClass('has-feedback')).to.equal(true);
});
expect(element.hasClass('has-success')).to.equal(false);
expect(element.hasClass('has-error')).to.equal(true);
expect(element.hasClass('has-feedback')).to.equal(true);
});
it('should add an error icon when property "addValidationStateIcons" is true', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el3" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
it('should add an error icon when property "addValidationStateIcons" is true', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el3" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
bootstrap3ElementModifier.makeInvalid(element.find('#el3'));
bootstrap3ElementModifier.makeInvalid(element.find('#el3'));
expect(element.find('.glyphicon.glyphicon-remove.form-control-feedback').length).to.equal(1);
});
expect(element.find('.glyphicon.glyphicon-remove.form-control-feedback').length).to.equal(1);
});
it('should add the .help-block element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el4" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
it('should add the .help-block element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el4" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
bootstrap3ElementModifier.makeInvalid(element.find('#el4'));
bootstrap3ElementModifier.makeInvalid(element.find('#el4'));
expect(element.find('.help-block').length).to.equal(1);
});
});
expect(element.find('.help-block').length).to.equal(1);
});
});
describe('makeValid', function () {
it('should remove the .has-error class and add the .has-success and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-error"><input type="text"/></div>');
describe('makeValid', function () {
it('should remove the .has-error class and add the .has-success and .has-feedback classes', function () {
var element = angular.element('<div class="form-group has-error"><input type="text"/></div>');
bootstrap3ElementModifier.makeValid(element);
bootstrap3ElementModifier.makeValid(element);
expect(element.hasClass('has-error')).to.equal(false);
expect(element.hasClass('has-success')).to.equal(true);
expect(element.hasClass('has-feedback')).to.equal(true);
});
expect(element.hasClass('has-error')).to.equal(false);
expect(element.hasClass('has-success')).to.equal(true);
expect(element.hasClass('has-feedback')).to.equal(true);
});
it('should add an OK icon when property "addValidationStateIcons" is true', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el1" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
it('should add an OK icon when property "addValidationStateIcons" is true', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el1" type="email" class="form-control" required="required" ng-model="model.email"></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
bootstrap3ElementModifier.makeValid(element.find('#el1'));
bootstrap3ElementModifier.makeValid(element.find('#el1'));
expect(element.find('.glyphicon.glyphicon-ok.form-control-feedback').length).to.equal(1);
});
expect(element.find('.glyphicon.glyphicon-ok.form-control-feedback').length).to.equal(1);
});
it('should remove the .error-msg element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el2" type="email" class="form-control" required="required" ng-model="model.email"><span class="help-block error-msg">help text</span></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
it('should remove the .error-msg element', function () {
var element = angular.element('<div class="form-group"><div class="col-sm-10">' +
'<input id="el2" type="email" class="form-control" required="required" ng-model="model.email"><span class="help-block error-msg">help text</span></div></div>');
bootstrap3ElementModifier.enableValidationStateIcons(true);
bootstrap3ElementModifier.makeValid(element.find('#el2'));
bootstrap3ElementModifier.makeValid(element.find('#el2'));
expect(element.find('.help-block').length).to.equal(0);
});
});
expect(element.find('.help-block').length).to.equal(0);
});
});
});
});
}(angular, sinon));
(function (angular, sinon) {
'use strict';
'use strict';
describe('jcs.autoValidate debounce', function () {
var sandbox, $rootScope, $timeout, debounce;
describe('jcs.autoValidate debounce', function () {
var sandbox, $rootScope, $timeout, debounce;
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('bootstrap3ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$timeout = $injector.get('$timeout');
debounce = $injector.get('jcs-debounce');
}));
describe('bootstrap3ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$timeout = $injector.get('$timeout');
debounce = $injector.get('jcs-debounce');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
expect(debounce).to.not.equal(undefined);
});
it('should be defined', function () {
expect(debounce).to.not.equal(undefined);
});
describe('debounce', function () {
it('should return a function', function () {
var debouceFn = debounce.debounce(angular.noop);
describe('debounce', function () {
it('should return a function', function () {
var debouceFn = debounce.debounce(angular.noop);
expect(typeof debouceFn === 'function').to.equal(true);
});
expect(typeof debouceFn === 'function').to.equal(true);
});
it('should execute immediately with a specified timeout', function () {
var debouceFnCalledTimes = 0,
debouceFn = debounce.debounce(function () {
debouceFnCalledTimes += 1;
});
it('should execute immediately with a specified timeout', function () {
var debouceFnCalledTimes = 0,
debouceFn = debounce.debounce(function () {
debouceFnCalledTimes += 1;
});
debouceFn();
debouceFn();
$timeout.flush();
$timeout.flush();
expect(debouceFnCalledTimes).to.equal(1);
});
expect(debouceFnCalledTimes).to.equal(1);
});
it('should only execute once when called multiple times', function () {
var debouceFnCalledTimes = 0,
debouceFn = debounce.debounce(function () {
debouceFnCalledTimes += 1;
}, 100);
it('should only execute once when called multiple times', function () {
var debouceFnCalledTimes = 0,
debouceFn = debounce.debounce(function () {
debouceFnCalledTimes += 1;
}, 100);
debouceFn();
debouceFn();
debouceFn();
debouceFn();
debouceFn();
debouceFn();
debouceFn();
debouceFn();
$timeout.flush();
$timeout.flush();
expect(debouceFnCalledTimes).to.equal(1);
});
});
expect(debouceFnCalledTimes).to.equal(1);
});
});
});
});
}(angular, sinon));
(function (angular, sinon) {
'use strict';
'use strict';
describe('jcs-autoValidate defaultErrorMessageResolver', function () {
var sandbox, $rootScope, $q, $httpBackend, defaultErrorMessageResolver;
describe('jcs-autoValidate defaultErrorMessageResolver', function () {
var sandbox, $rootScope, $q, $httpBackend, defaultErrorMessageResolver;
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('defaultErrorMessageResolver', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$httpBackend = $injector.get('$httpBackend');
$q = $injector.get('$q');
defaultErrorMessageResolver = $injector.get('defaultErrorMessageResolver');
}));
describe('defaultErrorMessageResolver', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$httpBackend = $injector.get('$httpBackend');
$q = $injector.get('$q');
defaultErrorMessageResolver = $injector.get('defaultErrorMessageResolver');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
expect(defaultErrorMessageResolver).to.exist;
});
it('should be defined', function () {
expect(defaultErrorMessageResolver).to.exist;
});
describe('getErrorMessages', function () {
it('should be an object', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages).to.not.equal(undefined);
done();
});
describe('getErrorMessages', function () {
it('should be an object', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key defaultMsg', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.defaultMsg).to.not.equal(undefined);
done();
});
it('should have the key defaultMsg', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.defaultMsg).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key email', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.email).to.not.equal(undefined);
done();
});
it('should have the key email', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.email).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key minlength', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.minlength).to.not.equal(undefined);
done();
});
it('should have the key minlength', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.minlength).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key maxlength', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.maxlength).to.not.equal(undefined);
done();
});
it('should have the key maxlength', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.maxlength).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key min', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.min).to.not.equal(undefined);
done();
});
it('should have the key min', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.min).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key max', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.max).to.not.equal(undefined);
done();
});
it('should have the key max', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.max).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key required', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.required).to.not.equal(undefined);
done();
});
it('should have the key required', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.required).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key date', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.date).to.not.equal(undefined);
done();
});
it('should have the key date', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.date).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key pattern', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.pattern).to.not.equal(undefined);
done();
});
it('should have the key pattern', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.pattern).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key number', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.number).to.not.equal(undefined);
done();
});
it('should have the key number', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.number).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should have the key url', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.url).to.not.equal(undefined);
done();
});
it('should have the key url', function (done) {
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
expect(errorMessages.url).to.not.equal(undefined);
done();
});
$rootScope.$apply();
});
});
$rootScope.$apply();
});
});
describe('setI18nFileRootPath', function () {
it('should be defined', function () {
expect(defaultErrorMessageResolver.setI18nFileRootPath).to.not.equal(undefined);
});
});
describe('setI18nFileRootPath', function () {
it('should be defined', function () {
expect(defaultErrorMessageResolver.setI18nFileRootPath).to.not.equal(undefined);
});
});
describe('setCulture', function () {
afterEach(function () {
//$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('setCulture', function () {
afterEach(function () {
//$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should return with calling the loadingFn if the culture is already loaded', function (done) {
var loadingFnCalled = false,
loadingFn = function () {
loadingFnCalled = true;
};
it('should return with calling the loadingFn if the culture is already loaded', function (done) {
var loadingFnCalled = false,
loadingFn = function () {
loadingFnCalled = true;
};
defaultErrorMessageResolver.setCulture('en-gb', loadingFn).then(function () {
expect(loadingFnCalled).to.equal(false);
done();
});
defaultErrorMessageResolver.setCulture('en-gb', loadingFn).then(function () {
expect(loadingFnCalled).to.equal(false);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should call the loading function if it is specified', function (done) {
var loadingFnCalled = false,
loadingFn = function () {
var defer = $q.defer();
loadingFnCalled = true;
defer.resolve({});
return defer.promise;
};
it('should call the loading function if it is specified', function (done) {
var loadingFnCalled = false,
loadingFn = function () {
var defer = $q.defer();
loadingFnCalled = true;
defer.resolve({});
return defer.promise;
};
defaultErrorMessageResolver.setCulture('fr-fr', loadingFn).then(function () {
expect(loadingFnCalled).to.equal(true);
done();
});
defaultErrorMessageResolver.setCulture('fr-fr', loadingFn).then(function () {
expect(loadingFnCalled).to.equal(true);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should call $http to load the culture file with the correct url', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_fr-fr.json').respond(200, {});
it('should call $http to load the culture file with the correct url', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_fr-fr.json').respond(200, {});
defaultErrorMessageResolver.setCulture('fr-fr').then(function () {
done();
});
defaultErrorMessageResolver.setCulture('fr-fr').then(function () {
done();
});
$httpBackend.flush();
$httpBackend.flush();
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should call $http to load the culture file with the correct url by lower casing the culture code', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-es.json').respond(200, {});
it('should call $http to load the culture file with the correct url by lower casing the culture code', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-es.json').respond(200, {});
defaultErrorMessageResolver.setCulture('en-ES').then(function () {
done();
});
defaultErrorMessageResolver.setCulture('en-ES').then(function () {
done();
});
$httpBackend.flush();
$httpBackend.flush();
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should return the error in the promise when the load of a remote culture file fails', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-it.json').respond(404, {
data: 'some error'
});
it('should return the error in the promise when the load of a remote culture file fails', function (done) {
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-it.json').respond(404, {
data: 'some error'
});
defaultErrorMessageResolver.setCulture('en-it').then(function () {}, function (err) {
done();
expect(err.data).to.equal('some error');
});
defaultErrorMessageResolver.setCulture('en-it').then(function () {}, function (err) {
done();
expect(err.data).to.equal('some error');
});
$httpBackend.flush();
$httpBackend.flush();
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should call $http with the correct url path when the root has been set', function (done) {
$httpBackend.expectGET('some/made/up/path/jcs-auto-validate_zh-cn.json').respond(200, {});
it('should call $http with the correct url path when the root has been set', function (done) {
$httpBackend.expectGET('some/made/up/path/jcs-auto-validate_zh-cn.json').respond(200, {});
defaultErrorMessageResolver.setI18nFileRootPath('some/made/up/path');
defaultErrorMessageResolver.setI18nFileRootPath('some/made/up/path');
defaultErrorMessageResolver.setCulture('zh-cn').then(function () {
done();
});
defaultErrorMessageResolver.setCulture('zh-cn').then(function () {
done();
});
$httpBackend.flush();
$httpBackend.flush();
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should resolve the current waiting error message once the culture has been loaded.', function (done) {
var requiredStr = 'required';
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-fr.json').respond(200, {
required: requiredStr
});
it('should resolve the current waiting error message once the culture has been loaded.', function (done) {
var requiredStr = 'required';
$httpBackend.expectGET('js/angular-auto-validate/dist/lang/jcs-auto-validate_en-fr.json').respond(200, {
required: requiredStr
});
defaultErrorMessageResolver.setCulture('en-fr');
defaultErrorMessageResolver.resolve('required').then(function (msg) {
expect(msg).to.equal(requiredStr);
done();
});
defaultErrorMessageResolver.setCulture('en-fr');
defaultErrorMessageResolver.resolve('required').then(function (msg) {
expect(msg).to.equal(requiredStr);
done();
});
$httpBackend.flush();
$httpBackend.flush();
$rootScope.$apply();
});
});
$rootScope.$apply();
});
});
describe('resolve', function () {
it('should return a promise', function () {
var promise = defaultErrorMessageResolver.resolve('required');
describe('resolve', function () {
it('should return a promise', function () {
var promise = defaultErrorMessageResolver.resolve('required');
expect(promise).to.not.equal(undefined);
expect(promise.then).to.not.equal(undefined);
});
expect(promise).to.not.equal(undefined);
expect(promise.then).to.not.equal(undefined);
});
it('should return the default error message when the error type is not found', function (done) {
var errorType = 'not_present';
defaultErrorMessageResolver.resolve(errorType).then(function (msg) {
expect(msg).to.equal('Please add error message for ' + errorType);
done();
});
it('should return the default error message when the error type is not found', function (done) {
var errorType = 'not_present';
defaultErrorMessageResolver.resolve(errorType).then(function (msg) {
expect(msg).to.equal('Please add error message for ' + errorType);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should return only the error message if the element is undefined', function (done) {
var errorType = 'required';
defaultErrorMessageResolver.resolve(errorType).then(function (msg) {
expect(msg).to.equal('This field is required');
done();
});
it('should return only the error message if the element is undefined', function (done) {
var errorType = 'required';
defaultErrorMessageResolver.resolve(errorType).then(function (msg) {
expect(msg).to.equal('This field is required');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should replace parameters in error message it element is passed has data-* attribute of errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" data-ng-minlength="2" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter at least 2 characters');
done();
});
it('should replace parameters in error message it element is passed has data-* attribute of errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" data-ng-minlength="2" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter at least 2 characters');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should replace parameters in error message if element is passed has ng-* attribute of errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" ng-minlength="2" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter at least 2 characters');
done();
});
it('should replace parameters in error message if element is passed has ng-* attribute of errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" ng-minlength="2" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter at least 2 characters');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should default to the ng-* version of the attribute when replacing parameters in the meesage', function (done) {
var errorType = 'max',
element = angular.element('<input type="number" ng-max="2" max="2147483647" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter the maximum number of 2');
done();
});
it('should default to the ng-* version of the attribute when replacing parameters in the meesage', function (done) {
var errorType = 'max',
element = angular.element('<input type="number" ng-max="2" max="2147483647" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter the maximum number of 2');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should return an overridden error message type if the attribute is present on the element and contains the correct key', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" data-ng-minlength="2" ng-minlength-err-type="required" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('This field is required');
done();
});
it('should return an overridden error message type if the attribute is present on the element and contains the correct key', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" data-ng-minlength="2" ng-minlength-err-type="required" />');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('This field is required');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should replace parameters in error message if element is is overriding the error message type and using a parameter for the overridden errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" ng-minlength="3" ng-minlength-err-type="max"/>');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter the maximum number of 3');
done();
});
it('should replace parameters in error message if element is is overriding the error message type and using a parameter for the overridden errorType', function (done) {
var errorType = 'minlength',
element = angular.element('<input type="text" ng-minlength="3" ng-minlength-err-type="max"/>');
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal('Please enter the maximum number of 3');
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should return the overridden errorType for a custom validation type', function (done) {
var errorType = 'validator',
errorMessage = 'Please ensure the password you entered match',
element = angular.element('<input type="password" ng-model="vm.confirmPassword" validator-err-type="invalidPassword_Confirmation" />');
it('should return the overridden errorType for a custom validation type', function (done) {
var errorType = 'validator',
errorMessage = 'Please ensure the password you entered match',
element = angular.element('<input type="password" ng-model="vm.confirmPassword" validator-err-type="invalidPassword_Confirmation" />');
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
errorMessages.invalidPassword_Confirmation = errorMessage;
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
errorMessages.invalidPassword_Confirmation = errorMessage;
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal(errorMessage);
done();
});
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal(errorMessage);
done();
});
});
$rootScope.$apply();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
it('should return the overridden errorType for a custom validation type which has invalid quote characters', function (done) {
var errorType = 'validator',
errorMessage = 'Please ensure the password you entered match',
element = angular.element('<input type="password" ng-model="vm.confirmPassword" validator-err-type=“invalidPasswordConfirmation“ />');
it('should return the overridden errorType for a custom validation type which has invalid quote characters', function (done) {
var errorType = 'validator',
errorMessage = 'Please ensure the password you entered match',
element = angular.element('<input type="password" ng-model="vm.confirmPassword" validator-err-type=“invalidPasswordConfirmation“ />');
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
errorMessages.invalidPasswordConfirmation = errorMessage;
defaultErrorMessageResolver.getErrorMessages().then(function (errorMessages) {
errorMessages.invalidPasswordConfirmation = errorMessage;
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal(errorMessage);
done();
});
});
defaultErrorMessageResolver.resolve(errorType, element).then(function (msg) {
expect(msg).to.equal(errorMessage);
done();
});
$rootScope.$apply();
});
$rootScope.$apply();
});
});
$rootScope.$apply();
});
});
});
});
}(angular, sinon));
(function (angular, sinon) {
'use strict';
'use strict';
describe('angulartemplates.modules.form foundation5ElementModifier', function () {
var sandbox, $rootScope, foundation5ElementModifier;
describe('angulartemplates.modules.form foundation5ElementModifier', function () {
var sandbox, $rootScope, foundation5ElementModifier;
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('foundation5ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
foundation5ElementModifier = $injector.get('foundation5ElementModifier');
}));
describe('foundation5ElementModifier', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
foundation5ElementModifier = $injector.get('foundation5ElementModifier');
}));
afterEach(function () {
sandbox.restore();
});
afterEach(function () {
sandbox.restore();
});
it('should be defined', function () {
expect(foundation5ElementModifier).to.not.equal(undefined);
});
it('should be defined', function () {
expect(foundation5ElementModifier).to.not.equal(undefined);
});
describe('makeDefault', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
describe('makeDefault', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
it('should remove the error class from the input', function () {
var element = angular.element('<input type="text" class="error"/>');
foundation5ElementModifier.makeDefault(element);
it('should remove the error class from the input', function () {
var element = angular.element('<input type="text" class="error"/>');
foundation5ElementModifier.makeDefault(element);
expect(element.hasClass('error')).to.equal(false);
});
expect(element.hasClass('error')).to.equal(false);
});
it('should remove the error class from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /></div>');
foundation5ElementModifier.makeDefault(element);
it('should remove the error class from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /></div>');
foundation5ElementModifier.makeDefault(element);
expect(element.hasClass('error')).to.equal(false);
});
expect(element.hasClass('error')).to.equal(false);
});
it('should remove the small.error element from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /><small class="error">error text</small></div>');
foundation5ElementModifier.makeDefault(element);
it('should remove the small.error element from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /><small class="error">error text</small></div>');
foundation5ElementModifier.makeDefault(element);
expect(element.find('small.error').length).to.equal(0);
});
});
expect(element.find('small.error').length).to.equal(0);
});
});
describe('makeValid', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
describe('makeValid', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
it('should remove the error class from the input', function () {
var element = angular.element('<input type="text" class="error"/>');
foundation5ElementModifier.makeValid(element);
it('should remove the error class from the input', function () {
var element = angular.element('<input type="text" class="error"/>');
foundation5ElementModifier.makeValid(element);
expect(element.hasClass('error')).to.equal(false);
});
expect(element.hasClass('error')).to.equal(false);
});
it('should remove the error class from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /></div>');
foundation5ElementModifier.makeValid(element);
it('should remove the error class from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /></div>');
foundation5ElementModifier.makeValid(element);
expect(element.hasClass('error')).to.equal(false);
});
expect(element.hasClass('error')).to.equal(false);
});
it('should remove the small.error element from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /><small class="error">error text</small></div>');
foundation5ElementModifier.makeValid(element);
it('should remove the small.error element from the parent element with .columns class', function () {
var element = angular.element('<div class="columns error"><input type="text" /><small class="error">error text</small></div>');
foundation5ElementModifier.makeValid(element);
expect(element.find('small.error').length).to.equal(0);
});
});
expect(element.find('small.error').length).to.equal(0);
});
});
describe('makeInvalid', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
describe('makeInvalid', function () {
/**
* Foundation allows the .error class to be on either the element or the parent .column element.
*/
it('should add the error class to the input element', function () {
var element = angular.element('<input type="text" />');
foundation5ElementModifier.makeInvalid(element);
it('should add the error class to the input element', function () {
var element = angular.element('<input type="text" />');
foundation5ElementModifier.makeInvalid(element);
expect(element.hasClass('error')).to.equal(true);
});
expect(element.hasClass('error')).to.equal(true);
});
it('should add the error class to the parent element with .columns class', function () {
var element = angular.element('<div class="columns"><input type="text" /></div>');
foundation5ElementModifier.makeInvalid(element);
it('should add the error class to the parent element with .columns class', function () {
var element = angular.element('<div class="columns"><input type="text" /></div>');
foundation5ElementModifier.makeInvalid(element);
expect(element.hasClass('error')).to.equal(true);
});
expect(element.hasClass('error')).to.equal(true);
});
it('should add the small.error element to the parent element with .columns class', function () {
var element = angular.element('<div class="columns"><input type="text" /></div>');
foundation5ElementModifier.makeInvalid(element);
it('should add the small.error element to the parent element with .columns class', function () {
var element = angular.element('<div class="columns"><input type="text" /></div>');
foundation5ElementModifier.makeInvalid(element);
expect(element.find('small.error').length).to.equal(1);
});
});
expect(element.find('small.error').length).to.equal(1);
});
});
});
});
}(angular, sinon));
(function (angular, sinon) {
'use strict';
'use strict';
describe('jcs-autoValidate validationManager', function () {
var sandbox, $rootScope, $compile, $q, validator, validationManager, modelCtrl, defer, elementUtils,
setModelCtrl = function () {
modelCtrl = {
$parsers: [],
$formatters: [],
$name: 'name'
};
},
compileElement = function (html, includesForm) {
html = includesForm ? html : '<form ng-submit="">' + html + '</form>';
var element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
element = includesForm ? element : angular.element(element[0].children[0]);
return element;
},
getDefaultFormOptions = function () {
return {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false
};
};
describe('jcs-autoValidate validationManager', function () {
var sandbox, $rootScope, $compile, $q, validator, validationManager, modelCtrl, defer, elementUtils,
setModelCtrl = function () {
modelCtrl = {
$parsers: [],
$formatters: [],
$name: 'name'
};
},
compileElement = function (html, includesForm) {
html = includesForm ? html : '<form ng-submit="">' + html + '</form>';
var element = angular.element(html);
$compile(element)($rootScope);
$rootScope.$digest();
element = includesForm ? element : angular.element(element[0].children[0]);
return element;
},
getDefaultFormOptions = function () {
return {
forceValidation: false,
disabled: false,
validateNonVisibleControls: false,
validateOnFormSubmit: false,
formController: {}
};
};
beforeEach(module('jcs-autoValidate'));
beforeEach(module('jcs-autoValidate'));
describe('validationManager', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
defer = $q.defer();
validator = $injector.get('validator');
validationManager = $injector.get('validationManager');
elementUtils = $injector.get('jcs-elementUtils');
describe('validationManager', function () {
beforeEach(inject(function ($injector) {
sandbox = sinon.sandbox.create();
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$q = $injector.get('$q');
defer = $q.defer();
validator = $injector.get('validator');
validationManager = $injector.get('validationManager');
elementUtils = $injector.get('jcs-elementUtils');
sandbox.stub(validator, 'makeValid');
sandbox.stub(validator, 'makeInvalid');
sandbox.stub(validator, 'getErrorMessage').returns(defer.promise);
sandbox.stub(validator, 'makeValid');
sandbox.stub(validator, 'makeInvalid');
sandbox.stub(validator, 'getErrorMessage').returns(defer.promise);
setModelCtrl();
}));
setModelCtrl();
}));
afterEach(function () {
sandbox.restore();
setModelCtrl();
});
afterEach(function () {
sandbox.restore();
setModelCtrl();
});
it('should be defined', function () {
expect(validationManager).to.exist;
});
it('should be defined', function () {
expect(validationManager).to.exist;
});
describe('validateElement', function () {
it('should return true if the control is pristine and not make the element valid', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
describe('validateElement', function () {
it('should return true if the control is pristine and not make the element valid', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = true;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(false);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = true;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(false);
});
it('should make the element valid and return true if the control is not pristine and has no validation requirements', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
it('should make the element valid and return true if the control is not pristine and has no validation requirements', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = false;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(true);
expect(validator.makeInvalid.called).to.equal(false);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = false;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(true);
expect(validator.makeInvalid.called).to.equal(false);
});
it('should not validate the element if it is not visible on the screen', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
it('should not validate the element if it is not visible on the screen', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
sandbox.stub(elementUtils, 'isElementVisible').returns(false);
modelCtrl.$pristine = false;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
sandbox.stub(elementUtils, 'isElementVisible').returns(false);
modelCtrl.$pristine = false;
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(false);
});
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(false);
});
it('should validate the element if it is not visible on the screen as the form option validateNonVisibleControls is true', function () {
var el = compileElement('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result,
frmOptions = getDefaultFormOptions();
it('should validate the element if it is not visible on the screen as the form option validateNonVisibleControls is true', function () {
var el = compileElement('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result,
frmOptions = getDefaultFormOptions();
frmOptions.validateNonVisibleControls = true;
sandbox.stub(elementUtils, 'isElementVisible').returns(false);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$errors = {
required: true
};
result = validationManager.validateElement(modelCtrl, el, frmOptions);
frmOptions.validateNonVisibleControls = true;
sandbox.stub(elementUtils, 'isElementVisible').returns(false);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$errors = {
required: true
};
result = validationManager.validateElement(modelCtrl, el, frmOptions);
defer.resolve('error message');
$rootScope.$apply();
defer.resolve('error message');
$rootScope.$apply();
expect(result).to.equal(false);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(true);
});
expect(result).to.equal(false);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(true);
});
it('should validate the element regardless of whether there is a parent form', function () {
var el = compileElement('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>', true),
result,
frmOptions = getDefaultFormOptions();
it('should validate the element regardless of whether there is a parent form', function () {
var el = compileElement('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>', true),
result,
frmOptions = getDefaultFormOptions();
frmOptions.validateNonVisibleControls = true;
sandbox.stub(elementUtils, 'isElementVisible').returns(false);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$errors = {
required: true
};
result = validationManager.validateElement(modelCtrl, el, frmOptions);
frmOptions.validateNonVisibleControls = true;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$errors = {
required: true
};
result = validationManager.validateElement(modelCtrl, el, frmOptions);
defer.resolve('error message');
$rootScope.$apply();
defer.resolve('error message');
$rootScope.$apply();
expect(result).to.equal(false);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(true);
});
expect(result).to.equal(false);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(true);
});
it('should call validator to make element valid when there are $formatters and the form is valid', function () {
var el = angular.element('<input type="text" ng-model="propOne"/>');
it('should not validate the element if validateOnSubmit is true and the form has not been submitted yet', function () {
var el = angular.element('<input type="text" ng-model="propOne" required="" ng-minlength="10"/>'),
result;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = false;
var formOptions = getDefaultFormOptions();
formOptions.formController.$submitted = false;
formOptions.validateOnFormSubmit = true;
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(validator.makeValid.calledOnce).to.equal(true);
expect(validator.makeValid.calledWith(el)).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$pristine = false;
result = validationManager.validateElement(modelCtrl, el, formOptions);
it('should call validator to make element invalid when there are $formatters and the form is invalid', function () {
var el = angular.element('<input type="text" ng-model="propOne" />'),
errorMsg = 'msg';
expect(result).to.equal(true);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(false);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
it('should validate the element if validateOnSubmit is true and the form has been submitted', function () {
var el = angular.element('<input type="text" ng-model="propOne"/>'),
result;
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
var formOptions = getDefaultFormOptions();
formOptions.formController.$submitted = true;
formOptions.validateOnFormSubmit = true;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
defer.resolve('error message');
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
modelCtrl.$parsers.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
it('should call validator to make element invalid when there are $parsers and the form is invalid', function () {
var el = angular.element('<input type="text" ng-model="propOne"/>'),
errorMsg = 'msg';
result = validationManager.validateElement(modelCtrl, el, formOptions);
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$parsers.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
$rootScope.$apply();
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(result).to.equal(false);
expect(validator.makeValid.called).to.equal(false);
expect(validator.makeInvalid.called).to.equal(true);
});
$rootScope.$apply();
it('should call validator to make element valid when there are $formatters and the form is valid', function () {
var el = angular.element('<input type="text" ng-model="propOne"/>');
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = false;
it('should return true if the input has no validation specified', function () {
var el = angular.element('<input type="text" ng-model="propertyOne" />'),
result;
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(validator.makeValid.calledOnce).to.equal(true);
expect(validator.makeValid.calledWith(el)).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
it('should call validator to make element invalid when there are $formatters and the form is invalid', function () {
var el = angular.element('<input type="text" ng-model="propOne" />'),
errorMsg = 'msg';
expect(result).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
it('should call validator to make element valid it the control is marked as a custom form control', function () {
var el = angular.element('<div type="text" ng-model="propOne" register-custom-form-control=""></div>');
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = false;
$rootScope.$apply();
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(validator.makeValid.calledOnce).to.equal(true);
expect(validator.makeValid.calledWith(el)).to.equal(true);
});
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
it('should call validator to make element invalid it the control is marked as a custom form control', function () {
var el = angular.element('<div type="text" ng-model="propOne" register-custom-form-control=""></div>'),
errorMsg = 'msg';
it('should call validator to make element invalid when there are $parsers and the form is invalid', function () {
var el = angular.element('<input type="text" ng-model="propOne"/>'),
errorMsg = 'msg';
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$parsers.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
$rootScope.$apply();
$rootScope.$apply();
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
});
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
describe('validateForm', function () {
it('should return false it the form element is undefined', function () {
var result = validationManager.validateForm();
it('should return true if the input has no validation specified', function () {
var el = angular.element('<input type="text" ng-model="propertyOne" />'),
result;
expect(result).to.equal(false);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
result = validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
it('should return true it the form controller is set to not auto validate the form', function () {
var form = compileElement('<form role="form" novalidate="novalidate" ng-submit="submit();" disable-dynamic-validation><input ng-model="name" required /></form>', true),
result = validationManager.validateForm(form);
expect(result).to.equal(true);
});
expect(result).to.equal(true);
});
it('should call validator to make element valid if the control is marked as a custom form control', function () {
var el = angular.element('<div type="text" ng-model="propOne" register-custom-form-control=""></div>');
it('should only validate elements on the parent and not disabled subform', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
subFrm = compileElement('<ng-form name="subFrm1" disable-dynamic-validation></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="surname" ng-minlength="2" />', true),
isValid;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = false;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
subFrm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('minlength', false);
frm.append(subFrm);
$rootScope.$apply();
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
expect(validator.makeValid.calledOnce).to.equal(true);
expect(validator.makeValid.calledWith(el)).to.equal(true);
});
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
it('should call validator to make element invalid it the control is marked as a custom form control', function () {
var el = angular.element('<div type="text" ng-model="propOne" register-custom-form-control=""></div>'),
errorMsg = 'msg';
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
modelCtrl.$formatters.push(angular.noop);
modelCtrl.$pristine = false;
modelCtrl.$invalid = true;
modelCtrl.$error = {
required: true
};
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
defer.resolve(errorMsg);
validationManager.validateElement(modelCtrl, el, getDefaultFormOptions());
it('should only validate elements on the parent and not disabled subform where the subform is via an attribute', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
subFrm = compileElement('<div ng-form name="subFrm1" disable-dynamic-validation></div>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="surname" ng-minlength="2" />', true),
isValid;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
subFrm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('minlength', false);
frm.append(subFrm);
$rootScope.$apply();
expect(validator.makeInvalid.calledOnce).to.equal(true);
expect(validator.makeInvalid.calledWith(el, errorMsg)).to.equal(true);
});
});
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
describe('validateForm', function () {
it('should return false it the form element is undefined', function () {
var result = validationManager.validateForm();
$rootScope.$apply();
expect(result).to.equal(false);
});
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
it('should return true it the form controller is set to not auto validate the form', function () {
var form = compileElement('<form role="form" novalidate="novalidate" ng-submit="submit();" disable-dynamic-validation><input ng-model="name" required /></form>', true),
result = validationManager.validateForm(form);
it('should call validator makeInvalid once when a single form input element is invalid', function () {
var frm = compileElement('<form name="frm1"></form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
isValid;
expect(result).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
it('should only validate elements on the parent and not disabled subform', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
subFrm = compileElement('<ng-form name="subFrm1" disable-dynamic-validation></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="surname" ng-minlength="2" />', true),
isValid;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
subFrm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('minlength', false);
frm.append(subFrm);
$rootScope.$apply();
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
$rootScope.$apply();
$rootScope.$apply();
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
it('should call validator makeInvalid twice when a single form input element is invalid', function () {
var frm = compileElement('<form name="frm1"></form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="name" ng-maxlength="2" />', true),
isValid;
it('should only validate elements on the parent and not disabled subform where the subform is via an attribute', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
subFrm = compileElement('<div ng-form name="subFrm1" disable-dynamic-validation></div>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="surname" ng-minlength="2" />', true),
isValid;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
frm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('maxlength', false);
inpt2.controller('ngModel').$pristine = false;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
subFrm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('minlength', false);
frm.append(subFrm);
$rootScope.$apply();
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
$rootScope.$apply();
$rootScope.$apply();
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledTwice).to.equal(true);
});
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
it('should call validator makeInvalid once when a single form input element is invalid in a child ng-form', function () {
var frm = compileElement('<form name="frm1"></form>', true),
ngFrm = compileElement('<ng-form name="childFrm"></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
isValid;
it('should call validator makeInvalid once when a single form input element is invalid', function () {
var frm = compileElement('<form name="frm1"></form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
isValid;
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
ngFrm.append(inpt);
frm.append(ngFrm);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
$rootScope.$apply();
$rootScope.$apply();
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
$rootScope.$apply();
it('should call validator makeInvalid once when a single form input element is invalid and the form is submitted', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
inpt = compileElement('<input type="text" ng-model="name" required="required" ng-minlength="2" />', true);
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
$rootScope.$apply();
it('should call validator makeInvalid twice when a single form input element is invalid', function () {
var frm = compileElement('<form name="frm1"></form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inpt2 = compileElement('<input type="text" ng-model="name" ng-maxlength="2" />', true),
isValid;
frm.on('submit', function (event) {
event.preventDefault();
});
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
frm.append(inpt2);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
inpt2.controller('ngModel').$setValidity('maxlength', false);
inpt2.controller('ngModel').$pristine = false;
$rootScope.$apply();
defer.resolve('errorMsg');
frm.trigger('submit');
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
$rootScope.$apply();
$rootScope.$apply();
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
});
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledTwice).to.equal(true);
});
describe('resetForm', function () {
it('should call validator.makeDefault for every input type element in the form', function () {
var frm = compileElement('<form name="frm1"><input type="text" ng-model="name" ng-minlength="2" /><input type="text" ng-model="lastname" ng-maxlength="2" /></form>', true);
sandbox.stub(validator, 'makeDefault');
it('should call validator makeInvalid once when a single form input element is invalid in a child ng-form', function () {
var frm = compileElement('<form name="frm1"></form>', true),
ngFrm = compileElement('<ng-form name="childFrm"></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
isValid;
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
ngFrm.append(inpt);
frm.append(ngFrm);
inpt.controller('ngModel').$setValidity('minlength', false);
inpt.controller('ngModel').$pristine = false;
$rootScope.$apply();
validationManager.resetForm(frm);
defer.resolve('errorMsg');
isValid = validationManager.validateForm(frm);
$rootScope.$apply();
$rootScope.$apply();
expect(validator.makeDefault.calledTwice).to.equal(true);
});
expect(isValid).to.equal(false);
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
it('should call validator makeDefault once when a single form input element is invalid in a child ng-form', function () {
var frm = compileElement('<form name="frm1"><ng-form name="childFrm"><input type="text" ng-model="name" ng-minlength="2" /></ng-form></form>', true);
sandbox.stub(validator, 'makeDefault');
it('should call validator makeInvalid once when a single form input element is invalid and the form is submitted', function () {
var frm = compileElement('<form name="frm1" ng-submit=""></form>', true),
inpt = compileElement('<input type="text" ng-model="name" required="required" ng-minlength="2" />', true);
$rootScope.$apply();
sandbox.stub(elementUtils, 'isElementVisible').returns(true);
frm.append(inpt);
$rootScope.$apply();
validationManager.resetForm(frm);
frm.on('submit', function (event) {
event.preventDefault();
});
$rootScope.$apply();
defer.resolve('errorMsg');
frm.trigger('submit');
expect(validator.makeDefault.calledOnce).to.equal(true);
});
$rootScope.$apply();
it('should set the model controller of the input element to pristine', function () {
var frm = compileElement('<form name="frm1"></form>', true),
ngFrm = compileElement('<ng-form name="childFrm"></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inptNgModelController = inpt.controller('ngModel');
expect(validator.makeInvalid.calledOnce).to.equal(true);
});
});
sandbox.stub(validator, 'makeDefault');
describe('resetForm', function () {
it('should call validator.makeDefault for every input type element in the form', function () {
var frm = compileElement('<form name="frm1"><input type="text" ng-model="name" ng-minlength="2" /><input type="text" ng-model="lastname" ng-maxlength="2" /></form>', true);
sandbox.stub(validator, 'makeDefault');
ngFrm.append(inpt);
frm.append(ngFrm);
$rootScope.$apply();
$rootScope.$apply();
inptNgModelController.$setViewValue('123');
$rootScope.$apply();
expect(inptNgModelController.$pristine).to.equal(false);
validationManager.resetForm(frm);
validationManager.resetForm(frm);
$rootScope.$apply();
$rootScope.$apply();
expect(validator.makeDefault.calledTwice).to.equal(true);
});
expect(inptNgModelController.$pristine).to.equal(true);
});
});
it('should call validator makeDefault once when a single form input element is invalid in a child ng-form', function () {
var frm = compileElement('<form name="frm1"><ng-form name="childFrm"><input type="text" ng-model="name" ng-minlength="2" /></ng-form></form>', true);
sandbox.stub(validator, 'makeDefault');
describe('resetElement', function () {
it('should call validator.makeDefault with the given element', function () {
var inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />');
$rootScope.$apply();
sandbox.stub(validator, 'makeDefault');
validationManager.resetForm(frm);
$rootScope.$apply();
$rootScope.$apply();
validationManager.resetElement(inpt);
expect(validator.makeDefault.calledOnce).to.equal(true);
});
$rootScope.$apply();
it('should set the model controller of the input element to pristine', function () {
var frm = compileElement('<form name="frm1"></form>', true),
ngFrm = compileElement('<ng-form name="childFrm"></ng-form>', true),
inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />', true),
inptNgModelController = inpt.controller('ngModel');
expect(validator.makeDefault.calledOnce).to.equal(true);
});
});
sandbox.stub(validator, 'makeDefault');
ngFrm.append(inpt);
frm.append(ngFrm);
$rootScope.$apply();
inptNgModelController.$setViewValue('123');
$rootScope.$apply();
expect(inptNgModelController.$pristine).to.equal(false);
validationManager.resetForm(frm);
$rootScope.$apply();
expect(inptNgModelController.$pristine).to.equal(true);
});
});
describe('resetElement', function () {
it('should call validator.makeDefault with the given element', function () {
var inpt = compileElement('<input type="text" ng-model="name" ng-minlength="2" />');
sandbox.stub(validator, 'makeDefault');
$rootScope.$apply();
validationManager.resetElement(inpt);
$rootScope.$apply();
expect(validator.makeDefault.calledOnce).to.equal(true);
});
});
});
});
}(angular, sinon));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet