From 3e1013a7ea137a6ab465ff269c88baefb53fe06e Mon Sep 17 00:00:00 2001 From: Steve Wasiura Date: Thu, 25 Jul 2013 11:44:36 -0400 Subject: [PATCH 1/4] add validator checkbox_group, plus utility for numeric range checkbox_group added validator to check a group of checkboxes, to ensure required number of checkboxes were checked, using range (1-2), min1, or max2, etc. lang added prefix & suffixes for checkbox_group renamed prefixes & suffixes used for length validation numericRangeCheck added utility function to evaluate value against allowed parameter. abstracted internal check in validate_length to use this util function instead of repeating functionality vaildate_length edited function to use new utility function numericRangeCheck --- form-validator/jquery.form-validator.js | 170 +++++++++++++++++++----- 1 file changed, 137 insertions(+), 33 deletions(-) diff --git a/form-validator/jquery.form-validator.js b/form-validator/jquery.form-validator.js index bdb5cf5..bbb5f16 100644 --- a/form-validator/jquery.form-validator.js +++ b/form-validator/jquery.form-validator.js @@ -386,7 +386,7 @@ * Short hand function that makes the validation setup require less code * @param config */ - $.setupForm = function(config) { + $.validatorLoad = function(config) { config = $.extend({ form : 'form', validateOnBlur : true, @@ -828,6 +828,35 @@ $(document).bind("ready", countCharacters); }, + /** + * Test numeric against allowed range + * + * @param $value int + * @param $rangeAllowed str; (1-2, min1, max2) + * @return array + */ + numericRangeCheck : function($value, $rangeAllowed) + { + // split by dash + var range = $.split($rangeAllowed, '-'); + // range ? + if (range.length == 2 && ($value < parseInt(range[0],10) || $value > parseInt(range[1],10) )) + { // value is out of range + return [ "out", range[0], range[1] ] ; + } + else if ($rangeAllowed.indexOf('min') === 0) // min + { // check if above min + var minQty = parseInt($rangeAllowed.substr(3),10); + if($value < minQty) { return [ "min", minQty ] ; } + } + else if ($rangeAllowed.indexOf('max') === 0) // max + { var maxQty = parseInt($rangeAllowed.substr(3),10); + if($value > maxQty) { return [ "max", maxQty ] ; } + } + else { return "ok"} // value is in allowed range + }, + + _numSuggestionElements : 0, _selectedSuggestion : null, _previousTypedVal : null, @@ -1043,11 +1072,10 @@ badTelephone : 'You have not given a correct phone number', badSecurityAnswer : 'You have not given a correct answer to the security question', badDate : 'You have not given a correct date', - tooLongStart : 'You have given an answer longer than ', - tooLongEnd : ' characters', - tooShortStart : 'You have given an answer shorter than ', - tooShortEnd : ' characters', - badLength : 'You have to give an answer between ', + lengthBadStart : 'You must give an answer between ', + lengthBadEnd : 'characters', + lengthTooLongStart : 'You have given an answer longer than ', + lengthTooShortStart : 'You have given an answer shorter than ', notConfirmed : 'Values could not be confirmed', badDomain : 'Incorrect domain value', badUrl : 'The answer you gave was not a correct URL', @@ -1061,7 +1089,13 @@ badAlphaNumeric : 'The answer you gave must contain only alphanumeric characters ', badAlphaNumericExtra: ' and ', wrongFileSize : 'The file you are trying to upload is too large', - wrongFileType : 'The file you are trying to upload is of wrong type' + wrongFileType : 'The file you are trying to upload is of wrong type', + groupCheckedRangeStart : 'Please choose between ', + groupCheckedTooFewStart : 'Please choose at least ', + groupCheckedTooManyStart : 'Please choose a maximum of ', + groupCheckedEnd : ' item(s)', + + _dummy--last-item-placeholder-without-comma : 0 } }; @@ -1198,39 +1232,39 @@ */ $.formUtils.addValidator({ name : 'length', - validate : function(value, $el, config, language) { - var len = $el.valAttr('length'); - if(len == undefined) { + validate : function(value, $el, config, lang) { + var lengthAllowed = $el.valAttr('length'); + if(lengthAllowed == undefined) { var elementType = $el.get(0).nodeName; alert('Please add attribute "data-validation-length" to '+elementType+' named '+$el.attr('name')); return true; } - var range = $.split(len, '-'); + // check if length is above min, below max, within range etc. + var lengthCheckResults = $.formUtils.numericRangeCheck(value.length, lengthAllowed) ; - // range - if(range.length == 2 && (value.length < parseInt(range[0],10) || value.length > parseInt(range[1],10))) { - this.errorMessage = language.badLength + len + language.tooLongEnd; - return false; - } - // min - else if(len.indexOf('min') === 0) { - var minLength = parseInt(len.substr(3),10); - if(minLength > value.length) { - this.errorMessage = language.tooShortStart + minLength + language.tooShortEnd; - return false; - } - } - // max - else if(len.indexOf('max') === 0) { - var maxLength = parseInt(len.substr(3),10); - if(maxLength < value.length) { - this.errorMessage = language.tooLongStart + maxLength + language.tooLongEnd; - return false; + switch(lengthCheckResults[0] ) + { // outside of allowed range + case "out": + this.errorMessage = lang.lengthBadStart + len + lang.lengthBadEnd; + checkResult = false; + break; + // too short + case "min": + this.errorMessage = lang.lengthTooShortStart + lengthCheckResults[1] + lang.lengthBadEnd; + checkResult = false; + break; + // too long + case "max": + this.errorMessage = lang.lengthTooLongStart + lengthCheckResults[1] + lang.lengthBadEnd; + checkResult = false; + break; + // ok + default: + checkResult = true; } - } - - return true; + + return checkResult; }, errorMessage : '', errorMessageKey: '' @@ -1349,4 +1383,74 @@ errorMessageKey: 'badDate' }); + +/* + * Validate group of checkboxes, validate qty required is checked + * written by Steve Wasiura : http://stevewasiura.waztech.com + * element attrs + * data-validation="checkbox_group" + * data-validation-qty="1-2" // min 1 max 2 + * data-validation-error-msg="chose min 1, max of 2 checkboxes" + */ + + /* formUtils global var to hold string of checkboxes that were prev checked by validator, + * to prevent wasted duplication when multiple checkboxes have call to same validator + */ + $.formUtils._checkboxGroups = ''; + + $.formUtils.addValidator({ + name : 'checkbox_group', + validate : function(val, $el, config, lang, form) + { // set return var + var checkResult = true; + // get name of element. since it is a checkbox group, all checkboxes will have same name + var elname = $el.attr('name'); + // check if we have already checked this group + // global var "_checkboxGroups" + // if element name is not found in global var, then do the check + if ($.formUtils._checkboxGroups.indexOf(elname) == -1 ) + { // get count of checked checkboxes with this name + var checkedCount = $("input[type=checkbox][name^='"+elname+"']:checked", form).length; + // get el attr that specs qty required / allowed + var qtyAllowed = $el.valAttr('qty'); + if (qtyAllowed == undefined) { + var elementType = $el.get(0).nodeName; + alert('Attribute "data-validation-qty" is missing from '+elementType+' named '+$el.attr('name')); + } + // call Utility function to check if count is above min, below max, within range etc. + var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed) ; + // results will be array, [0]=result str, [1]=qty int + switch(qtyCheckResults[0] ) + { // outside allowed range + case "out": + this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + lang.groupCheckedEnd; + checkResult = false; + break; + // below min qty + case "min": + this.errorMessage = lang.groupCheckedTooFewStart + qtyCheckResults[1] + lang.groupCheckedEnd; + checkResult = false; + break; + // above max qty + case "max": + this.errorMessage = lang.groupCheckedTooManyStart + qtyCheckResults[1] + lang.groupCheckedEnd; + checkResult = false; + break; + // ok + default: + checkResult = true; + } + + // add element name to global var so group won't be checked on subsequent calls + $.formUtils._checkboxGroups += elname + ', '; + } + + return checkResult; + + } // remove comma + // errorMessage : '', // set above in switch statement + // errorMessageKey: '' // not used + }); + + })(jQuery); From f637c62b0be6d84466b5abea0b9e30086f5426c2 Mon Sep 17 00:00:00 2001 From: Steve Wasiura Date: Thu, 25 Jul 2013 20:34:44 -0400 Subject: [PATCH 2/4] add new code descriptions for validator checkbox groups and variable name changes --- README.md | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3d414ec..b77c49b 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ So what has changed since version 1.x? * **length** — *min/max/range* * **required** — *no validation except that a value has to be given* * **custom** — *Validate value against regexp* + * **checkboxgroup** — *ensure at least 1 checkbox in group has been selected* * Show help information automatically when input is focused * Validate given values immediately when input looses focus. * Make validation optional by adding attribute data-validation-optional="true" to the element. This means @@ -135,7 +136,7 @@ that checks if the input contains an even number. // Add validator $.formUtils.addValidator({ name : 'even', - validate : function(value, $el, config, language, $form) { + validatorFunction : function(value, $el, config, language, $form) { return parseInt(value, 10) % 2 === 0; }, errorMessage : 'You have to answer an even number', @@ -152,7 +153,7 @@ that checks if the input contains an even number. *name* - The name of the validator, which is used in the validation attribute of the input element. -*validate* - Callback function that validates the input. Should return a boolean telling if the value is considered valid or not. +*validatorFunction* - Callback function that validates the input. Should return a boolean telling if the value is considered valid or not. *errorMessageKey* - Name of language property that is used in case the value of the input is invalid. @@ -228,11 +229,10 @@ var enErrorDialogs = { badTelephone : 'You have not given a correct phone number', badSecurityAnswer : 'You have not given a correct answer to the security question', badDate : 'You have not given a correct date', - tooLongStart : 'You have given an answer longer than ', - tooLongEnd : ' characters', - tooShortStart : 'You have given an answer shorter than ', - tooShortEnd : ' characters', - badLength : 'You have to give an answer between ', + lengthBadStart : 'You must give an answer between ', + lengthBadEnd : 'characters', + lengthTooLongStart : 'You have given an answer longer than ', + lengthTooShortStart : 'You have given an answer shorter than ', notConfirmed : 'Values could not be confirmed', badDomain : 'Incorrect domain value', badUrl : 'The answer you gave was not a correct URL', @@ -246,7 +246,14 @@ var enErrorDialogs = { badAlphaNumeric : 'The answer you gave must contain only alphanumeric characters ', badAlphaNumericExtra: ' and ', wrongFileSize : 'The file you are trying to upload is too large', - wrongFileType : 'The file you are trying to upload is of wrong type' + wrongFileType : 'The file you are trying to upload is of wrong type', + groupCheckedTooFewStart : 'Please choose at least ', + groupCheckedTooManyStart : 'Please choose a maximum of ', + groupCheckedRangeStart : 'Please choose between ', + groupCheckedEnd : ' item(s)', + + _dummy--last-item-no-comma : 0 + }; ``` @@ -279,6 +286,17 @@ that attribute will be displayed instead of the error dialog that the validation ``` +## Program Flow +form submit() event is bound to jQ func **validateForm()** + +when the form is submitted, it calls jQ func **$.formUtils.validateInput**, which calls **validatorFunction** for the specific validation rule assigned to the input element + +if a validation fails, error messages are assigned and displayed as configured. + + +if **validateOnBlur** = true, jQ finds all form input elements with the data-validation attribute and binds their onBlur event to call the function **validateInputOnBlur**. it calls jQ func **$.formUtils.validateInput** to validate the single input when blurred + + ## Changelog #### 2.0.7 @@ -303,7 +321,7 @@ that attribute will be displayed instead of the error dialog that the validation #### Contributors Joel Sutherland
-Steve Wasiura
+Steve Wasiura
Matt Clements
@dfcplc
Andree Wendel
@@ -317,3 +335,4 @@ that attribute will be displayed instead of the error dialog that the validation Scott Gonzales (URL regexp)
Darren Mason (Password strength meter) +Steve Wasiura (Checkbox group) From d415c7d41e2177c5987f89ad5710595aaef09b2e Mon Sep 17 00:00:00 2001 From: Steve Wasiura Date: Thu, 25 Jul 2013 20:55:43 -0400 Subject: [PATCH 3/4] input field selector onblur, name changes jQ selector of form inputs for onBlur, only select input that have attribute "data-validation", this skips form elements with no validation, including submits, buttons, and reset i was going crazy debugging this when every function was named validate, dovalidate, validateInput, etc. so i renamed them based on what they did. thanks --- form-validator/jquery.form-validator.js | 55 +++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/form-validator/jquery.form-validator.js b/form-validator/jquery.form-validator.js index bbb5f16..39d1eea 100644 --- a/form-validator/jquery.form-validator.js +++ b/form-validator/jquery.form-validator.js @@ -12,22 +12,23 @@ 'use strict'; /** - * Should be called on the element containing the input elements + * Assigns validateInputOnBlur function to elements blur event * * @param {Object} language Optional, will override $.formUtils.LANG * @param {Object} settings Optional, will override the default settings * @return {jQuery} */ $.fn.validateOnBlur = function(language, settings) { - this.find('textarea,input').blur(function() { - $(this).doValidate(language, settings); + this.find('input[data-validation], textarea[data-validation]') + .blur(function() { + $(this).validateInputOnBlur(language, settings); }); - return this; }; /** - * Should be called on the element containing the input elements. + * fade in help message when input gains focus + * fade out when input loses focus * * * @param {String} attrName - Optional, default is data-help @@ -71,16 +72,16 @@ }; /** - * Function that validates the value of given input and shows - * error message in a span element that is appended to the parent - * element + * Validate single input when it loses focus + * shows error message in a span element + * that is appended to the parent element * * @param {Object} [language] Optional, will override $.formUtils.LANG * @param {Object} [config] Optional, will override the default settings * @param {Boolean} [attachKeyupEvent] Optional * @return {jQuery} */ - $.fn.doValidate = function(language, config, attachKeyupEvent) { + $.fn.validateInputOnBlur = function(language, config, attachKeyupEvent) { if(attachKeyupEvent === undefined) { attachKeyupEvent = true; } @@ -143,7 +144,7 @@ if(attachKeyupEvent) { $element.bind('keyup', function() { - $(this).doValidate(language, config, false); + $(this).validateInputOnBlur(language, config, false); }); } } @@ -177,7 +178,7 @@ * @param [language] * @param [config] */ - $.fn.validate = function(language, config) { + $.fn.validateForm = function(language, config) { language = $.extend($.formUtils.LANG, language || {}); config = $.extend($.formUtils.defaultConfig(), config || {}); @@ -410,7 +411,7 @@ }, 200); return false; } - var valid = $(this).validate(config.language, config); + var valid = $(this).validateForm(config.language, config); if( valid && typeof config.onSuccess == 'function') { var callbackResponse = config.onSuccess($form); if( callbackResponse === false ) @@ -450,7 +451,7 @@ $.formUtils = { /** - * Default config for $(...).validate(); + * Default config for $(...).validateForm(); */ defaultConfig : function() { return { @@ -695,9 +696,9 @@ var validator = $.formUtils.validators[rule]; - if( validator && typeof validator['validate'] == 'function' ) { + if( validator && typeof validator['validatorFunction'] == 'function' ) { - var isValid = validator.validate(value, $element, config, language, $form); + var isValid = validator.validatorFunction(value, $element, config, language, $form); if(!isValid) { validationErrorMsg = $element.attr(config.validationErrorMsgAttribute); @@ -1110,12 +1111,12 @@ */ $.formUtils.addValidator({ name : 'email', - validate : function(email) { + validatorFunction : function(email) { var emailFilter = /^([a-zA-Z0-9_\.\-])+@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; if(emailFilter.test(email)) { var parts = email.split('@'); if(parts.length == 2) { - return $.formUtils.validators.validate_domain.validate(parts[1]); + return $.formUtils.validators.validate_domain.validatorFunction(parts[1]); } } return false; @@ -1129,7 +1130,7 @@ */ $.formUtils.addValidator({ name : 'domain', - validate : function(val, $input) { + validatorFunction : function(val, $input) { var topDomains = ['.com', '.net', '.org', '.biz', '.coop', '.info', '.museum', '.name', '.pro', '.edu', '.gov', '.int', '.mil', '.ac', '.ad', '.ae', '.af', '.ag', '.ai', '.al', @@ -1220,7 +1221,7 @@ */ $.formUtils.addValidator({ name : 'required', - validate : function(val, $el) { + validatorFunction : function(val, $el) { return $el.attr('type') == 'checkbox' ? $el.is(':checked') : $.trim(val) !== ''; }, errorMessage : '', @@ -1232,7 +1233,7 @@ */ $.formUtils.addValidator({ name : 'length', - validate : function(value, $el, config, lang) { + validatorFunction : function(value, $el, config, lang) { var lengthAllowed = $el.valAttr('length'); if(lengthAllowed == undefined) { var elementType = $el.get(0).nodeName; @@ -1275,7 +1276,7 @@ */ $.formUtils.addValidator({ name : 'url', - validate : function(url) { + validatorFunction : function(url) { // written by Scott Gonzalez: http://projects.scottsplayground.com/iri/ but added support for arrays in the url ?arg[]=sdfsdf var urlFilter = /^(https|http|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; if( urlFilter.test(url) ) { @@ -1284,7 +1285,7 @@ if(domainSlashPos > -1) domain = domain.substr(0, domainSlashPos); - return $.formUtils.validators.validate_domain.validate(domain); // todo: add support for IP-addresses + return $.formUtils.validators.validate_domain.validatorFunction(domain); // todo: add support for IP-addresses } return false; }, @@ -1297,7 +1298,7 @@ */ $.formUtils.addValidator({ name : 'number', - validate : function(val, $el) { + validatorFunction : function(val, $el) { if(val !== '') { var allowing = $el.valAttr('allowing') || ''; if(allowing.indexOf('number') == -1) @@ -1325,7 +1326,7 @@ */ $.formUtils.addValidator({ name : 'alphanumeric', - validate : function(val, $el, config, language) { + validatorFunction : function(val, $el, config, language) { var patternStart = '^([a-zA-Z0-9', patternEnd = ']+)$', additionalChars = $el.attr('data-validation-allowing'), @@ -1355,7 +1356,7 @@ */ $.formUtils.addValidator({ name : 'custom', - validate : function(val, $el, config) { + validatorFunction : function(val, $el, config) { var regexp = new RegExp($el.valAttr('regexp')); return regexp.test(val); }, @@ -1368,7 +1369,7 @@ */ $.formUtils.addValidator({ name : 'date', - validate : function(date, $el, conf) { + validatorFunction : function(date, $el, conf) { var dateFormat = 'yyyy-mm-dd'; if($el.valAttr('format')) { dateFormat = $el.valAttr('format'); @@ -1400,7 +1401,7 @@ $.formUtils.addValidator({ name : 'checkbox_group', - validate : function(val, $el, config, lang, form) + validatorFunction : function(val, $el, config, lang, form) { // set return var var checkResult = true; // get name of element. since it is a checkbox group, all checkboxes will have same name From 6400635c3a05b9963495a441e2bfe1c9fb318129 Mon Sep 17 00:00:00 2001 From: Steve Wasiura Date: Fri, 26 Jul 2013 01:42:32 -0400 Subject: [PATCH 4/4] bug fix numericRangeCheck, bug fix checkbox_group numericRangeCheck had bug in conditional structure; fixed. checkbox_group had bug when checking checkboxes in same group. added special test in validateInput() function, to force element to be first input element in group, so error msg only output once. also changed .append back to .text to support this case. --- form-validator/jquery.form-validator.js | 111 +++++++++++------------- 1 file changed, 49 insertions(+), 62 deletions(-) diff --git a/form-validator/jquery.form-validator.js b/form-validator/jquery.form-validator.js index 39d1eea..d5660bb 100644 --- a/form-validator/jquery.form-validator.js +++ b/form-validator/jquery.form-validator.js @@ -312,7 +312,7 @@ var $parent = $input.parent(), $errorSpan = $parent.find('span[class='+config.errorMessageClass+']'); if ($errorSpan.length > 0) { - $errorSpan.append(', '+$input.valAttr('current-error')); + $errorSpan.text(', '+$input.valAttr('current-error')); } else { $parent.append('' + $input.valAttr('current-error') + ''); } @@ -697,6 +697,11 @@ var validator = $.formUtils.validators[rule]; if( validator && typeof validator['validatorFunction'] == 'function' ) { + // special change of element for checkbox_group rule + if ( rule == 'validate_checkbox_group' ) { + // set element to first in group, so error msg is set only once + $element = $("[name='"+$element.attr('name')+"']:eq(0)"); + } var isValid = validator.validatorFunction(value, $element, config, language, $form); @@ -836,25 +841,20 @@ * @param $rangeAllowed str; (1-2, min1, max2) * @return array */ - numericRangeCheck : function($value, $rangeAllowed) + numericRangeCheck : function(value, rangeAllowed) { // split by dash - var range = $.split($rangeAllowed, '-'); + var range = $.split(rangeAllowed, '-'); + // min or max + var minmax = parseInt(rangeAllowed.substr(3),10) // range ? - if (range.length == 2 && ($value < parseInt(range[0],10) || $value > parseInt(range[1],10) )) - { // value is out of range - return [ "out", range[0], range[1] ] ; - } - else if ($rangeAllowed.indexOf('min') === 0) // min - { // check if above min - var minQty = parseInt($rangeAllowed.substr(3),10); - if($value < minQty) { return [ "min", minQty ] ; } - } - else if ($rangeAllowed.indexOf('max') === 0) // max - { var maxQty = parseInt($rangeAllowed.substr(3),10); - if($value > maxQty) { return [ "max", maxQty ] ; } - } - else { return "ok"} // value is in allowed range + if (range.length == 2 && (value < parseInt(range[0],10) || value > parseInt(range[1],10) ) ) + { return [ "out", range[0], range[1] ] ; } // value is out of range + else if (rangeAllowed.indexOf('min') === 0 && (value < minmax ) ) // min + { return ["min", minmax]; } // value is below min + else if (rangeAllowed.indexOf('max') === 0 && (value > minmax ) ) // max + { return ["max", minmax]; } // value is above max + else { return [ "ok" ] ; } // value is in allowed range }, @@ -1394,56 +1394,43 @@ * data-validation-error-msg="chose min 1, max of 2 checkboxes" */ - /* formUtils global var to hold string of checkboxes that were prev checked by validator, - * to prevent wasted duplication when multiple checkboxes have call to same validator - */ - $.formUtils._checkboxGroups = ''; - $.formUtils.addValidator({ name : 'checkbox_group', - validatorFunction : function(val, $el, config, lang, form) - { // set return var + validatorFunction : function(val, $el, config, lang, $form) + { // preset return var var checkResult = true; // get name of element. since it is a checkbox group, all checkboxes will have same name var elname = $el.attr('name'); - // check if we have already checked this group - // global var "_checkboxGroups" - // if element name is not found in global var, then do the check - if ($.formUtils._checkboxGroups.indexOf(elname) == -1 ) - { // get count of checked checkboxes with this name - var checkedCount = $("input[type=checkbox][name^='"+elname+"']:checked", form).length; - // get el attr that specs qty required / allowed - var qtyAllowed = $el.valAttr('qty'); - if (qtyAllowed == undefined) { - var elementType = $el.get(0).nodeName; - alert('Attribute "data-validation-qty" is missing from '+elementType+' named '+$el.attr('name')); - } - // call Utility function to check if count is above min, below max, within range etc. - var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed) ; - // results will be array, [0]=result str, [1]=qty int - switch(qtyCheckResults[0] ) - { // outside allowed range - case "out": - this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + lang.groupCheckedEnd; - checkResult = false; - break; - // below min qty - case "min": - this.errorMessage = lang.groupCheckedTooFewStart + qtyCheckResults[1] + lang.groupCheckedEnd; - checkResult = false; - break; - // above max qty - case "max": - this.errorMessage = lang.groupCheckedTooManyStart + qtyCheckResults[1] + lang.groupCheckedEnd; - checkResult = false; - break; - // ok - default: - checkResult = true; - } - - // add element name to global var so group won't be checked on subsequent calls - $.formUtils._checkboxGroups += elname + ', '; + // get count of checked checkboxes with this name + var checkedCount = $("input[type=checkbox][name^='"+elname+"']:checked", $form).length; + // get el attr that specs qty required / allowed + var qtyAllowed = $el.valAttr('qty'); + if (qtyAllowed == undefined) { + var elementType = $el.get(0).nodeName; + alert('Attribute "data-validation-qty" is missing from '+elementType+' named '+$el.attr('name')); + } + // call Utility function to check if count is above min, below max, within range etc. + var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed) ; + // results will be array, [0]=result str, [1]=qty int + switch(qtyCheckResults[0] ) { + // outside allowed range + case "out": + this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + lang.groupCheckedEnd; + checkResult = false; + break; + // below min qty + case "min": + this.errorMessage = lang.groupCheckedTooFewStart + qtyCheckResults[1] + lang.groupCheckedEnd; + checkResult = false; + break; + // above max qty + case "max": + this.errorMessage = lang.groupCheckedTooManyStart + qtyCheckResults[1] + lang.groupCheckedEnd; + checkResult = false; + break; + // ok + default: + checkResult = true; } return checkResult;