From f488903d8eadd211eb6677cd96ba3f6d4ebb9d44 Mon Sep 17 00:00:00 2001 From: Murillo Date: Fri, 15 Aug 2014 12:14:43 -0300 Subject: [PATCH 1/4] update Control-group to form-group bootstrap 3 --- dist/jqBootstrapValidation-1.3.7.js | 12 ++++++------ dist/jqBootstrapValidation-1.3.7.min.js | 2 +- src/jqBootstrapValidation.js | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dist/jqBootstrapValidation-1.3.7.js b/dist/jqBootstrapValidation-1.3.7.js index 3944a41..918a0c0 100644 --- a/dist/jqBootstrapValidation-1.3.7.js +++ b/dist/jqBootstrapValidation-1.3.7.js @@ -44,7 +44,7 @@ var warningsFound = 0; // Get all inputs var $allInputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); - var $allControlGroups = $form.find(".control-group"); + var $allControlGroups = $form.find(".form-group"); // Only trigger validation on the ones that actually _have_ validation var $inputsWithValidators = $allInputs.filter(function () { @@ -89,7 +89,7 @@ // Get references to everything we're interested in var $this = $(this), - $controlGroup = $this.parents(".control-group").first(), + $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(), $form = $this.parents("form").first(), validatorNames = []; @@ -599,7 +599,7 @@ var $this = $(this), - $controlGroup = $this.parents(".control-group").first(), + $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(), $form = $this.parents("form").first(); @@ -865,7 +865,7 @@ var $label = null; if (($label = $form.find("label[for=\"" + elementName + "\"]")).length) { message += " '" + $label.text() + "'"; - } else if (($label = $element.parents(".control-group").first().find("label")).length) { + } else if (($label = $element.parents(".form-group").first().find("label")).length) { message += " '" + $label.first().text() + "'"; } @@ -1147,14 +1147,14 @@ var type = $this.attr("type"); if (type === "checkbox") { value = ($this.is(":checked") ? value : ""); - var checkboxParent = $this.parents("form").first() || $this.parents(".control-group").first(); + var checkboxParent = $this.parents("form").first() || $this.parents(".form-group").first(); if (checkboxParent) { value = checkboxParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); }).toArray().join(","); } } else if (type === "radio") { value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? $this.val() : ""); - var radioParent = $this.parents("form").first() || $this.parents(".control-group").first(); + var radioParent = $this.parents("form").first() || $this.parents(".form-group").first(); if (radioParent) { value = radioParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); }).toArray().join(","); } diff --git a/dist/jqBootstrapValidation-1.3.7.min.js b/dist/jqBootstrapValidation-1.3.7.min.js index c5d5236..b9a7f85 100644 --- a/dist/jqBootstrapValidation-1.3.7.min.js +++ b/dist/jqBootstrapValidation-1.3.7.min.js @@ -1,4 +1,4 @@ /*! jqBootstrapValidation - v1.3.7 - 2013-05-07 * http://reactiveraven.github.com/jqBootstrapValidation * Copyright (c) 2013 David Godfrey; Licensed MIT */ -(function(e){function s(e){return new RegExp("^"+e+"$")}function o(e,t){var n=Array.prototype.slice.call(arguments,2),r=e.split("."),i=r.pop();for(var s=0;s0});u.trigger("submit.validation"),i.trigger("validationLostFocus.validation"),s.each(function(t,n){var i=e(n);if(i.hasClass("warning")||i.hasClass("error"))i.removeClass("warning").addClass("error"),r++}),r?(o.options.preventSubmit&&(t.preventDefault(),t.stopImmediatePropagation()),n.addClass("error"),e.isFunction(o.options.submitError)&&o.options.submitError(n,t,u.jqBootstrapValidation("collectErrors",!0))):(n.removeClass("error"),e.isFunction(o.options.submitSuccess)&&o.options.submitSuccess(n,t))}),this.each(function(){var n=e(this),s=n.parents(".control-group").first(),u=s.find(".help-block").first(),a=n.parents("form").first(),f=[];!u.length&&o.options.autoAdd&&o.options.autoAdd.helpBlocks&&(u=e('
'),s.find(".controls").append(u),t.push(u[0]));if(o.options.sniffHtml){var l;n.data("validationPatternPattern")&&n.attr("pattern",n.data("validationPatternPattern")),n.attr("pattern")!==undefined&&(l="Not in the expected format",n.data("validationPatternMessage")&&(l=n.data("validationPatternMessage")),n.data("validationPatternMessage",l),n.data("validationPatternRegex",n.attr("pattern")));if(n.attr("max")!==undefined||n.attr("aria-valuemax")!==undefined){var c=n.attr("max")!==undefined?n.attr("max"):n.attr("aria-valuemax");l="Too high: Maximum of '"+c+"'",n.data("validationMaxMessage")&&(l=n.data("validationMaxMessage")),n.data("validationMaxMessage",l),n.data("validationMaxMax",c)}if(n.attr("min")!==undefined||n.attr("aria-valuemin")!==undefined){var h=n.attr("min")!==undefined?n.attr("min"):n.attr("aria-valuemin");l="Too low: Minimum of '"+h+"'",n.data("validationMinMessage")&&(l=n.data("validationMinMessage")),n.data("validationMinMessage",l),n.data("validationMinMin",h)}n.attr("maxlength")!==undefined&&(l="Too long: Maximum of '"+n.attr("maxlength")+"' characters",n.data("validationMaxlengthMessage")&&(l=n.data("validationMaxlengthMessage")),n.data("validationMaxlengthMessage",l),n.data("validationMaxlengthMaxlength",n.attr("maxlength"))),n.attr("minlength")!==undefined&&(l="Too short: Minimum of '"+n.attr("minlength")+"' characters",n.data("validationMinlengthMessage")&&(l=n.data("validationMinlengthMessage")),n.data("validationMinlengthMessage",l),n.data("validationMinlengthMinlength",n.attr("minlength")));if(n.attr("required")!==undefined||n.attr("aria-required")!==undefined)l=o.builtInValidators.required.message,n.data("validationRequiredMessage")&&(l=n.data("validationRequiredMessage")),n.data("validationRequiredMessage",l);if(n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="number"){l=o.validatorTypes.number.message,n.data("validationNumberMessage")&&(l=n.data("validationNumberMessage")),n.data("validationNumberMessage",l);var p=o.validatorTypes.number.step;n.data("validationNumberStep")&&(p=n.data("validationNumberStep")),n.data("validationNumberStep",p);var d=o.validatorTypes.number.decimal;n.data("validationNumberDecimal")&&(d=n.data("validationNumberDecimal")),n.data("validationNumberDecimal",d)}n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="email"&&(l="Not a valid email address",n.data("validationEmailMessage")&&(l=n.data("validationEmailMessage")),n.data("validationEmailMessage",l)),n.attr("minchecked")!==undefined&&(l="Not enough options checked; Minimum of '"+n.attr("minchecked")+"' required",n.data("validationMincheckedMessage")&&(l=n.data("validationMincheckedMessage")),n.data("validationMincheckedMessage",l),n.data("validationMincheckedMinchecked",n.attr("minchecked"))),n.attr("maxchecked")!==undefined&&(l="Too many options checked; Maximum of '"+n.attr("maxchecked")+"' required",n.data("validationMaxcheckedMessage")&&(l=n.data("validationMaxcheckedMessage")),n.data("validationMaxcheckedMessage",l),n.data("validationMaxcheckedMaxchecked",n.attr("maxchecked")))}n.data("validation")!==undefined&&(f=n.data("validation").split(",")),e.each(n.data(),function(e,t){var n=e.replace(/([A-Z])/g,",$1").split(",");n[0]==="validation"&&n[1]&&f.push(n[1])});var v=f,m=[],g=function(e,t){f[e]=r(t)},y=function(t,i){if(n.data("validation"+i+"Shortcut")!==undefined)e.each(n.data("validation"+i+"Shortcut").split(","),function(e,t){m.push(t)});else if(o.builtInValidators[i.toLowerCase()]){var s=o.builtInValidators[i.toLowerCase()];s.type.toLowerCase()==="shortcut"&&e.each(s.shortcut.split(","),function(e,t){t=r(t),m.push(t),f.push(t)})}};do e.each(f,g),f=e.unique(f),m=[],e.each(v,y),v=m;while(v.length>0);var b={};e.each(f,function(t,i){var s=n.data("validation"+i+"Message"),u=!!s,a=!1;s||(s="'"+i+"' validation failed "),e.each(o.validatorTypes,function(t,o){b[t]===undefined&&(b[t]=[]);if(!a&&n.data("validation"+i+r(o.name))!==undefined){var f=o.init(n,i);u&&(f.message=s),b[t].push(e.extend(!0,{name:r(o.name),message:s},f)),a=!0}});if(!a&&o.builtInValidators[i.toLowerCase()]){var f=e.extend(!0,{},o.builtInValidators[i.toLowerCase()]);u&&(f.message=s);var l=f.type.toLowerCase();l==="shortcut"?a=!0:e.each(o.validatorTypes,function(t,s){b[t]===undefined&&(b[t]=[]),!a&&l===t.toLowerCase()&&(n.data("validation"+i+r(s.name),f[s.name.toLowerCase()]),b[l].push(e.extend(f,s.init(n,i))),a=!0)})}a||e.error("Cannot find validation info for '"+i+"'")}),u.data("original-contents",u.data("original-contents")?u.data("original-contents"):u.html()),u.data("original-role",u.data("original-role")?u.data("original-role"):u.attr("role")),s.data("original-classes",s.data("original-clases")?s.data("original-classes"):s.attr("class")),n.data("original-aria-invalid",n.data("original-aria-invalid")?n.data("original-aria-invalid"):n.attr("aria-invalid")),n.bind("validation.validation",function(t,r){var s=i(n),u=[];return e.each(b,function(t,i){(s||s.length||r&&r.includeEmpty||!!o.validatorTypes[t].includeEmpty||!!o.validatorTypes[t].blockSubmit&&r&&!!r.submitting)&&e.each(i,function(e,r){o.validatorTypes[t].validate(n,s,r)&&u.push(r.message)})}),u}),n.bind("getValidators.validation",function(){return b});var w=0;e.each(b,function(e,t){w+=t.length}),n.bind("getValidatorCount.validation",function(){return w}),n.bind("submit.validation",function(){return n.triggerHandler("change.validation",{submitting:!0})}),n.bind((o.options.bindEvents.length>0?o.options.bindEvents:["keyup","focus","blur","click","keydown","keypress","change"]).concat(["revalidate"]).join(".validation ")+".validation",function(t,r){var f=i(n),l=[];r&&!!r.submitting?s.data("jqbvIsSubmitting",!0):t.type!=="revalidate"&&s.data("jqbvIsSubmitting",!1);var c=!!s.data("jqbvIsSubmitting");s.find("input,textarea,select").each(function(t,i){var s=l.length;e.each(e(i).triggerHandler("validation.validation",r),function(e,t){l.push(t)});if(l.length>s)e(i).attr("aria-invalid","true");else{var o=n.data("original-aria-invalid");e(i).attr("aria-invalid",o!==undefined?o:!1)}}),a.find("input,select,textarea").not(n).not('[name="'+n.attr("name")+'"]').trigger("validationLostFocus.validation"),l=e.unique(l.sort()),l.length?(s.removeClass("success error warning").addClass(c?"error":"warning"),o.options.semanticallyStrict&&l.length===1?u.html(l[0]+(o.options.prependExistingHelpBlock?u.data("original-contents"):"")):u.html('
  • '+l.join("
  • ")+"
"+(o.options.prependExistingHelpBlock?u.data("original-contents"):""))):(s.removeClass("warning error success"),f.length>0&&s.addClass("success"),u.html(u.data("original-contents"))),t.type==="blur"&&s.removeClass("success")}),n.bind("validationLostFocus.validation",function(){s.removeClass("success")})})},destroy:function(){return this.each(function(){var n=e(this),r=n.parents(".control-group").first(),i=r.find(".help-block").first(),s=n.parents("form").first();n.unbind(".validation"),s.unbind(".validationSubmit"),i.html(i.data("original-contents")),r.attr("class",r.data("original-classes")),n.attr("aria-invalid",n.data("original-aria-invalid")),i.attr("role",n.data("original-role")),e.inArray(i[0],t)>-1&&i.remove()})},collectErrors:function(t){var n={};return this.each(function(t,r){var i=e(r),s=i.attr("name"),o=i.triggerHandler("validation.validation",{includeEmpty:!0});n[s]=e.extend(!0,o,n[s])}),e.each(n,function(e,t){t.length===0&&delete n[e]}),n},hasErrors:function(){var t=[];return this.find("input,select,textarea").add(this).each(function(n,r){t=t.concat(e(r).triggerHandler("getValidators.validation")?e(r).triggerHandler("validation.validation",{submitting:!0}):[])}),t.length>0},override:function(t){n=e.extend(!0,n,t)}},validatorTypes:{callback:{name:"callback",init:function(e,t){var n={validatorName:t,callback:e.data("validation"+t+"Callback"),lastValue:e.val(),lastValid:!0,lastFinished:!0},r="Not valid";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n},validate:function(e,t,n){if(n.lastValue===t&&n.lastFinished)return!n.lastValid;if(n.lastFinished===!0){n.lastValue=t,n.lastValid=!0,n.lastFinished=!1;var r=n,i=e;o(n.callback,window,e,t,function(t){r.lastValue===t.value&&(r.lastValid=t.valid,t.message&&(r.message=t.message),r.lastFinished=!0,i.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){!e.is(":focus")&&e.parents("form").first().data("jqbvIsSubmitting")?i.trigger("blur.validation"):i.trigger("revalidate.validation")},1))})}return!1}},ajax:{name:"ajax",init:function(e,t){return{validatorName:t,url:e.data("validation"+t+"Ajax"),lastValue:e.val(),lastValid:!0,lastFinished:!0}},validate:function(t,n,r){return""+r.lastValue==""+n&&r.lastFinished===!0?r.lastValid===!1:(r.lastFinished===!0&&(r.lastValue=n,r.lastValid=!0,r.lastFinished=!1,e.ajax({url:r.url,data:"value="+encodeURIComponent(n)+"&field="+t.attr("name"),dataType:"json",success:function(e){""+r.lastValue==""+e.value&&(r.lastValid=!!e.valid,e.message&&(r.message=e.message),r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1))},failure:function(){r.lastValid=!0,r.message="ajax call failed",r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1)}})),!1)}},regex:{name:"regex",init:function(t,n){var r={},i=t.data("validation"+n+"Regex");r.regex=s(i),i===undefined&&e.error("Can't find regex for '"+n+"' validator on '"+t.attr("name")+"'");var o="Not in the expected format";return t.data("validation"+n+"Message")&&(o=t.data("validation"+n+"Message")),r.message=o,r.originalName=n,r},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},email:{name:"email",init:function(e,t){var n={};n.regex=s("[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");var r="Not a valid email address";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n.originalName=t,n},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},required:{name:"required",init:function(e,t){var n="This is required";return e.data("validation"+t+"Message")&&(n=e.data("validation"+t+"Message")),{message:n,includeEmpty:!0}},validate:function(e,t,n){return!!(t.length===0&&!n.negative||t.length>0&&n.negative)},blockSubmit:!0},match:{name:"match",init:function(t,n){var r=t.data("validation"+n+"Match"),i=t.parents("form").first(),s=i.find('[name="'+r+'"]').first();s.bind("validation.validation",function(){t.trigger("revalidate.validation",{submitting:!0})});var o={};o.element=s,s.length===0&&e.error("Can't find field '"+r+"' to match '"+t.attr("name")+"' against in '"+n+"' validator");var u="Must match",a=null;return(a=i.find('label[for="'+r+'"]')).length?u+=" '"+a.text()+"'":(a=s.parents(".control-group").first().find("label")).length&&(u+=" '"+a.first().text()+"'"),t.data("validation"+n+"Message")&&(u=t.data("validation"+n+"Message")),o.message=u,o},validate:function(e,t,n){return t!==n.element.val()&&!n.negative||t===n.element.val()&&n.negative},blockSubmit:!0,includeEmpty:!0},max:{name:"max",init:function(e,t){var n={};return n.max=e.data("validation"+t+"Max"),n.message="Too high: Maximum of '"+n.max+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t,10)>parseFloat(n.max,10)&&!n.negative||parseFloat(t,10)<=parseFloat(n.max,10)&&n.negative}},min:{name:"min",init:function(e,t){var n={};return n.min=e.data("validation"+t+"Min"),n.message="Too low: Minimum of '"+n.min+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t)=parseFloat(n.min)&&n.negative}},maxlength:{name:"maxlength",init:function(e,t){var n={};return n.maxlength=e.data("validation"+t+"Maxlength"),n.message="Too long: Maximum of '"+n.maxlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length>n.maxlength&&!n.negative||t.length<=n.maxlength&&n.negative}},minlength:{name:"minlength",init:function(e,t){var n={};return n.minlength=e.data("validation"+t+"Minlength"),n.message="Too short: Minimum of '"+n.minlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length=n.minlength&&n.negative}},maxchecked:{name:"maxchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.maxchecked=e.data("validation"+t+"Maxchecked");var i="Too many: Max '"+n.maxchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length>n.maxchecked&&!n.negative||n.elements.filter(":checked").length<=n.maxchecked&&n.negative},blockSubmit:!0},minchecked:{name:"minchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.minchecked=e.data("validation"+t+"Minchecked");var i="Too few: Min '"+n.minchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length=n.minchecked&&n.negative},blockSubmit:!0,includeEmpty:!0},number:{name:"number",init:function(e,t){var n={};n.step=1,e.attr("step")&&(n.step=e.attr("step")),e.data("validation"+t+"Step")&&(n.step=e.data("validation"+t+"Step")),n.decimal=".",e.data("validation"+t+"Decimal")&&(n.decimal=e.data("validation"+t+"Decimal")),n.thousands="",e.data("validation"+t+"Thousands")&&(n.thousands=e.data("validation"+t+"Thousands")),n.regex=s("([+-]?\\d+(\\"+n.decimal+"\\d+)?)?"),n.message="Must be a number";var r=e.data("validation"+t+"Message");return r&&(n.message=r),n},validate:function(e,t,n){var r=t.replace(n.decimal,".").replace(n.thousands,""),i=parseFloat(r),s=parseFloat(n.step);while(s%1!==0)s=parseFloat(s.toPrecision(12))*10,i=parseFloat(i.toPrecision(12))*10;var o=n.regex.test(t),u=parseFloat(i)%parseFloat(s)===0,a=!isNaN(parseFloat(r))&&isFinite(r),f=!(o&&u&&a);return f},message:"Must be a number"}},builtInValidators:{email:{name:"Email",type:"email"},passwordagain:{name:"Passwordagain",type:"match",match:"password",message:"Does not match the given password"},positive:{name:"Positive",type:"shortcut",shortcut:"number,positivenumber"},negative:{name:"Negative",type:"shortcut",shortcut:"number,negativenumber"},integer:{name:"Integer",type:"regex",regex:"[+-]?\\d+",message:"No decimal places allowed"},positivenumber:{name:"Positivenumber",type:"min",min:0,message:"Must be a positive number"},negativenumber:{name:"Negativenumber",type:"max",max:0,message:"Must be a negative number"},required:{name:"Required",type:"required",message:"This is required"},checkone:{name:"Checkone",type:"minchecked",minchecked:1,message:"Check at least one option"},number:{name:"Number",type:"number",decimal:".",step:"1"},pattern:{name:"Pattern",type:"regex",message:"Not in expected format"}}},r=function(e){return e.toLowerCase().replace(/(^|\s)([a-z])/g,function(e,t,n){return t+n.toUpperCase()})},i=function(t){var n=null,r=t.attr("type");if(r==="checkbox"){n=t.is(":checked")?n:"";var i=t.parents("form").first()||t.parents(".control-group").first();i&&(n=i.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else if(r==="radio"){n=e('input[name="'+t.attr("name")+'"]:checked').length>0?t.val():"";var s=t.parents("form").first()||t.parents(".control-group").first();s&&(n=s.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else n=t.val();return n};e.fn.jqBootstrapValidation=function(t){return n.methods[t]?n.methods[t].apply(this,Array.prototype.slice.call(arguments,1)):typeof t=="object"||!t?n.methods.init.apply(this,arguments):(e.error("Method "+t+" does not exist on jQuery.jqBootstrapValidation"),null)},e.jqBootstrapValidation=function(t){e(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments)}})(jQuery); \ No newline at end of file +(function(e){function s(e){return new RegExp("^"+e+"$")}function o(e,t){var n=Array.prototype.slice.call(arguments,2),r=e.split("."),i=r.pop();for(var s=0;s0});u.trigger("submit.validation"),i.trigger("validationLostFocus.validation"),s.each(function(t,n){var i=e(n);if(i.hasClass("warning")||i.hasClass("error"))i.removeClass("warning").addClass("error"),r++}),r?(o.options.preventSubmit&&(t.preventDefault(),t.stopImmediatePropagation()),n.addClass("error"),e.isFunction(o.options.submitError)&&o.options.submitError(n,t,u.jqBootstrapValidation("collectErrors",!0))):(n.removeClass("error"),e.isFunction(o.options.submitSuccess)&&o.options.submitSuccess(n,t))}),this.each(function(){var n=e(this),s=n.parents(".form-group").first(),u=s.find(".help-block").first(),a=n.parents("form").first(),f=[];!u.length&&o.options.autoAdd&&o.options.autoAdd.helpBlocks&&(u=e('
'),s.find(".controls").append(u),t.push(u[0]));if(o.options.sniffHtml){var l;n.data("validationPatternPattern")&&n.attr("pattern",n.data("validationPatternPattern")),n.attr("pattern")!==undefined&&(l="Not in the expected format",n.data("validationPatternMessage")&&(l=n.data("validationPatternMessage")),n.data("validationPatternMessage",l),n.data("validationPatternRegex",n.attr("pattern")));if(n.attr("max")!==undefined||n.attr("aria-valuemax")!==undefined){var c=n.attr("max")!==undefined?n.attr("max"):n.attr("aria-valuemax");l="Too high: Maximum of '"+c+"'",n.data("validationMaxMessage")&&(l=n.data("validationMaxMessage")),n.data("validationMaxMessage",l),n.data("validationMaxMax",c)}if(n.attr("min")!==undefined||n.attr("aria-valuemin")!==undefined){var h=n.attr("min")!==undefined?n.attr("min"):n.attr("aria-valuemin");l="Too low: Minimum of '"+h+"'",n.data("validationMinMessage")&&(l=n.data("validationMinMessage")),n.data("validationMinMessage",l),n.data("validationMinMin",h)}n.attr("maxlength")!==undefined&&(l="Too long: Maximum of '"+n.attr("maxlength")+"' characters",n.data("validationMaxlengthMessage")&&(l=n.data("validationMaxlengthMessage")),n.data("validationMaxlengthMessage",l),n.data("validationMaxlengthMaxlength",n.attr("maxlength"))),n.attr("minlength")!==undefined&&(l="Too short: Minimum of '"+n.attr("minlength")+"' characters",n.data("validationMinlengthMessage")&&(l=n.data("validationMinlengthMessage")),n.data("validationMinlengthMessage",l),n.data("validationMinlengthMinlength",n.attr("minlength")));if(n.attr("required")!==undefined||n.attr("aria-required")!==undefined)l=o.builtInValidators.required.message,n.data("validationRequiredMessage")&&(l=n.data("validationRequiredMessage")),n.data("validationRequiredMessage",l);if(n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="number"){l=o.validatorTypes.number.message,n.data("validationNumberMessage")&&(l=n.data("validationNumberMessage")),n.data("validationNumberMessage",l);var p=o.validatorTypes.number.step;n.data("validationNumberStep")&&(p=n.data("validationNumberStep")),n.data("validationNumberStep",p);var d=o.validatorTypes.number.decimal;n.data("validationNumberDecimal")&&(d=n.data("validationNumberDecimal")),n.data("validationNumberDecimal",d)}n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="email"&&(l="Not a valid email address",n.data("validationEmailMessage")&&(l=n.data("validationEmailMessage")),n.data("validationEmailMessage",l)),n.attr("minchecked")!==undefined&&(l="Not enough options checked; Minimum of '"+n.attr("minchecked")+"' required",n.data("validationMincheckedMessage")&&(l=n.data("validationMincheckedMessage")),n.data("validationMincheckedMessage",l),n.data("validationMincheckedMinchecked",n.attr("minchecked"))),n.attr("maxchecked")!==undefined&&(l="Too many options checked; Maximum of '"+n.attr("maxchecked")+"' required",n.data("validationMaxcheckedMessage")&&(l=n.data("validationMaxcheckedMessage")),n.data("validationMaxcheckedMessage",l),n.data("validationMaxcheckedMaxchecked",n.attr("maxchecked")))}n.data("validation")!==undefined&&(f=n.data("validation").split(",")),e.each(n.data(),function(e,t){var n=e.replace(/([A-Z])/g,",$1").split(",");n[0]==="validation"&&n[1]&&f.push(n[1])});var v=f,m=[],g=function(e,t){f[e]=r(t)},y=function(t,i){if(n.data("validation"+i+"Shortcut")!==undefined)e.each(n.data("validation"+i+"Shortcut").split(","),function(e,t){m.push(t)});else if(o.builtInValidators[i.toLowerCase()]){var s=o.builtInValidators[i.toLowerCase()];s.type.toLowerCase()==="shortcut"&&e.each(s.shortcut.split(","),function(e,t){t=r(t),m.push(t),f.push(t)})}};do e.each(f,g),f=e.unique(f),m=[],e.each(v,y),v=m;while(v.length>0);var b={};e.each(f,function(t,i){var s=n.data("validation"+i+"Message"),u=!!s,a=!1;s||(s="'"+i+"' validation failed "),e.each(o.validatorTypes,function(t,o){b[t]===undefined&&(b[t]=[]);if(!a&&n.data("validation"+i+r(o.name))!==undefined){var f=o.init(n,i);u&&(f.message=s),b[t].push(e.extend(!0,{name:r(o.name),message:s},f)),a=!0}});if(!a&&o.builtInValidators[i.toLowerCase()]){var f=e.extend(!0,{},o.builtInValidators[i.toLowerCase()]);u&&(f.message=s);var l=f.type.toLowerCase();l==="shortcut"?a=!0:e.each(o.validatorTypes,function(t,s){b[t]===undefined&&(b[t]=[]),!a&&l===t.toLowerCase()&&(n.data("validation"+i+r(s.name),f[s.name.toLowerCase()]),b[l].push(e.extend(f,s.init(n,i))),a=!0)})}a||e.error("Cannot find validation info for '"+i+"'")}),u.data("original-contents",u.data("original-contents")?u.data("original-contents"):u.html()),u.data("original-role",u.data("original-role")?u.data("original-role"):u.attr("role")),s.data("original-classes",s.data("original-clases")?s.data("original-classes"):s.attr("class")),n.data("original-aria-invalid",n.data("original-aria-invalid")?n.data("original-aria-invalid"):n.attr("aria-invalid")),n.bind("validation.validation",function(t,r){var s=i(n),u=[];return e.each(b,function(t,i){(s||s.length||r&&r.includeEmpty||!!o.validatorTypes[t].includeEmpty||!!o.validatorTypes[t].blockSubmit&&r&&!!r.submitting)&&e.each(i,function(e,r){o.validatorTypes[t].validate(n,s,r)&&u.push(r.message)})}),u}),n.bind("getValidators.validation",function(){return b});var w=0;e.each(b,function(e,t){w+=t.length}),n.bind("getValidatorCount.validation",function(){return w}),n.bind("submit.validation",function(){return n.triggerHandler("change.validation",{submitting:!0})}),n.bind((o.options.bindEvents.length>0?o.options.bindEvents:["keyup","focus","blur","click","keydown","keypress","change"]).concat(["revalidate"]).join(".validation ")+".validation",function(t,r){var f=i(n),l=[];r&&!!r.submitting?s.data("jqbvIsSubmitting",!0):t.type!=="revalidate"&&s.data("jqbvIsSubmitting",!1);var c=!!s.data("jqbvIsSubmitting");s.find("input,textarea,select").each(function(t,i){var s=l.length;e.each(e(i).triggerHandler("validation.validation",r),function(e,t){l.push(t)});if(l.length>s)e(i).attr("aria-invalid","true");else{var o=n.data("original-aria-invalid");e(i).attr("aria-invalid",o!==undefined?o:!1)}}),a.find("input,select,textarea").not(n).not('[name="'+n.attr("name")+'"]').trigger("validationLostFocus.validation"),l=e.unique(l.sort()),l.length?(s.removeClass("success error warning").addClass(c?"error":"warning"),o.options.semanticallyStrict&&l.length===1?u.html(l[0]+(o.options.prependExistingHelpBlock?u.data("original-contents"):"")):u.html('
  • '+l.join("
  • ")+"
"+(o.options.prependExistingHelpBlock?u.data("original-contents"):""))):(s.removeClass("warning error success"),f.length>0&&s.addClass("success"),u.html(u.data("original-contents"))),t.type==="blur"&&s.removeClass("success")}),n.bind("validationLostFocus.validation",function(){s.removeClass("success")})})},destroy:function(){return this.each(function(){var n=e(this),r=n.parents(".form-group").first(),i=r.find(".help-block").first(),s=n.parents("form").first();n.unbind(".validation"),s.unbind(".validationSubmit"),i.html(i.data("original-contents")),r.attr("class",r.data("original-classes")),n.attr("aria-invalid",n.data("original-aria-invalid")),i.attr("role",n.data("original-role")),e.inArray(i[0],t)>-1&&i.remove()})},collectErrors:function(t){var n={};return this.each(function(t,r){var i=e(r),s=i.attr("name"),o=i.triggerHandler("validation.validation",{includeEmpty:!0});n[s]=e.extend(!0,o,n[s])}),e.each(n,function(e,t){t.length===0&&delete n[e]}),n},hasErrors:function(){var t=[];return this.find("input,select,textarea").add(this).each(function(n,r){t=t.concat(e(r).triggerHandler("getValidators.validation")?e(r).triggerHandler("validation.validation",{submitting:!0}):[])}),t.length>0},override:function(t){n=e.extend(!0,n,t)}},validatorTypes:{callback:{name:"callback",init:function(e,t){var n={validatorName:t,callback:e.data("validation"+t+"Callback"),lastValue:e.val(),lastValid:!0,lastFinished:!0},r="Not valid";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n},validate:function(e,t,n){if(n.lastValue===t&&n.lastFinished)return!n.lastValid;if(n.lastFinished===!0){n.lastValue=t,n.lastValid=!0,n.lastFinished=!1;var r=n,i=e;o(n.callback,window,e,t,function(t){r.lastValue===t.value&&(r.lastValid=t.valid,t.message&&(r.message=t.message),r.lastFinished=!0,i.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){!e.is(":focus")&&e.parents("form").first().data("jqbvIsSubmitting")?i.trigger("blur.validation"):i.trigger("revalidate.validation")},1))})}return!1}},ajax:{name:"ajax",init:function(e,t){return{validatorName:t,url:e.data("validation"+t+"Ajax"),lastValue:e.val(),lastValid:!0,lastFinished:!0}},validate:function(t,n,r){return""+r.lastValue==""+n&&r.lastFinished===!0?r.lastValid===!1:(r.lastFinished===!0&&(r.lastValue=n,r.lastValid=!0,r.lastFinished=!1,e.ajax({url:r.url,data:"value="+encodeURIComponent(n)+"&field="+t.attr("name"),dataType:"json",success:function(e){""+r.lastValue==""+e.value&&(r.lastValid=!!e.valid,e.message&&(r.message=e.message),r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1))},failure:function(){r.lastValid=!0,r.message="ajax call failed",r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1)}})),!1)}},regex:{name:"regex",init:function(t,n){var r={},i=t.data("validation"+n+"Regex");r.regex=s(i),i===undefined&&e.error("Can't find regex for '"+n+"' validator on '"+t.attr("name")+"'");var o="Not in the expected format";return t.data("validation"+n+"Message")&&(o=t.data("validation"+n+"Message")),r.message=o,r.originalName=n,r},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},email:{name:"email",init:function(e,t){var n={};n.regex=s("[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");var r="Not a valid email address";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n.originalName=t,n},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},required:{name:"required",init:function(e,t){var n="This is required";return e.data("validation"+t+"Message")&&(n=e.data("validation"+t+"Message")),{message:n,includeEmpty:!0}},validate:function(e,t,n){return!!(t.length===0&&!n.negative||t.length>0&&n.negative)},blockSubmit:!0},match:{name:"match",init:function(t,n){var r=t.data("validation"+n+"Match"),i=t.parents("form").first(),s=i.find('[name="'+r+'"]').first();s.bind("validation.validation",function(){t.trigger("revalidate.validation",{submitting:!0})});var o={};o.element=s,s.length===0&&e.error("Can't find field '"+r+"' to match '"+t.attr("name")+"' against in '"+n+"' validator");var u="Must match",a=null;return(a=i.find('label[for="'+r+'"]')).length?u+=" '"+a.text()+"'":(a=s.parents(".form-group").first().find("label")).length&&(u+=" '"+a.first().text()+"'"),t.data("validation"+n+"Message")&&(u=t.data("validation"+n+"Message")),o.message=u,o},validate:function(e,t,n){return t!==n.element.val()&&!n.negative||t===n.element.val()&&n.negative},blockSubmit:!0,includeEmpty:!0},max:{name:"max",init:function(e,t){var n={};return n.max=e.data("validation"+t+"Max"),n.message="Too high: Maximum of '"+n.max+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t,10)>parseFloat(n.max,10)&&!n.negative||parseFloat(t,10)<=parseFloat(n.max,10)&&n.negative}},min:{name:"min",init:function(e,t){var n={};return n.min=e.data("validation"+t+"Min"),n.message="Too low: Minimum of '"+n.min+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t)=parseFloat(n.min)&&n.negative}},maxlength:{name:"maxlength",init:function(e,t){var n={};return n.maxlength=e.data("validation"+t+"Maxlength"),n.message="Too long: Maximum of '"+n.maxlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length>n.maxlength&&!n.negative||t.length<=n.maxlength&&n.negative}},minlength:{name:"minlength",init:function(e,t){var n={};return n.minlength=e.data("validation"+t+"Minlength"),n.message="Too short: Minimum of '"+n.minlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length=n.minlength&&n.negative}},maxchecked:{name:"maxchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.maxchecked=e.data("validation"+t+"Maxchecked");var i="Too many: Max '"+n.maxchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length>n.maxchecked&&!n.negative||n.elements.filter(":checked").length<=n.maxchecked&&n.negative},blockSubmit:!0},minchecked:{name:"minchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.minchecked=e.data("validation"+t+"Minchecked");var i="Too few: Min '"+n.minchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length=n.minchecked&&n.negative},blockSubmit:!0,includeEmpty:!0},number:{name:"number",init:function(e,t){var n={};n.step=1,e.attr("step")&&(n.step=e.attr("step")),e.data("validation"+t+"Step")&&(n.step=e.data("validation"+t+"Step")),n.decimal=".",e.data("validation"+t+"Decimal")&&(n.decimal=e.data("validation"+t+"Decimal")),n.thousands="",e.data("validation"+t+"Thousands")&&(n.thousands=e.data("validation"+t+"Thousands")),n.regex=s("([+-]?\\d+(\\"+n.decimal+"\\d+)?)?"),n.message="Must be a number";var r=e.data("validation"+t+"Message");return r&&(n.message=r),n},validate:function(e,t,n){var r=t.replace(n.decimal,".").replace(n.thousands,""),i=parseFloat(r),s=parseFloat(n.step);while(s%1!==0)s=parseFloat(s.toPrecision(12))*10,i=parseFloat(i.toPrecision(12))*10;var o=n.regex.test(t),u=parseFloat(i)%parseFloat(s)===0,a=!isNaN(parseFloat(r))&&isFinite(r),f=!(o&&u&&a);return f},message:"Must be a number"}},builtInValidators:{email:{name:"Email",type:"email"},passwordagain:{name:"Passwordagain",type:"match",match:"password",message:"Does not match the given password"},positive:{name:"Positive",type:"shortcut",shortcut:"number,positivenumber"},negative:{name:"Negative",type:"shortcut",shortcut:"number,negativenumber"},integer:{name:"Integer",type:"regex",regex:"[+-]?\\d+",message:"No decimal places allowed"},positivenumber:{name:"Positivenumber",type:"min",min:0,message:"Must be a positive number"},negativenumber:{name:"Negativenumber",type:"max",max:0,message:"Must be a negative number"},required:{name:"Required",type:"required",message:"This is required"},checkone:{name:"Checkone",type:"minchecked",minchecked:1,message:"Check at least one option"},number:{name:"Number",type:"number",decimal:".",step:"1"},pattern:{name:"Pattern",type:"regex",message:"Not in expected format"}}},r=function(e){return e.toLowerCase().replace(/(^|\s)([a-z])/g,function(e,t,n){return t+n.toUpperCase()})},i=function(t){var n=null,r=t.attr("type");if(r==="checkbox"){n=t.is(":checked")?n:"";var i=t.parents("form").first()||t.parents(".form-group").first();i&&(n=i.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else if(r==="radio"){n=e('input[name="'+t.attr("name")+'"]:checked').length>0?t.val():"";var s=t.parents("form").first()||t.parents(".form-group").first();s&&(n=s.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else n=t.val();return n};e.fn.jqBootstrapValidation=function(t){return n.methods[t]?n.methods[t].apply(this,Array.prototype.slice.call(arguments,1)):typeof t=="object"||!t?n.methods.init.apply(this,arguments):(e.error("Method "+t+" does not exist on jQuery.jqBootstrapValidation"),null)},e.jqBootstrapValidation=function(t){e(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments)}})(jQuery); \ No newline at end of file diff --git a/src/jqBootstrapValidation.js b/src/jqBootstrapValidation.js index 79f3048..0e3a503 100644 --- a/src/jqBootstrapValidation.js +++ b/src/jqBootstrapValidation.js @@ -41,7 +41,7 @@ var warningsFound = 0; // Get all inputs var $allInputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); - var $allControlGroups = $form.find(".control-group"); + var $allControlGroups = $form.find(".form-group"); // Only trigger validation on the ones that actually _have_ validation var $inputsWithValidators = $allInputs.filter(function () { @@ -86,7 +86,7 @@ // Get references to everything we're interested in var $this = $(this), - $controlGroup = $this.parents(".control-group").first(), + $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(), $form = $this.parents("form").first(), validatorNames = []; @@ -597,7 +597,7 @@ var $this = $(this), - $controlGroup = $this.parents(".control-group").first(), + $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(), $form = $this.parents("form").first(); @@ -861,7 +861,7 @@ var $label = null; if (($label = $form.find("label[for=\"" + elementName + "\"]")).length) { message += " '" + $label.text() + "'"; - } else if (($label = $element.parents(".control-group").first().find("label")).length) { + } else if (($label = $element.parents(".form-group").first().find("label")).length) { message += " '" + $label.first().text() + "'"; } @@ -1143,7 +1143,7 @@ var type = $this.attr("type"); if (type === "checkbox") { value = ($this.is(":checked") ? value : ""); - var checkboxParent = $this.parents("form").first() || $this.parents(".control-group").first(); + var checkboxParent = $this.parents("form").first() || $this.parents(".form-group").first(); if (checkboxParent) { value = checkboxParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); @@ -1152,7 +1152,7 @@ } else if (type === "radio") { value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? $this.val() : ""); - var radioParent = $this.parents("form").first() || $this.parents(".control-group").first(); + var radioParent = $this.parents("form").first() || $this.parents(".form-group").first(); if (radioParent) { value = radioParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); From 5b4516bbc12272a569eb1837d3ec2221b8d2caa4 Mon Sep 17 00:00:00 2001 From: Murillo Date: Fri, 15 Aug 2014 15:35:24 -0300 Subject: [PATCH 2/4] update Control-group to form-group bootstrap 3 --- dist/jqBootstrapValidation-1.3.7.js | 2250 ++++++++++++----------- dist/jqBootstrapValidation-1.3.7.min.js | 6 +- dist/jqBootstrapValidation.zip | Bin 14067 -> 17232 bytes test/issues/39/test.js | 4 +- test/issues/50/test.js | 4 +- test/jqBootstrapValidation_helpers.js | 14 +- test/jqBootstrapValidation_test.js | 72 +- test/notravis/67/test.js | 2 +- 8 files changed, 1182 insertions(+), 1170 deletions(-) diff --git a/dist/jqBootstrapValidation-1.3.7.js b/dist/jqBootstrapValidation-1.3.7.js index 918a0c0..1ebad0a 100644 --- a/dist/jqBootstrapValidation-1.3.7.js +++ b/dist/jqBootstrapValidation-1.3.7.js @@ -1,667 +1,668 @@ -/*! jqBootstrapValidation - v1.3.7 - 2013-05-07 +/*! jqBootstrapValidation - v1.3.7 - 2014-08-15 * http://reactiveraven.github.com/jqBootstrapValidation -* Copyright (c) 2013 David Godfrey; Licensed MIT */ - -(function( $ ){ - - var createdElements = []; - - var defaults = { - options: { - prependExistingHelpBlock: false, - sniffHtml: true, // sniff for 'required', 'maxlength', etc - preventSubmit: true, // stop the form submit event from firing if validation fails - submitError: false, // function called if there is an error when trying to submit - submitSuccess: false, // function called just before a successful submit event is sent to the server +* Copyright (c) 2014 David Godfrey; Licensed MIT */ +(function ($) { + + var createdElements = []; + + var defaults = { + options: { + prependExistingHelpBlock: false, + sniffHtml: true, // sniff for 'required', 'maxlength', etc + preventSubmit: true, // stop the form submit event from firing if validation fails + submitError: false, // function called if there is an error when trying to submit + submitSuccess: false, // function called just before a successful submit event is sent to the server semanticallyStrict: false, // set to true to tidy up generated HTML output + removeSuccess : true, bindEvents: [], - autoAdd: { - helpBlocks: true - }, - filter: function () { - // return $(this).is(":visible"); // only validate elements you can see - return true; // validate everything - } - }, - methods: { - init : function( options ) { - - // Get a clean copy of the defaults for extending - var settings = $.extend(true, {}, defaults); - // Set up the options based on the input - settings.options = $.extend(true, settings.options, options); - - var $siblingElements = this; - - var uniqueForms = $.unique( - $siblingElements.map( function () { - return $(this).parents("form")[0]; - }).toArray() - ); - - $(uniqueForms).bind("submit.validationSubmit", function (e) { - var $form = $(this); - var warningsFound = 0; - // Get all inputs - var $allInputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); - var $allControlGroups = $form.find(".form-group"); - - // Only trigger validation on the ones that actually _have_ validation - var $inputsWithValidators = $allInputs.filter(function () { - return $(this).triggerHandler("getValidatorCount.validation") > 0; - }); - $inputsWithValidators.trigger("submit.validation"); - - // But all of them are out-of-focus now, because we're submitting. - $allInputs.trigger("validationLostFocus.validation"); - - // Okay, now check each controlgroup for errors (or warnings) - $allControlGroups.each(function (i, el) { - var $controlGroup = $(el); - if ($controlGroup.hasClass("warning") || $controlGroup.hasClass("error")) { - $controlGroup.removeClass("warning").addClass("error"); - warningsFound++; - } - }); - - if (warningsFound) { - // If we found any warnings, maybe we should prevent the submit - // event, and trigger 'submitError' (if they're set up) - if (settings.options.preventSubmit) { - e.preventDefault(); - e.stopImmediatePropagation(); - } - $form.addClass("error"); - if ($.isFunction(settings.options.submitError)) { - settings.options.submitError($form, e, $inputsWithValidators.jqBootstrapValidation("collectErrors", true)); - } - } else { - // Woo! No errors! We can pass the submit event to submitSuccess - // (if it has been set up) - $form.removeClass("error"); - if ($.isFunction(settings.options.submitSuccess)) { - settings.options.submitSuccess($form, e); - } - } - }); - - return this.each(function(){ - - // Get references to everything we're interested in - var $this = $(this), - $controlGroup = $this.parents(".form-group").first(), - $helpBlock = $controlGroup.find(".help-block").first(), - $form = $this.parents("form").first(), - validatorNames = []; - - // create message container if not exists - if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { - $helpBlock = $('
'); - $controlGroup.find('.controls').append($helpBlock); - createdElements.push($helpBlock[0]); - } - - // ============================================================= - // SNIFF HTML FOR VALIDATORS - // ============================================================= - - // *snort sniff snuffle* - - if (settings.options.sniffHtml) { - var message; - // --------------------------------------------------------- - // PATTERN - // --------------------------------------------------------- - if ($this.data("validationPatternPattern")) { - $this.attr("pattern", $this.data("validationPatternPattern")); - } - if ($this.attr("pattern") !== undefined) { - message = "Not in the expected format"; - if ($this.data("validationPatternMessage")) { - message = $this.data("validationPatternMessage"); - } - $this.data("validationPatternMessage", message); - $this.data("validationPatternRegex", $this.attr("pattern")); - } - // --------------------------------------------------------- - // MAX - // --------------------------------------------------------- - if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { - var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); - message = "Too high: Maximum of '" + max + "'"; - if ($this.data("validationMaxMessage")) { - message = $this.data("validationMaxMessage"); - } - $this.data("validationMaxMessage", message); - $this.data("validationMaxMax", max); - } - // --------------------------------------------------------- - // MIN - // --------------------------------------------------------- - if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { - var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); - message = "Too low: Minimum of '" + min + "'"; - if ($this.data("validationMinMessage")) { - message = $this.data("validationMinMessage"); - } - $this.data("validationMinMessage", message); - $this.data("validationMinMin", min); - } - // --------------------------------------------------------- - // MAXLENGTH - // --------------------------------------------------------- - if ($this.attr("maxlength") !== undefined) { - message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters"; - if ($this.data("validationMaxlengthMessage")) { - message = $this.data("validationMaxlengthMessage"); - } - $this.data("validationMaxlengthMessage", message); - $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); - } - // --------------------------------------------------------- - // MINLENGTH - // --------------------------------------------------------- - if ($this.attr("minlength") !== undefined) { - message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters"; - if ($this.data("validationMinlengthMessage")) { - message = $this.data("validationMinlengthMessage"); - } - $this.data("validationMinlengthMessage", message); - $this.data("validationMinlengthMinlength", $this.attr("minlength")); - } - // --------------------------------------------------------- - // REQUIRED - // --------------------------------------------------------- - if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { - message = settings.builtInValidators.required.message; - if ($this.data("validationRequiredMessage")) { - message = $this.data("validationRequiredMessage"); - } - $this.data("validationRequiredMessage", message); - } - // --------------------------------------------------------- - // NUMBER - // --------------------------------------------------------- - if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { - message = settings.validatorTypes.number.message; // TODO: fix this - if ($this.data("validationNumberMessage")) { - message = $this.data("validationNumberMessage"); - } - $this.data("validationNumberMessage", message); - - var step = settings.validatorTypes.number.step; // TODO: and this - if ($this.data("validationNumberStep")) { - step = $this.data("validationNumberStep"); - } - $this.data("validationNumberStep", step); - - var decimal = settings.validatorTypes.number.decimal; - if ($this.data("validationNumberDecimal")) { - decimal = $this.data("validationNumberDecimal"); - } - $this.data("validationNumberDecimal", decimal); - } - // --------------------------------------------------------- - // EMAIL - // --------------------------------------------------------- - if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { - message = "Not a valid email address"; - if ($this.data("validationEmailMessage")) { - message = $this.data("validationEmailMessage"); - } - $this.data("validationEmailMessage", message); - } - // --------------------------------------------------------- - // MINCHECKED - // --------------------------------------------------------- - if ($this.attr("minchecked") !== undefined) { - message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required"; - if ($this.data("validationMincheckedMessage")) { - message = $this.data("validationMincheckedMessage"); - } - $this.data("validationMincheckedMessage", message); - $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); + autoAdd: { + helpBlocks: true + }, + filter: function () { + // return $(this).is(":visible"); // only validate elements you can see + return true; // validate everything } - // --------------------------------------------------------- - // MAXCHECKED - // --------------------------------------------------------- - if ($this.attr("maxchecked") !== undefined) { - message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required"; - if ($this.data("validationMaxcheckedMessage")) { - message = $this.data("validationMaxcheckedMessage"); - } - $this.data("validationMaxcheckedMessage", message); - $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); - } - } - - // ============================================================= - // COLLECT VALIDATOR NAMES - // ============================================================= - - // Get named validators - if ($this.data("validation") !== undefined) { - validatorNames = $this.data("validation").split(","); - } - - // Get extra ones defined on the element's data attributes - $.each($this.data(), function (i, el) { - var parts = i.replace(/([A-Z])/g, ",$1").split(","); - if (parts[0] === "validation" && parts[1]) { - validatorNames.push(parts[1]); - } - }); - - // ============================================================= - // NORMALISE VALIDATOR NAMES - // ============================================================= - - var validatorNamesToInspect = validatorNames; - var newValidatorNamesToInspect = []; - - var uppercaseEachValidatorName = function (i, el) { - validatorNames[i] = formatValidatorName(el); - }; - - var inspectValidators = function(i, el) { - if ($this.data("validation" + el + "Shortcut") !== undefined) { - // Are these custom validators? - // Pull them out! - $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { - newValidatorNamesToInspect.push(el2); - }); - } else if (settings.builtInValidators[el.toLowerCase()]) { - // Is this a recognised built-in? - // Pull it out! - var validator = settings.builtInValidators[el.toLowerCase()]; - if (validator.type.toLowerCase() === "shortcut") { - $.each(validator.shortcut.split(","), function (i, el) { - el = formatValidatorName(el); - newValidatorNamesToInspect.push(el); - validatorNames.push(el); + }, + methods: { + init: function (options) { + + // Get a clean copy of the defaults for extending + var settings = $.extend(true, {}, defaults); + // Set up the options based on the input + settings.options = $.extend(true, settings.options, options); + + var $siblingElements = this; + + var uniqueForms = $.unique( + $siblingElements.map(function () { + return $(this).parents("form")[0]; + }).toArray() + ); + + $(uniqueForms).bind("submit.validationSubmit", function (e) { + var $form = $(this); + var warningsFound = 0; + // Get all inputs + var $allInputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); + var $allControlGroups = $form.find(".form-group"); + + // Only trigger validation on the ones that actually _have_ validation + var $inputsWithValidators = $allInputs.filter(function () { + return $(this).triggerHandler("getValidatorCount.validation") > 0; + }); + $inputsWithValidators.trigger("submit.validation"); + + // But all of them are out-of-focus now, because we're submitting. + $allInputs.trigger("validationLostFocus.validation"); + + // Okay, now check each controlgroup for errors (or warnings) + $allControlGroups.each(function (i, el) { + var $controlGroup = $(el); + if ($controlGroup.hasClass("warning") || $controlGroup.hasClass("error")) { + $controlGroup.removeClass("warning").addClass("error"); + warningsFound++; + } + }); + + if (warningsFound) { + // If we found any warnings, maybe we should prevent the submit + // event, and trigger 'submitError' (if they're set up) + if (settings.options.preventSubmit) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + $form.addClass("error"); + if ($.isFunction(settings.options.submitError)) { + settings.options.submitError($form, e, $inputsWithValidators.jqBootstrapValidation("collectErrors", true)); + } + } else { + // Woo! No errors! We can pass the submit event to submitSuccess + // (if it has been set up) + $form.removeClass("error"); + if ($.isFunction(settings.options.submitSuccess)) { + settings.options.submitSuccess($form, e); + } + } }); - } - } - }; - - do // repeatedly expand 'shortcut' validators into their real validators - { - // Uppercase only the first letter of each name - $.each(validatorNames, uppercaseEachValidatorName); - - // Remove duplicate validator names - validatorNames = $.unique(validatorNames); - - // Pull out the new validator names from each shortcut - newValidatorNamesToInspect = []; - $.each(validatorNamesToInspect, inspectValidators); - - validatorNamesToInspect = newValidatorNamesToInspect; - - } while (validatorNamesToInspect.length > 0); - - // ============================================================= - // SET UP VALIDATOR ARRAYS - // ============================================================= - - /* We're gonna generate something like - * - * { - * "regex": [ - * { -- a validator object here --}, - * { -- a validator object here --} - * ], - * "required": [ - * { -- a validator object here --}, - * { -- a validator object here --} - * ] - * } - * - * with a few more entries. - * - * Because we only add a few validators to each field, most of the - * keys will be empty arrays with no validator objects in them, and - * thats fine. - */ - - var validators = {}; - - $.each(validatorNames, function (i, el) { - // Set up the 'override' message - var message = $this.data("validation" + el + "Message"); - var hasOverrideMessage = !!message; - var foundValidator = false; - if (!message) { - message = "'" + el + "' validation failed "; - } - $.each( - settings.validatorTypes, - function (validatorType, validatorTemplate) { - if (validators[validatorType] === undefined) { - validators[validatorType] = []; - } - if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { - var initted = validatorTemplate.init($this, el); - if (hasOverrideMessage) { - initted.message = message; - } - - validators[validatorType].push( - $.extend( - true, - { - name: formatValidatorName(validatorTemplate.name), - message: message - }, - initted - ) - ); - foundValidator = true; - } - } - ); - - if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { - - var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); - if (hasOverrideMessage) { - validator.message = message; - } - var validatorType = validator.type.toLowerCase(); - - if (validatorType === "shortcut") { - foundValidator = true; - } else { - $.each( - settings.validatorTypes, - function (validatorTemplateType, validatorTemplate) { - if (validators[validatorTemplateType] === undefined) { - validators[validatorTemplateType] = []; + return this.each(function () { + + // Get references to everything we're interested in + var $this = $(this), + $controlGroup = $this.parents(".form-group").first(), + $helpBlock = $controlGroup.find(".help-block").first(), + $form = $this.parents("form").first(), + validatorNames = []; + + // create message container if not exists + if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { + $helpBlock = $('
'); + $controlGroup.find('.controls').append($helpBlock); + createdElements.push($helpBlock[0]); } - if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { - $this.data( - "validation" + el + formatValidatorName(validatorTemplate.name), - validator[validatorTemplate.name.toLowerCase()] - ); - validators[validatorType].push( - $.extend( - validator, - validatorTemplate.init($this, el) - ) - ); - foundValidator = true; + + // ============================================================= + // SNIFF HTML FOR VALIDATORS + // ============================================================= + + // *snort sniff snuffle* + + if (settings.options.sniffHtml) { + var message; + // --------------------------------------------------------- + // PATTERN + // --------------------------------------------------------- + if ($this.data("validationPatternPattern")) { + $this.attr("pattern", $this.data("validationPatternPattern")); + } + if ($this.attr("pattern") !== undefined) { + message = "Not in the expected format"; + if ($this.data("validationPatternMessage")) { + message = $this.data("validationPatternMessage"); + } + $this.data("validationPatternMessage", message); + $this.data("validationPatternRegex", $this.attr("pattern")); + } + // --------------------------------------------------------- + // MAX + // --------------------------------------------------------- + if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { + var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); + message = "Too high: Maximum of '" + max + "'"; + if ($this.data("validationMaxMessage")) { + message = $this.data("validationMaxMessage"); + } + $this.data("validationMaxMessage", message); + $this.data("validationMaxMax", max); + } + // --------------------------------------------------------- + // MIN + // --------------------------------------------------------- + if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { + var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); + message = "Too low: Minimum of '" + min + "'"; + if ($this.data("validationMinMessage")) { + message = $this.data("validationMinMessage"); + } + $this.data("validationMinMessage", message); + $this.data("validationMinMin", min); + } + // --------------------------------------------------------- + // MAXLENGTH + // --------------------------------------------------------- + if ($this.attr("maxlength") !== undefined) { + message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters"; + if ($this.data("validationMaxlengthMessage")) { + message = $this.data("validationMaxlengthMessage"); + } + $this.data("validationMaxlengthMessage", message); + $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); + } + // --------------------------------------------------------- + // MINLENGTH + // --------------------------------------------------------- + if ($this.attr("minlength") !== undefined) { + message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters"; + if ($this.data("validationMinlengthMessage")) { + message = $this.data("validationMinlengthMessage"); + } + $this.data("validationMinlengthMessage", message); + $this.data("validationMinlengthMinlength", $this.attr("minlength")); + } + // --------------------------------------------------------- + // REQUIRED + // --------------------------------------------------------- + if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { + message = settings.builtInValidators.required.message; + if ($this.data("validationRequiredMessage")) { + message = $this.data("validationRequiredMessage"); + } + $this.data("validationRequiredMessage", message); + } + // --------------------------------------------------------- + // NUMBER + // --------------------------------------------------------- + if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { + message = settings.validatorTypes.number.message; // TODO: fix this + if ($this.data("validationNumberMessage")) { + message = $this.data("validationNumberMessage"); + } + $this.data("validationNumberMessage", message); + + var step = settings.validatorTypes.number.step; // TODO: and this + if ($this.data("validationNumberStep")) { + step = $this.data("validationNumberStep"); + } + $this.data("validationNumberStep", step); + + var decimal = settings.validatorTypes.number.decimal; + if ($this.data("validationNumberDecimal")) { + decimal = $this.data("validationNumberDecimal"); + } + $this.data("validationNumberDecimal", decimal); + } + // --------------------------------------------------------- + // EMAIL + // --------------------------------------------------------- + if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { + message = "Not a valid email address"; + if ($this.data("validationEmailMessage")) { + message = $this.data("validationEmailMessage"); + } + $this.data("validationEmailMessage", message); + } + // --------------------------------------------------------- + // MINCHECKED + // --------------------------------------------------------- + if ($this.attr("minchecked") !== undefined) { + message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required"; + if ($this.data("validationMincheckedMessage")) { + message = $this.data("validationMincheckedMessage"); + } + $this.data("validationMincheckedMessage", message); + $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); + } + // --------------------------------------------------------- + // MAXCHECKED + // --------------------------------------------------------- + if ($this.attr("maxchecked") !== undefined) { + message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required"; + if ($this.data("validationMaxcheckedMessage")) { + message = $this.data("validationMaxcheckedMessage"); + } + $this.data("validationMaxcheckedMessage", message); + $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); + } } - } - ); - } - } - if (! foundValidator) { - $.error("Cannot find validation info for '" + el + "'"); - } - }); - - // ============================================================= - // STORE FALLBACK VALUES - // ============================================================= - - $helpBlock.data( - "original-contents", - ( - $helpBlock.data("original-contents") ? - $helpBlock.data("original-contents") : - $helpBlock.html() - ) - ); - - $helpBlock.data( - "original-role", - ( - $helpBlock.data("original-role") ? - $helpBlock.data("original-role") : - $helpBlock.attr("role") - ) - ); - - $controlGroup.data( - "original-classes", - ( - $controlGroup.data("original-clases") ? - $controlGroup.data("original-classes") : - $controlGroup.attr("class") - ) - ); - - $this.data( - "original-aria-invalid", - ( - $this.data("original-aria-invalid") ? - $this.data("original-aria-invalid") : - $this.attr("aria-invalid") - ) - ); - - // ============================================================= - // VALIDATION - // ============================================================= - - $this.bind( - "validation.validation", - function (event, params) { - - var value = getValue($this); - - // Get a list of the errors to apply - var errorsFound = []; - - $.each(validators, function (validatorType, validatorTypeArray) { - if ( - value || // has a truthy value - value.length || // not an empty string - ( // am including empty values - ( - params && - params.includeEmpty - ) || - !!settings.validatorTypes[validatorType].includeEmpty - ) || - ( // validator is blocking submit - !!settings.validatorTypes[validatorType].blockSubmit && - params && - !!params.submitting - ) - ) - { - $.each( - validatorTypeArray, - function (i, validator) { - if (settings.validatorTypes[validatorType].validate($this, value, validator)) { - errorsFound.push(validator.message); - } + // ============================================================= + // COLLECT VALIDATOR NAMES + // ============================================================= + + // Get named validators + if ($this.data("validation") !== undefined) { + validatorNames = $this.data("validation").split(","); } - ); - } - }); - return errorsFound; - } - ); + // Get extra ones defined on the element's data attributes + $.each($this.data(), function (i, el) { + var parts = i.replace(/([A-Z])/g, ",$1").split(","); + if (parts[0] === "validation" && parts[1]) { + validatorNames.push(parts[1]); + } + }); - $this.bind( - "getValidators.validation", - function () { - return validators; - } - ); - - var numValidators = 0; - - $.each(validators, function (i, el) { - numValidators += el.length; - }); - - $this.bind("getValidatorCount.validation", function () { - return numValidators; - }); - - // ============================================================= - // WATCH FOR CHANGES - // ============================================================= - $this.bind( - "submit.validation", - function () { - return $this.triggerHandler("change.validation", {submitting: true}); - } - ); - $this.bind( - ( - settings.options.bindEvents.length > 0 ? - settings.options.bindEvents : - [ - "keyup", - "focus", - "blur", - "click", - "keydown", - "keypress", - "change" - ] - ).concat(["revalidate"]).join(".validation ") + ".validation", - function (e, params) { - - var value = getValue($this); - - var errorsFound = []; - - if (params && !!params.submitting) { - $controlGroup.data("jqbvIsSubmitting", true); - } else if (e.type !== "revalidate") { - $controlGroup.data("jqbvIsSubmitting", false); - } - - var formIsSubmitting = !!$controlGroup.data("jqbvIsSubmitting"); - - $controlGroup.find("input,textarea,select").each(function (i, el) { - var oldCount = errorsFound.length; - $.each($(el).triggerHandler("validation.validation", params), function (j, message) { - errorsFound.push(message); + // ============================================================= + // NORMALISE VALIDATOR NAMES + // ============================================================= + + var validatorNamesToInspect = validatorNames; + var newValidatorNamesToInspect = []; + + var uppercaseEachValidatorName = function (i, el) { + validatorNames[i] = formatValidatorName(el); + }; + + var inspectValidators = function (i, el) { + if ($this.data("validation" + el + "Shortcut") !== undefined) { + // Are these custom validators? + // Pull them out! + $.each($this.data("validation" + el + "Shortcut").split(","), function (i2, el2) { + newValidatorNamesToInspect.push(el2); + }); + } else if (settings.builtInValidators[el.toLowerCase()]) { + // Is this a recognised built-in? + // Pull it out! + var validator = settings.builtInValidators[el.toLowerCase()]; + if (validator.type.toLowerCase() === "shortcut") { + $.each(validator.shortcut.split(","), function (i, el) { + el = formatValidatorName(el); + newValidatorNamesToInspect.push(el); + validatorNames.push(el); + }); + } + } + }; + + do // repeatedly expand 'shortcut' validators into their real validators + { + // Uppercase only the first letter of each name + $.each(validatorNames, uppercaseEachValidatorName); + + // Remove duplicate validator names + validatorNames = $.unique(validatorNames); + + // Pull out the new validator names from each shortcut + newValidatorNamesToInspect = []; + $.each(validatorNamesToInspect, inspectValidators); + + validatorNamesToInspect = newValidatorNamesToInspect; + + } while (validatorNamesToInspect.length > 0); + + // ============================================================= + // SET UP VALIDATOR ARRAYS + // ============================================================= + + /* We're gonna generate something like + * + * { + * "regex": [ + * { -- a validator object here --}, + * { -- a validator object here --} + * ], + * "required": [ + * { -- a validator object here --}, + * { -- a validator object here --} + * ] + * } + * + * with a few more entries. + * + * Because we only add a few validators to each field, most of the + * keys will be empty arrays with no validator objects in them, and + * thats fine. + */ + + var validators = {}; + + $.each(validatorNames, function (i, el) { + // Set up the 'override' message + var message = $this.data("validation" + el + "Message"); + var hasOverrideMessage = !!message; + var foundValidator = false; + if (!message) { + message = "'" + el + "' validation failed "; + } + + $.each( + settings.validatorTypes, + function (validatorType, validatorTemplate) { + if (validators[validatorType] === undefined) { + validators[validatorType] = []; + } + if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { + var initted = validatorTemplate.init($this, el); + if (hasOverrideMessage) { + initted.message = message; + } + + validators[validatorType].push( + $.extend( + true, + { + name: formatValidatorName(validatorTemplate.name), + message: message + }, + initted + ) + ); + foundValidator = true; + } + } + ); + + if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { + + var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); + if (hasOverrideMessage) { + validator.message = message; + } + var validatorType = validator.type.toLowerCase(); + + if (validatorType === "shortcut") { + foundValidator = true; + } else { + $.each( + settings.validatorTypes, + function (validatorTemplateType, validatorTemplate) { + if (validators[validatorTemplateType] === undefined) { + validators[validatorTemplateType] = []; + } + if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { + $this.data( + "validation" + el + formatValidatorName(validatorTemplate.name), + validator[validatorTemplate.name.toLowerCase()] + ); + validators[validatorType].push( + $.extend( + validator, + validatorTemplate.init($this, el) + ) + ); + foundValidator = true; + } + } + ); + } + } + + if (!foundValidator) { + $.error("Cannot find validation info for '" + el + "'"); + } + }); + + // ============================================================= + // STORE FALLBACK VALUES + // ============================================================= + + $helpBlock.data( + "original-contents", + ( + $helpBlock.data("original-contents") ? + $helpBlock.data("original-contents") : + $helpBlock.html() + ) + ); + + $helpBlock.data( + "original-role", + ( + $helpBlock.data("original-role") ? + $helpBlock.data("original-role") : + $helpBlock.attr("role") + ) + ); + + $controlGroup.data( + "original-classes", + ( + $controlGroup.data("original-clases") ? + $controlGroup.data("original-classes") : + $controlGroup.attr("class") + ) + ); + + $this.data( + "original-aria-invalid", + ( + $this.data("original-aria-invalid") ? + $this.data("original-aria-invalid") : + $this.attr("aria-invalid") + ) + ); + + // ============================================================= + // VALIDATION + // ============================================================= + + $this.bind( + "validation.validation", + function (event, params) { + + var value = getValue($this); + + // Get a list of the errors to apply + var errorsFound = []; + + $.each(validators, function (validatorType, validatorTypeArray) { + if ( + value || // has a truthy value + value.length || // not an empty string + ( // am including empty values + ( + params && + params.includeEmpty + ) || !!settings.validatorTypes[validatorType].includeEmpty + ) || + ( // validator is blocking submit + !!settings.validatorTypes[validatorType].blockSubmit && + params && !!params.submitting + ) + ) { + $.each( + validatorTypeArray, + function (i, validator) { + if (settings.validatorTypes[validatorType].validate($this, value, validator)) { + errorsFound.push(validator.message); + } + } + ); + } + }); + + return errorsFound; + } + ); + + $this.bind( + "getValidators.validation", + function () { + return validators; + } + ); + + var numValidators = 0; + + $.each(validators, function (i, el) { + numValidators += el.length; + }); + + $this.bind("getValidatorCount.validation", function () { + return numValidators; + }); + + // ============================================================= + // WATCH FOR CHANGES + // ============================================================= + $this.bind( + "submit.validation", + function () { + return $this.triggerHandler("change.validation", {submitting: true}); + } + ); + $this.bind( + ( + settings.options.bindEvents.length > 0 ? + settings.options.bindEvents : + [ + "keyup", + "focus", + "blur", + "click", + "keydown", + "keypress", + "change" + ] + ).concat(["revalidate"]).join(".validation ") + ".validation", + function (e, params) { + + var value = getValue($this); + + var errorsFound = []; + + if (params && !!params.submitting) { + $controlGroup.data("jqbvIsSubmitting", true); + } else if (e.type !== "revalidate") { + $controlGroup.data("jqbvIsSubmitting", false); + } + + var formIsSubmitting = !!$controlGroup.data("jqbvIsSubmitting"); + + $controlGroup.find("input,textarea,select").not('[type=submit]').each(function (i, el) { + var oldCount = errorsFound.length; + $.each($(el).triggerHandler("validation.validation", params) || [], function (j, message) { + errorsFound.push(message); + }); + if (errorsFound.length > oldCount) { + $(el).attr("aria-invalid", "true"); + } else { + var original = $this.data("original-aria-invalid"); + $(el).attr("aria-invalid", (original !== undefined ? original : false)); + } + }); + + $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); + + errorsFound = $.unique(errorsFound.sort()); + + // Were there any errors? + if (errorsFound.length) { + // Better flag it up as a warning. + $controlGroup.removeClass("success error warning").addClass(formIsSubmitting ? "error" : "warning"); + + // How many errors did we find? + if (settings.options.semanticallyStrict && errorsFound.length === 1) { + // Only one? Being strict? Just output it. + $helpBlock.html(errorsFound[0] + + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); + } else { + // Multiple? Being sloppy? Glue them together into an UL. + $helpBlock.html("
  • " + errorsFound.join("
  • ") + "
" + + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); + } + } else { + $controlGroup.removeClass("warning error success"); + if (value.length > 0) { + $controlGroup.addClass("success"); + } + $helpBlock.html($helpBlock.data("original-contents")); + } + + if (e.type === "blur") { + if( settings.options.removeSuccess ){ + $controlGroup.removeClass("success"); + } + } + } + ); + $this.bind("validationLostFocus.validation", function () { + if( settings.options.removeSuccess ){ + $controlGroup.removeClass("success"); + } + }); }); - if (errorsFound.length > oldCount) { - $(el).attr("aria-invalid", "true"); - } else { - var original = $this.data("original-aria-invalid"); - $(el).attr("aria-invalid", (original !== undefined ? original : false)); - } - }); + }, + destroy: function () { + + return this.each( + function () { + + var + $this = $(this), + $controlGroup = $this.parents(".form-group").first(), + $helpBlock = $controlGroup.find(".help-block").first(), + $form = $this.parents("form").first(); + + // remove our events + $this.unbind('.validation'); // events are namespaced. + $form.unbind(".validationSubmit"); + // reset help text + $helpBlock.html($helpBlock.data("original-contents")); + // reset classes + $controlGroup.attr("class", $controlGroup.data("original-classes")); + // reset aria + $this.attr("aria-invalid", $this.data("original-aria-invalid")); + // reset role + $helpBlock.attr("role", $this.data("original-role")); + // remove all elements we created + if ($.inArray($helpBlock[0], createdElements) > -1) { + $helpBlock.remove(); + } - $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); + } + ); - errorsFound = $.unique(errorsFound.sort()); + }, + collectErrors: function (includeEmpty) { - // Were there any errors? - if (errorsFound.length) { - // Better flag it up as a warning. - $controlGroup.removeClass("success error warning").addClass(formIsSubmitting ? "error" : "warning"); + var errorMessages = {}; + this.each(function (i, el) { + var $el = $(el); + var name = $el.attr("name"); + var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); + errorMessages[name] = $.extend(true, errors, errorMessages[name]); + }); - // How many errors did we find? - if (settings.options.semanticallyStrict && errorsFound.length === 1) { - // Only one? Being strict? Just output it. - $helpBlock.html(errorsFound[0] + - ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); - } else { - // Multiple? Being sloppy? Glue them together into an UL. - $helpBlock.html("
  • " + errorsFound.join("
  • ") + "
" + - ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); - } - } else { - $controlGroup.removeClass("warning error success"); - if (value.length > 0) { - $controlGroup.addClass("success"); - } - $helpBlock.html($helpBlock.data("original-contents")); - } + $.each(errorMessages, function (i, el) { + if (el.length === 0) { + delete errorMessages[i]; + } + }); - if (e.type === "blur") { - $controlGroup.removeClass("success"); - } - } - ); - $this.bind("validationLostFocus.validation", function () { - $controlGroup.removeClass("success"); - }); - }); - }, - destroy : function( ) { - - return this.each( - function() { - - var - $this = $(this), - $controlGroup = $this.parents(".form-group").first(), - $helpBlock = $controlGroup.find(".help-block").first(), - $form = $this.parents("form").first(); - - // remove our events - $this.unbind('.validation'); // events are namespaced. - $form.unbind(".validationSubmit"); - // reset help text - $helpBlock.html($helpBlock.data("original-contents")); - // reset classes - $controlGroup.attr("class", $controlGroup.data("original-classes")); - // reset aria - $this.attr("aria-invalid", $this.data("original-aria-invalid")); - // reset role - $helpBlock.attr("role", $this.data("original-role")); - // remove all elements we created - if ($.inArray($helpBlock[0], createdElements) > -1) { - $helpBlock.remove(); - } + return errorMessages; + + }, + hasErrors: function () { + + var errorMessages = []; + + this.find('input,select,textarea').add(this).each(function (i, el) { + errorMessages = errorMessages.concat( + $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] + ); + }); - } - ); - - }, - collectErrors : function(includeEmpty) { - - var errorMessages = {}; - this.each(function (i, el) { - var $el = $(el); - var name = $el.attr("name"); - var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); - errorMessages[name] = $.extend(true, errors, errorMessages[name]); - }); - - $.each(errorMessages, function (i, el) { - if (el.length === 0) { - delete errorMessages[i]; - } - }); - - return errorMessages; - - }, - hasErrors: function() { - - var errorMessages = []; - - this.find('input,select,textarea').add(this).each(function (i, el) { - errorMessages = errorMessages.concat( - $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] - ); - }); - - return (errorMessages.length > 0); - }, - override : function (newDefaults) { - defaults = $.extend(true, defaults, newDefaults); - } - }, - validatorTypes: { - callback: { + return (errorMessages.length > 0); + }, + override: function (newDefaults) { + defaults = $.extend(true, defaults, newDefaults); + } + }, + validatorTypes: { + callback: { name: "callback", - init: function($this, name) { + init: function ($this, name) { var result = { validatorName: name, callback: $this.data("validation" + name + "Callback"), @@ -678,13 +679,12 @@ return result; }, - validate: function($this, value, validator) { + validate: function ($this, value, validator) { if (validator.lastValue === value && validator.lastFinished) { return !validator.lastValid; } - if (validator.lastFinished === true) - { + if (validator.lastFinished === true) { validator.lastValue = value; validator.lastValid = true; validator.lastFinished = false; @@ -696,7 +696,7 @@ window, $this, value, - function(data) { + function (data) { if (rrjqbvValidator.lastValue === data.value) { rrjqbvValidator.lastValid = data.valid; if (data.message) { @@ -704,12 +704,12 @@ } rrjqbvValidator.lastFinished = true; rrjqbvThis.data( - "validation" + rrjqbvValidator.validatorName + "Message", + "validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message ); - + // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function() { + setTimeout(function () { if (!$this.is(":focus") && $this.parents("form").first().data("jqbvIsSubmitting")) { rrjqbvThis.trigger("blur.validation"); } else { @@ -724,481 +724,493 @@ return false; } - }, - ajax: { - name: "ajax", - init: function ($this, name) { - return { - validatorName: name, - url: $this.data("validation" + name + "Ajax"), - lastValue: $this.val(), - lastValid: true, - lastFinished: true - }; - }, - validate: function ($this, value, validator) { - if (""+validator.lastValue === ""+value && validator.lastFinished === true) { - return validator.lastValid === false; - } - - if (validator.lastFinished === true) - { - validator.lastValue = value; - validator.lastValid = true; - validator.lastFinished = false; - $.ajax({ - url: validator.url, - data: "value=" + encodeURIComponent(value) + "&field=" + $this.attr("name"), - dataType: "json", - success: function (data) { - if (""+validator.lastValue === ""+data.value) { - validator.lastValid = !!(data.valid); - if (data.message) { - validator.message = data.message; - } - validator.lastFinished = true; - $this.data("validation" + validator.validatorName + "Message", validator.message); - // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function () { - $this.trigger("revalidate.validation"); - }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + }, + ajax: { + name: "ajax", + init: function ($this, name) { + return { + validatorName: name, + url: $this.data("validation" + name + "Ajax"), + lastValue: $this.val(), + lastValid: true, + lastFinished: true + }; + }, + validate: function ($this, value, validator) { + if ("" + validator.lastValue === "" + value && validator.lastFinished === true) { + return validator.lastValid === false; + } + + if (validator.lastFinished === true) { + validator.lastValue = value; + validator.lastValid = true; + validator.lastFinished = false; + $.ajax({ + url: validator.url, + data: "value=" + encodeURIComponent(value) + "&field=" + $this.attr("name"), + dataType: "json", + success: function (data) { + if ("" + validator.lastValue === "" + data.value) { + validator.lastValid = !!(data.valid); + if (data.message) { + validator.message = data.message; + } + validator.lastFinished = true; + $this.data("validation" + validator.validatorName + "Message", validator.message); + // Timeout is set to avoid problems with the events being considered 'already fired' + setTimeout(function () { + $this.trigger("revalidate.validation"); + }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + } + }, + failure: function () { + validator.lastValid = true; + validator.message = "ajax call failed"; + validator.lastFinished = true; + $this.data("validation" + validator.validatorName + "Message", validator.message); + // Timeout is set to avoid problems with the events being considered 'already fired' + setTimeout(function () { + $this.trigger("revalidate.validation"); + }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + } + }); + } + + return false; + } - }, - failure: function () { - validator.lastValid = true; - validator.message = "ajax call failed"; - validator.lastFinished = true; - $this.data("validation" + validator.validatorName + "Message", validator.message); - // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function () { - $this.trigger("revalidate.validation"); - }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst - } - }); - } - - return false; + }, + regex: { + name: "regex", + init: function ($this, name) { + var result = {}; + var regexString = $this.data("validation" + name + "Regex"); + result.regex = regexFromString(regexString); + if (regexString === undefined) { + $.error("Can't find regex for '" + name + "' validator on '" + $this.attr("name") + "'"); + } - } - }, - regex: { - name: "regex", - init: function ($this, name) { - var result = {}; - var regexString = $this.data("validation" + name + "Regex"); - result.regex = regexFromString(regexString); - if (regexString === undefined) { - $.error("Can't find regex for '" + name + "' validator on '" + $this.attr("name") + "'"); - } - - var message = "Not in the expected format"; - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - - result.message = message; - - result.originalName = name; - return result; - }, - validate: function ($this, value, validator) { - return (!validator.regex.test(value) && ! validator.negative) || - (validator.regex.test(value) && validator.negative); - } - }, - email: { - name: "email", - init: function ($this, name) { - var result = {}; - result.regex = regexFromString('[a-zA-Z0-9.!#$%&\u2019*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}'); - - var message = "Not a valid email address"; - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - - result.message = message; - - result.originalName = name; - return result; - }, - validate: function ($this, value, validator) { - return (!validator.regex.test(value) && ! validator.negative) || - (validator.regex.test(value) && validator.negative); - } - }, - required: { - name: "required", - init: function ($this, name) { - var message = "This is required"; - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - - return {message: message, includeEmpty: true}; - }, - validate: function ($this, value, validator) { - return !!( - (value.length === 0 && !validator.negative) || - (value.length > 0 && validator.negative) - ); - }, - blockSubmit: true - }, - match: { - name: "match", - init: function ($this, name) { - var elementName = $this.data("validation" + name + "Match"); - var $form = $this.parents("form").first(); - var $element = $form.find("[name=\"" + elementName + "\"]").first(); - $element.bind("validation.validation", function () { - $this.trigger("revalidate.validation", {submitting: true}); - }); - var result = {}; - result.element = $element; - - if ($element.length === 0) { - $.error("Can't find field '" + elementName + "' to match '" + $this.attr("name") + "' against in '" + name + "' validator"); - } - - var message = "Must match"; - var $label = null; - if (($label = $form.find("label[for=\"" + elementName + "\"]")).length) { - message += " '" + $label.text() + "'"; - } else if (($label = $element.parents(".form-group").first().find("label")).length) { - message += " '" + $label.first().text() + "'"; - } - - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - - result.message = message; - - return result; - }, - validate: function ($this, value, validator) { - return (value !== validator.element.val() && ! validator.negative) || - (value === validator.element.val() && validator.negative); - }, - blockSubmit: true, - includeEmpty: true - }, - max: { - name: "max", - init: function ($this, name) { - var result = {}; - - result.max = $this.data("validation" + name + "Max"); - - result.message = "Too high: Maximum of '" + result.max + "'"; - if ($this.data("validation" + name + "Message")) { - result.message = $this.data("validation" + name + "Message"); - } - - return result; - }, - validate: function ($this, value, validator) { - return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) || - (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); - } - }, - min: { - name: "min", - init: function ($this, name) { - var result = {}; - - result.min = $this.data("validation" + name + "Min"); - - result.message = "Too low: Minimum of '" + result.min + "'"; - if ($this.data("validation" + name + "Message")) { - result.message = $this.data("validation" + name + "Message"); - } - - return result; - }, - validate: function ($this, value, validator) { - return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) || - (parseFloat(value) >= parseFloat(validator.min) && validator.negative); - } - }, - maxlength: { - name: "maxlength", - init: function ($this, name) { - var result = {}; - - result.maxlength = $this.data("validation" + name + "Maxlength"); - - result.message = "Too long: Maximum of '" + result.maxlength + "' characters"; - if ($this.data("validation" + name + "Message")) { - result.message = $this.data("validation" + name + "Message"); - } - - return result; - }, - validate: function ($this, value, validator) { - return ((value.length > validator.maxlength) && ! validator.negative) || - ((value.length <= validator.maxlength) && validator.negative); - } - }, - minlength: { - name: "minlength", - init: function ($this, name) { - var result = {}; - - result.minlength = $this.data("validation" + name + "Minlength"); - - result.message = "Too short: Minimum of '" + result.minlength + "' characters"; - if ($this.data("validation" + name + "Message")) { - result.message = $this.data("validation" + name + "Message"); - } - - return result; - }, - validate: function ($this, value, validator) { - return ((value.length < validator.minlength) && ! validator.negative) || - ((value.length >= validator.minlength) && validator.negative); - } - }, - maxchecked: { - name: "maxchecked", - init: function ($this, name) { - var result = {}; - - var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); - elements.bind("change.validation click.validation", function () { - $this.trigger("revalidate.validation", {includeEmpty: true}); - }); - - result.elements = elements; - result.maxchecked = $this.data("validation" + name + "Maxchecked"); - - var message = "Too many: Max '" + result.maxchecked + "' checked"; - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - result.message = message; - - return result; - }, - validate: function ($this, value, validator) { - return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) || - (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); - }, - blockSubmit: true - }, - minchecked: { - name: "minchecked", - init: function ($this, name) { - var result = {}; - - var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); - elements.bind("change.validation click.validation", function () { - $this.trigger("revalidate.validation", {includeEmpty: true}); - }); - - result.elements = elements; - result.minchecked = $this.data("validation" + name + "Minchecked"); - - var message = "Too few: Min '" + result.minchecked + "' checked"; - if ($this.data("validation" + name + "Message")) { - message = $this.data("validation" + name + "Message"); - } - result.message = message; - - return result; - }, - validate: function ($this, value, validator) { - return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) || - (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); - }, - blockSubmit: true, - includeEmpty: true - }, - number: { - name: "number", - init: function ($this, name) { - var result = {}; - result.step = 1; - if ($this.attr("step")) { - result.step = $this.attr("step"); - } - if ($this.data("validation" + name + "Step")) { - result.step = $this.data("validation" + name + "Step"); - } - - result.decimal = "."; - if ($this.data("validation" + name + "Decimal")) { - result.decimal = $this.data("validation" + name + "Decimal"); - } - - result.thousands = ""; - if ($this.data("validation" + name + "Thousands")) { - result.thousands = $this.data("validation" + name + "Thousands"); - } - - result.regex = regexFromString("([+-]?\\d+(\\" + result.decimal + "\\d+)?)?"); - - result.message = "Must be a number"; - var dataMessage = $this.data("validation" + name + "Message"); - if (dataMessage) { - result.message = dataMessage; - } - - return result; - }, - validate: function ($this, value, validator) { - var globalValue = value.replace(validator.decimal, ".").replace(validator.thousands, ""); - var multipliedValue = parseFloat(globalValue); - var multipliedStep = parseFloat(validator.step); - while (multipliedStep % 1 !== 0) { - /* thanks to @jkey #57 */ - multipliedStep = parseFloat(multipliedStep.toPrecision(12)) * 10; - multipliedValue = parseFloat(multipliedValue.toPrecision(12)) * 10; - } - var regexResult = validator.regex.test(value); - var stepResult = parseFloat(multipliedValue) % parseFloat(multipliedStep) === 0; - var typeResult = !isNaN(parseFloat(globalValue)) && isFinite(globalValue); - var result = !(regexResult && stepResult && typeResult); - return result; + var message = "Not in the expected format"; + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + + result.message = message; + + result.originalName = name; + return result; + }, + validate: function ($this, value, validator) { + return (!validator.regex.test(value) && !validator.negative) || + (validator.regex.test(value) && validator.negative); + } + }, + email: { + name: "email", + init: function ($this, name) { + var result = {}; + result.regex = regexFromString('[a-zA-Z0-9.!#$%&\u2019*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}'); + + var message = "Not a valid email address"; + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + + result.message = message; + + result.originalName = name; + return result; + }, + validate: function ($this, value, validator) { + return (!validator.regex.test(value) && !validator.negative) || + (validator.regex.test(value) && validator.negative); + } + }, + required: { + name: "required", + init: function ($this, name) { + var message = "This is required"; + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + + return {message: message, includeEmpty: true}; + }, + validate: function ($this, value, validator) { + return !!( + (value.length === 0 && !validator.negative) || + (value.length > 0 && validator.negative) + ); + }, + blockSubmit: true + }, + match: { + name: "match", + init: function ($this, name) { + var elementName = $this.data("validation" + name + "Match"); + var $form = $this.parents("form").first(); + var $element = $form.find("[name=\"" + elementName + "\"]").first(); + $element.bind("validation.validation", function () { + $this.trigger("revalidate.validation", {submitting: true}); + }); + var result = {}; + result.element = $element; + + if ($element.length === 0) { + $.error("Can't find field '" + elementName + "' to match '" + $this.attr("name") + "' against in '" + name + "' validator"); + } + + var message = "Must match"; + var $label = null; + if (($label = $form.find("label[for=\"" + elementName + "\"]")).length) { + message += " '" + $label.text() + "'"; + } else if (($label = $element.parents(".form-group").first().find("label")).length) { + message += " '" + $label.first().text() + "'"; + } + + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + + result.message = message; + + return result; + }, + validate: function ($this, value, validator) { + return (value !== validator.element.val() && !validator.negative) || + (value === validator.element.val() && validator.negative); + }, + blockSubmit: true, + includeEmpty: true + }, + max: { + name: "max", + init: function ($this, name) { + var result = {}; + + result.max = $this.data("validation" + name + "Max"); + + result.message = "Too high: Maximum of '" + result.max + "'"; + if ($this.data("validation" + name + "Message")) { + result.message = $this.data("validation" + name + "Message"); + } + + return result; + }, + validate: function ($this, value, validator) { + return (parseFloat(value, 10) > parseFloat(validator.max, 10) && !validator.negative) || + (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); + } + }, + min: { + name: "min", + init: function ($this, name) { + var result = {}; + + result.min = $this.data("validation" + name + "Min"); + + result.message = "Too low: Minimum of '" + result.min + "'"; + if ($this.data("validation" + name + "Message")) { + result.message = $this.data("validation" + name + "Message"); + } + + return result; + }, + validate: function ($this, value, validator) { + return (parseFloat(value) < parseFloat(validator.min) && !validator.negative) || + (parseFloat(value) >= parseFloat(validator.min) && validator.negative); + } + }, + maxlength: { + name: "maxlength", + init: function ($this, name) { + var result = {}; + + result.maxlength = $this.data("validation" + name + "Maxlength"); + + result.message = "Too long: Maximum of '" + result.maxlength + "' characters"; + if ($this.data("validation" + name + "Message")) { + result.message = $this.data("validation" + name + "Message"); + } + + return result; + }, + validate: function ($this, value, validator) { + return ((value.length > validator.maxlength) && !validator.negative) || + ((value.length <= validator.maxlength) && validator.negative); + } + }, + minlength: { + name: "minlength", + init: function ($this, name) { + var result = {}; + + result.minlength = $this.data("validation" + name + "Minlength"); + + result.message = "Too short: Minimum of '" + result.minlength + "' characters"; + if ($this.data("validation" + name + "Message")) { + result.message = $this.data("validation" + name + "Message"); + } + + return result; + }, + validate: function ($this, value, validator) { + return ((value.length < validator.minlength) && !validator.negative) || + ((value.length >= validator.minlength) && validator.negative); + } + }, + maxchecked: { + name: "maxchecked", + init: function ($this, name) { + var result = {}; + + var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); + elements.bind("change.validation click.validation", function () { + $this.trigger("revalidate.validation", {includeEmpty: true}); + }); + + result.elements = elements; + result.maxchecked = $this.data("validation" + name + "Maxchecked"); + + var message = "Too many: Max '" + result.maxchecked + "' checked"; + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + result.message = message; + + return result; + }, + validate: function ($this, value, validator) { + return (validator.elements.filter(":checked").length > validator.maxchecked && !validator.negative) || + (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); + }, + blockSubmit: true + }, + minchecked: { + name: "minchecked", + init: function ($this, name) { + var result = {}; + + var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); + elements.bind("change.validation click.validation", function () { + $this.trigger("revalidate.validation", {includeEmpty: true}); + }); + + result.elements = elements; + result.minchecked = $this.data("validation" + name + "Minchecked"); + + var message = "Too few: Min '" + result.minchecked + "' checked"; + if ($this.data("validation" + name + "Message")) { + message = $this.data("validation" + name + "Message"); + } + result.message = message; + + return result; + }, + validate: function ($this, value, validator) { + return (validator.elements.filter(":checked").length < validator.minchecked && !validator.negative) || + (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); + }, + blockSubmit: true, + includeEmpty: true + }, + number: { + name: "number", + init: function ($this, name) { + var result = {}; + result.step = 1; + if ($this.attr("step")) { + result.step = $this.attr("step"); + } + if ($this.data("validation" + name + "Step")) { + result.step = $this.data("validation" + name + "Step"); + } + + result.decimal = "."; + if ($this.data("validation" + name + "Decimal")) { + result.decimal = $this.data("validation" + name + "Decimal"); + } + + result.thousands = ""; + if ($this.data("validation" + name + "Thousands")) { + result.thousands = $this.data("validation" + name + "Thousands"); + } + + result.regex = regexFromString("([+-]?\\d+(\\" + result.decimal + "\\d+)?)?"); + + result.message = "Must be a number"; + var dataMessage = $this.data("validation" + name + "Message"); + if (dataMessage) { + result.message = dataMessage; + } + + return result; + }, + validate: function ($this, value, validator) { + var globalValue = value.replace(validator.decimal, ".").replace(validator.thousands, ""); + var multipliedValue = parseFloat(globalValue); + var multipliedStep = parseFloat(validator.step); + while (multipliedStep % 1 !== 0) { + /* thanks to @jkey #57 */ + multipliedStep = parseFloat(multipliedStep.toPrecision(12)) * 10; + multipliedValue = parseFloat(multipliedValue.toPrecision(12)) * 10; + } + var regexResult = validator.regex.test(value); + var stepResult = parseFloat(multipliedValue) % parseFloat(multipliedStep) === 0; + var typeResult = !isNaN(parseFloat(globalValue)) && isFinite(globalValue); + var result = !(regexResult && stepResult && typeResult); + return result; + }, + message: "Must be a number" + } }, - message: "Must be a number" - } - }, - builtInValidators: { - email: { - name: "Email", - type: "email" - }, - passwordagain: { - name: "Passwordagain", - type: "match", - match: "password", - message: "Does not match the given password" - }, - positive: { - name: "Positive", - type: "shortcut", - shortcut: "number,positivenumber" - }, - negative: { - name: "Negative", - type: "shortcut", - shortcut: "number,negativenumber" - }, - integer: { - name: "Integer", - type: "regex", - regex: "[+-]?\\d+", - message: "No decimal places allowed" - }, - positivenumber: { - name: "Positivenumber", - type: "min", - min: 0, - message: "Must be a positive number" - }, - negativenumber: { - name: "Negativenumber", - type: "max", - max: 0, - message: "Must be a negative number" - }, - required: { - name: "Required", - type: "required", - message: "This is required" - }, - checkone: { - name: "Checkone", - type: "minchecked", - minchecked: 1, - message: "Check at least one option" - }, - number: { - name: "Number", - type: "number", - decimal: ".", - step: "1" - }, - pattern: { - name: "Pattern", - type: "regex", - message: "Not in expected format" - } - } - }; - - var formatValidatorName = function (name) { - return name - .toLowerCase() - .replace( - /(^|\s)([a-z])/g , - function(m,p1,p2) { - return p1+p2.toUpperCase(); - } - ) - ; - }; - - var getValue = function ($this) { - // Extract the value we're talking about - var value = null; - var type = $this.attr("type"); - if (type === "checkbox") { - value = ($this.is(":checked") ? value : ""); - var checkboxParent = $this.parents("form").first() || $this.parents(".form-group").first(); - if (checkboxParent) { - value = checkboxParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); }).toArray().join(","); - } - } - else if (type === "radio") { - value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? $this.val() : ""); - var radioParent = $this.parents("form").first() || $this.parents(".form-group").first(); - if (radioParent) { - value = radioParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { return $(el).val(); }).toArray().join(","); - } - } - else { - value = $this.val(); + builtInValidators: { + email: { + name: "Email", + type: "email" + }, + passwordagain: { + name: "Passwordagain", + type: "match", + match: "password", + message: "Does not match the given password" + }, + positive: { + name: "Positive", + type: "shortcut", + shortcut: "number,positivenumber" + }, + negative: { + name: "Negative", + type: "shortcut", + shortcut: "number,negativenumber" + }, + integer: { + name: "Integer", + type: "regex", + regex: "[+-]?\\d+", + message: "No decimal places allowed" + }, + positivenumber: { + name: "Positivenumber", + type: "min", + min: 0, + message: "Must be a positive number" + }, + negativenumber: { + name: "Negativenumber", + type: "max", + max: 0, + message: "Must be a negative number" + }, + required: { + name: "Required", + type: "required", + message: "This is required" + }, + checkone: { + name: "Checkone", + type: "minchecked", + minchecked: 1, + message: "Check at least one option" + }, + number: { + name: "Number", + type: "number", + decimal: ".", + step: "1" + }, + pattern: { + name: "Pattern", + type: "regex", + message: "Not in expected format" + } + } + }; + + var formatValidatorName = function (name) { + return name + .toLowerCase() + .replace( + /(^|\s)([a-z])/g, + function (m, p1, p2) { + return p1 + p2.toUpperCase(); + } + ) + ; + }; + + var getValue = function ($this) { + // Extract the value we're talking about + var value = null; + var type = $this.attr("type"); + if (type === "checkbox") { + value = ($this.is(":checked") ? value : ""); + var checkboxParent = $this.parents("form").first() || $this.parents(".form-group").first(); + if (checkboxParent) { + value = checkboxParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { + return $(el).val(); + }).toArray().join(","); + } + } + else if (type === "radio") { + value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? $this.val() : ""); + var radioParent = $this.parents("form").first() || $this.parents(".form-group").first(); + if (radioParent) { + value = radioParent.find("input[name='" + $this.attr("name") + "']:checked").map(function (i, el) { + return $(el).val(); + }).toArray().join(","); + } + } else if (type === "number") { + if ($this[0].validity.valid) { + value = $this.val(); + } else { + if ($this[0].validity.badInput || $this[0].validity.stepMismatch) { + value = "NaN"; + } else { + value = ""; + } + } + } else { + value = $this.val(); + } + return value; + }; + + function regexFromString(inputstring) { + return new RegExp("^" + inputstring + "$"); } - return value; - }; - - function regexFromString(inputstring) { - return new RegExp("^" + inputstring + "$"); - } - - /** - * Thanks to Jason Bunting / Alex Nazarov via StackOverflow.com - * - * http://stackoverflow.com/a/4351575 - **/ -function executeFunctionByName(functionName, context /*, args */) { - var args = Array.prototype.slice.call(arguments, 2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for (var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; + + /** + * Thanks to Jason Bunting / Alex Nazarov via StackOverflow.com + * + * http://stackoverflow.com/a/4351575 + **/ + function executeFunctionByName(functionName, context /*, args */) { + var args = Array.prototype.slice.call(arguments, 2); + var namespaces = functionName.split("."); + var func = namespaces.pop(); + for (var i = 0; i < namespaces.length; i++) { + context = context[namespaces[i]]; + } + return context[func].apply(context, args); } - return context[func].apply(context, args); -} -$.fn.jqBootstrapValidation = function( method ) { + $.fn.jqBootstrapValidation = function (method) { - if ( defaults.methods[method] ) { - return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return defaults.methods.init.apply( this, arguments ); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); - return null; - } + if (defaults.methods[method]) { + return defaults.methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return defaults.methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.jqBootstrapValidation'); + return null; + } -}; + }; - $.jqBootstrapValidation = function (options) { - $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); - }; + $.jqBootstrapValidation = function (options) { + $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this, arguments); + }; -})( jQuery ); \ No newline at end of file +})(jQuery); diff --git a/dist/jqBootstrapValidation-1.3.7.min.js b/dist/jqBootstrapValidation-1.3.7.min.js index b9a7f85..28c195b 100644 --- a/dist/jqBootstrapValidation-1.3.7.min.js +++ b/dist/jqBootstrapValidation-1.3.7.min.js @@ -1,4 +1,4 @@ -/*! jqBootstrapValidation - v1.3.7 - 2013-05-07 +/*! jqBootstrapValidation - v1.3.7 - 2014-08-15 * http://reactiveraven.github.com/jqBootstrapValidation -* Copyright (c) 2013 David Godfrey; Licensed MIT */ -(function(e){function s(e){return new RegExp("^"+e+"$")}function o(e,t){var n=Array.prototype.slice.call(arguments,2),r=e.split("."),i=r.pop();for(var s=0;s0});u.trigger("submit.validation"),i.trigger("validationLostFocus.validation"),s.each(function(t,n){var i=e(n);if(i.hasClass("warning")||i.hasClass("error"))i.removeClass("warning").addClass("error"),r++}),r?(o.options.preventSubmit&&(t.preventDefault(),t.stopImmediatePropagation()),n.addClass("error"),e.isFunction(o.options.submitError)&&o.options.submitError(n,t,u.jqBootstrapValidation("collectErrors",!0))):(n.removeClass("error"),e.isFunction(o.options.submitSuccess)&&o.options.submitSuccess(n,t))}),this.each(function(){var n=e(this),s=n.parents(".form-group").first(),u=s.find(".help-block").first(),a=n.parents("form").first(),f=[];!u.length&&o.options.autoAdd&&o.options.autoAdd.helpBlocks&&(u=e('
'),s.find(".controls").append(u),t.push(u[0]));if(o.options.sniffHtml){var l;n.data("validationPatternPattern")&&n.attr("pattern",n.data("validationPatternPattern")),n.attr("pattern")!==undefined&&(l="Not in the expected format",n.data("validationPatternMessage")&&(l=n.data("validationPatternMessage")),n.data("validationPatternMessage",l),n.data("validationPatternRegex",n.attr("pattern")));if(n.attr("max")!==undefined||n.attr("aria-valuemax")!==undefined){var c=n.attr("max")!==undefined?n.attr("max"):n.attr("aria-valuemax");l="Too high: Maximum of '"+c+"'",n.data("validationMaxMessage")&&(l=n.data("validationMaxMessage")),n.data("validationMaxMessage",l),n.data("validationMaxMax",c)}if(n.attr("min")!==undefined||n.attr("aria-valuemin")!==undefined){var h=n.attr("min")!==undefined?n.attr("min"):n.attr("aria-valuemin");l="Too low: Minimum of '"+h+"'",n.data("validationMinMessage")&&(l=n.data("validationMinMessage")),n.data("validationMinMessage",l),n.data("validationMinMin",h)}n.attr("maxlength")!==undefined&&(l="Too long: Maximum of '"+n.attr("maxlength")+"' characters",n.data("validationMaxlengthMessage")&&(l=n.data("validationMaxlengthMessage")),n.data("validationMaxlengthMessage",l),n.data("validationMaxlengthMaxlength",n.attr("maxlength"))),n.attr("minlength")!==undefined&&(l="Too short: Minimum of '"+n.attr("minlength")+"' characters",n.data("validationMinlengthMessage")&&(l=n.data("validationMinlengthMessage")),n.data("validationMinlengthMessage",l),n.data("validationMinlengthMinlength",n.attr("minlength")));if(n.attr("required")!==undefined||n.attr("aria-required")!==undefined)l=o.builtInValidators.required.message,n.data("validationRequiredMessage")&&(l=n.data("validationRequiredMessage")),n.data("validationRequiredMessage",l);if(n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="number"){l=o.validatorTypes.number.message,n.data("validationNumberMessage")&&(l=n.data("validationNumberMessage")),n.data("validationNumberMessage",l);var p=o.validatorTypes.number.step;n.data("validationNumberStep")&&(p=n.data("validationNumberStep")),n.data("validationNumberStep",p);var d=o.validatorTypes.number.decimal;n.data("validationNumberDecimal")&&(d=n.data("validationNumberDecimal")),n.data("validationNumberDecimal",d)}n.attr("type")!==undefined&&n.attr("type").toLowerCase()==="email"&&(l="Not a valid email address",n.data("validationEmailMessage")&&(l=n.data("validationEmailMessage")),n.data("validationEmailMessage",l)),n.attr("minchecked")!==undefined&&(l="Not enough options checked; Minimum of '"+n.attr("minchecked")+"' required",n.data("validationMincheckedMessage")&&(l=n.data("validationMincheckedMessage")),n.data("validationMincheckedMessage",l),n.data("validationMincheckedMinchecked",n.attr("minchecked"))),n.attr("maxchecked")!==undefined&&(l="Too many options checked; Maximum of '"+n.attr("maxchecked")+"' required",n.data("validationMaxcheckedMessage")&&(l=n.data("validationMaxcheckedMessage")),n.data("validationMaxcheckedMessage",l),n.data("validationMaxcheckedMaxchecked",n.attr("maxchecked")))}n.data("validation")!==undefined&&(f=n.data("validation").split(",")),e.each(n.data(),function(e,t){var n=e.replace(/([A-Z])/g,",$1").split(",");n[0]==="validation"&&n[1]&&f.push(n[1])});var v=f,m=[],g=function(e,t){f[e]=r(t)},y=function(t,i){if(n.data("validation"+i+"Shortcut")!==undefined)e.each(n.data("validation"+i+"Shortcut").split(","),function(e,t){m.push(t)});else if(o.builtInValidators[i.toLowerCase()]){var s=o.builtInValidators[i.toLowerCase()];s.type.toLowerCase()==="shortcut"&&e.each(s.shortcut.split(","),function(e,t){t=r(t),m.push(t),f.push(t)})}};do e.each(f,g),f=e.unique(f),m=[],e.each(v,y),v=m;while(v.length>0);var b={};e.each(f,function(t,i){var s=n.data("validation"+i+"Message"),u=!!s,a=!1;s||(s="'"+i+"' validation failed "),e.each(o.validatorTypes,function(t,o){b[t]===undefined&&(b[t]=[]);if(!a&&n.data("validation"+i+r(o.name))!==undefined){var f=o.init(n,i);u&&(f.message=s),b[t].push(e.extend(!0,{name:r(o.name),message:s},f)),a=!0}});if(!a&&o.builtInValidators[i.toLowerCase()]){var f=e.extend(!0,{},o.builtInValidators[i.toLowerCase()]);u&&(f.message=s);var l=f.type.toLowerCase();l==="shortcut"?a=!0:e.each(o.validatorTypes,function(t,s){b[t]===undefined&&(b[t]=[]),!a&&l===t.toLowerCase()&&(n.data("validation"+i+r(s.name),f[s.name.toLowerCase()]),b[l].push(e.extend(f,s.init(n,i))),a=!0)})}a||e.error("Cannot find validation info for '"+i+"'")}),u.data("original-contents",u.data("original-contents")?u.data("original-contents"):u.html()),u.data("original-role",u.data("original-role")?u.data("original-role"):u.attr("role")),s.data("original-classes",s.data("original-clases")?s.data("original-classes"):s.attr("class")),n.data("original-aria-invalid",n.data("original-aria-invalid")?n.data("original-aria-invalid"):n.attr("aria-invalid")),n.bind("validation.validation",function(t,r){var s=i(n),u=[];return e.each(b,function(t,i){(s||s.length||r&&r.includeEmpty||!!o.validatorTypes[t].includeEmpty||!!o.validatorTypes[t].blockSubmit&&r&&!!r.submitting)&&e.each(i,function(e,r){o.validatorTypes[t].validate(n,s,r)&&u.push(r.message)})}),u}),n.bind("getValidators.validation",function(){return b});var w=0;e.each(b,function(e,t){w+=t.length}),n.bind("getValidatorCount.validation",function(){return w}),n.bind("submit.validation",function(){return n.triggerHandler("change.validation",{submitting:!0})}),n.bind((o.options.bindEvents.length>0?o.options.bindEvents:["keyup","focus","blur","click","keydown","keypress","change"]).concat(["revalidate"]).join(".validation ")+".validation",function(t,r){var f=i(n),l=[];r&&!!r.submitting?s.data("jqbvIsSubmitting",!0):t.type!=="revalidate"&&s.data("jqbvIsSubmitting",!1);var c=!!s.data("jqbvIsSubmitting");s.find("input,textarea,select").each(function(t,i){var s=l.length;e.each(e(i).triggerHandler("validation.validation",r),function(e,t){l.push(t)});if(l.length>s)e(i).attr("aria-invalid","true");else{var o=n.data("original-aria-invalid");e(i).attr("aria-invalid",o!==undefined?o:!1)}}),a.find("input,select,textarea").not(n).not('[name="'+n.attr("name")+'"]').trigger("validationLostFocus.validation"),l=e.unique(l.sort()),l.length?(s.removeClass("success error warning").addClass(c?"error":"warning"),o.options.semanticallyStrict&&l.length===1?u.html(l[0]+(o.options.prependExistingHelpBlock?u.data("original-contents"):"")):u.html('
  • '+l.join("
  • ")+"
"+(o.options.prependExistingHelpBlock?u.data("original-contents"):""))):(s.removeClass("warning error success"),f.length>0&&s.addClass("success"),u.html(u.data("original-contents"))),t.type==="blur"&&s.removeClass("success")}),n.bind("validationLostFocus.validation",function(){s.removeClass("success")})})},destroy:function(){return this.each(function(){var n=e(this),r=n.parents(".form-group").first(),i=r.find(".help-block").first(),s=n.parents("form").first();n.unbind(".validation"),s.unbind(".validationSubmit"),i.html(i.data("original-contents")),r.attr("class",r.data("original-classes")),n.attr("aria-invalid",n.data("original-aria-invalid")),i.attr("role",n.data("original-role")),e.inArray(i[0],t)>-1&&i.remove()})},collectErrors:function(t){var n={};return this.each(function(t,r){var i=e(r),s=i.attr("name"),o=i.triggerHandler("validation.validation",{includeEmpty:!0});n[s]=e.extend(!0,o,n[s])}),e.each(n,function(e,t){t.length===0&&delete n[e]}),n},hasErrors:function(){var t=[];return this.find("input,select,textarea").add(this).each(function(n,r){t=t.concat(e(r).triggerHandler("getValidators.validation")?e(r).triggerHandler("validation.validation",{submitting:!0}):[])}),t.length>0},override:function(t){n=e.extend(!0,n,t)}},validatorTypes:{callback:{name:"callback",init:function(e,t){var n={validatorName:t,callback:e.data("validation"+t+"Callback"),lastValue:e.val(),lastValid:!0,lastFinished:!0},r="Not valid";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n},validate:function(e,t,n){if(n.lastValue===t&&n.lastFinished)return!n.lastValid;if(n.lastFinished===!0){n.lastValue=t,n.lastValid=!0,n.lastFinished=!1;var r=n,i=e;o(n.callback,window,e,t,function(t){r.lastValue===t.value&&(r.lastValid=t.valid,t.message&&(r.message=t.message),r.lastFinished=!0,i.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){!e.is(":focus")&&e.parents("form").first().data("jqbvIsSubmitting")?i.trigger("blur.validation"):i.trigger("revalidate.validation")},1))})}return!1}},ajax:{name:"ajax",init:function(e,t){return{validatorName:t,url:e.data("validation"+t+"Ajax"),lastValue:e.val(),lastValid:!0,lastFinished:!0}},validate:function(t,n,r){return""+r.lastValue==""+n&&r.lastFinished===!0?r.lastValid===!1:(r.lastFinished===!0&&(r.lastValue=n,r.lastValid=!0,r.lastFinished=!1,e.ajax({url:r.url,data:"value="+encodeURIComponent(n)+"&field="+t.attr("name"),dataType:"json",success:function(e){""+r.lastValue==""+e.value&&(r.lastValid=!!e.valid,e.message&&(r.message=e.message),r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1))},failure:function(){r.lastValid=!0,r.message="ajax call failed",r.lastFinished=!0,t.data("validation"+r.validatorName+"Message",r.message),setTimeout(function(){t.trigger("revalidate.validation")},1)}})),!1)}},regex:{name:"regex",init:function(t,n){var r={},i=t.data("validation"+n+"Regex");r.regex=s(i),i===undefined&&e.error("Can't find regex for '"+n+"' validator on '"+t.attr("name")+"'");var o="Not in the expected format";return t.data("validation"+n+"Message")&&(o=t.data("validation"+n+"Message")),r.message=o,r.originalName=n,r},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},email:{name:"email",init:function(e,t){var n={};n.regex=s("[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");var r="Not a valid email address";return e.data("validation"+t+"Message")&&(r=e.data("validation"+t+"Message")),n.message=r,n.originalName=t,n},validate:function(e,t,n){return!n.regex.test(t)&&!n.negative||n.regex.test(t)&&n.negative}},required:{name:"required",init:function(e,t){var n="This is required";return e.data("validation"+t+"Message")&&(n=e.data("validation"+t+"Message")),{message:n,includeEmpty:!0}},validate:function(e,t,n){return!!(t.length===0&&!n.negative||t.length>0&&n.negative)},blockSubmit:!0},match:{name:"match",init:function(t,n){var r=t.data("validation"+n+"Match"),i=t.parents("form").first(),s=i.find('[name="'+r+'"]').first();s.bind("validation.validation",function(){t.trigger("revalidate.validation",{submitting:!0})});var o={};o.element=s,s.length===0&&e.error("Can't find field '"+r+"' to match '"+t.attr("name")+"' against in '"+n+"' validator");var u="Must match",a=null;return(a=i.find('label[for="'+r+'"]')).length?u+=" '"+a.text()+"'":(a=s.parents(".form-group").first().find("label")).length&&(u+=" '"+a.first().text()+"'"),t.data("validation"+n+"Message")&&(u=t.data("validation"+n+"Message")),o.message=u,o},validate:function(e,t,n){return t!==n.element.val()&&!n.negative||t===n.element.val()&&n.negative},blockSubmit:!0,includeEmpty:!0},max:{name:"max",init:function(e,t){var n={};return n.max=e.data("validation"+t+"Max"),n.message="Too high: Maximum of '"+n.max+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t,10)>parseFloat(n.max,10)&&!n.negative||parseFloat(t,10)<=parseFloat(n.max,10)&&n.negative}},min:{name:"min",init:function(e,t){var n={};return n.min=e.data("validation"+t+"Min"),n.message="Too low: Minimum of '"+n.min+"'",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return parseFloat(t)=parseFloat(n.min)&&n.negative}},maxlength:{name:"maxlength",init:function(e,t){var n={};return n.maxlength=e.data("validation"+t+"Maxlength"),n.message="Too long: Maximum of '"+n.maxlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length>n.maxlength&&!n.negative||t.length<=n.maxlength&&n.negative}},minlength:{name:"minlength",init:function(e,t){var n={};return n.minlength=e.data("validation"+t+"Minlength"),n.message="Too short: Minimum of '"+n.minlength+"' characters",e.data("validation"+t+"Message")&&(n.message=e.data("validation"+t+"Message")),n},validate:function(e,t,n){return t.length=n.minlength&&n.negative}},maxchecked:{name:"maxchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.maxchecked=e.data("validation"+t+"Maxchecked");var i="Too many: Max '"+n.maxchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length>n.maxchecked&&!n.negative||n.elements.filter(":checked").length<=n.maxchecked&&n.negative},blockSubmit:!0},minchecked:{name:"minchecked",init:function(e,t){var n={},r=e.parents("form").first().find('[name="'+e.attr("name")+'"]');r.bind("change.validation click.validation",function(){e.trigger("revalidate.validation",{includeEmpty:!0})}),n.elements=r,n.minchecked=e.data("validation"+t+"Minchecked");var i="Too few: Min '"+n.minchecked+"' checked";return e.data("validation"+t+"Message")&&(i=e.data("validation"+t+"Message")),n.message=i,n},validate:function(e,t,n){return n.elements.filter(":checked").length=n.minchecked&&n.negative},blockSubmit:!0,includeEmpty:!0},number:{name:"number",init:function(e,t){var n={};n.step=1,e.attr("step")&&(n.step=e.attr("step")),e.data("validation"+t+"Step")&&(n.step=e.data("validation"+t+"Step")),n.decimal=".",e.data("validation"+t+"Decimal")&&(n.decimal=e.data("validation"+t+"Decimal")),n.thousands="",e.data("validation"+t+"Thousands")&&(n.thousands=e.data("validation"+t+"Thousands")),n.regex=s("([+-]?\\d+(\\"+n.decimal+"\\d+)?)?"),n.message="Must be a number";var r=e.data("validation"+t+"Message");return r&&(n.message=r),n},validate:function(e,t,n){var r=t.replace(n.decimal,".").replace(n.thousands,""),i=parseFloat(r),s=parseFloat(n.step);while(s%1!==0)s=parseFloat(s.toPrecision(12))*10,i=parseFloat(i.toPrecision(12))*10;var o=n.regex.test(t),u=parseFloat(i)%parseFloat(s)===0,a=!isNaN(parseFloat(r))&&isFinite(r),f=!(o&&u&&a);return f},message:"Must be a number"}},builtInValidators:{email:{name:"Email",type:"email"},passwordagain:{name:"Passwordagain",type:"match",match:"password",message:"Does not match the given password"},positive:{name:"Positive",type:"shortcut",shortcut:"number,positivenumber"},negative:{name:"Negative",type:"shortcut",shortcut:"number,negativenumber"},integer:{name:"Integer",type:"regex",regex:"[+-]?\\d+",message:"No decimal places allowed"},positivenumber:{name:"Positivenumber",type:"min",min:0,message:"Must be a positive number"},negativenumber:{name:"Negativenumber",type:"max",max:0,message:"Must be a negative number"},required:{name:"Required",type:"required",message:"This is required"},checkone:{name:"Checkone",type:"minchecked",minchecked:1,message:"Check at least one option"},number:{name:"Number",type:"number",decimal:".",step:"1"},pattern:{name:"Pattern",type:"regex",message:"Not in expected format"}}},r=function(e){return e.toLowerCase().replace(/(^|\s)([a-z])/g,function(e,t,n){return t+n.toUpperCase()})},i=function(t){var n=null,r=t.attr("type");if(r==="checkbox"){n=t.is(":checked")?n:"";var i=t.parents("form").first()||t.parents(".form-group").first();i&&(n=i.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else if(r==="radio"){n=e('input[name="'+t.attr("name")+'"]:checked').length>0?t.val():"";var s=t.parents("form").first()||t.parents(".form-group").first();s&&(n=s.find("input[name='"+t.attr("name")+"']:checked").map(function(t,n){return e(n).val()}).toArray().join(","))}else n=t.val();return n};e.fn.jqBootstrapValidation=function(t){return n.methods[t]?n.methods[t].apply(this,Array.prototype.slice.call(arguments,1)):typeof t=="object"||!t?n.methods.init.apply(this,arguments):(e.error("Method "+t+" does not exist on jQuery.jqBootstrapValidation"),null)},e.jqBootstrapValidation=function(t){e(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments)}})(jQuery); \ No newline at end of file +* Copyright (c) 2014 David Godfrey; Licensed MIT */ +!function(a){function b(a){return new RegExp("^"+a+"$")}function c(a,b){for(var c=Array.prototype.slice.call(arguments,2),d=a.split("."),e=d.pop(),f=0;f0});h.trigger("submit.validation"),f.trigger("validationLostFocus.validation"),g.each(function(b,c){var d=a(c);(d.hasClass("warning")||d.hasClass("error"))&&(d.removeClass("warning").addClass("error"),e++)}),e?(c.options.preventSubmit&&(b.preventDefault(),b.stopImmediatePropagation()),d.addClass("error"),a.isFunction(c.options.submitError)&&c.options.submitError(d,b,h.jqBootstrapValidation("collectErrors",!0))):(d.removeClass("error"),a.isFunction(c.options.submitSuccess)&&c.options.submitSuccess(d,b))}),this.each(function(){var b=a(this),e=b.parents(".form-group").first(),h=e.find(".help-block").first(),i=b.parents("form").first(),j=[];if(!h.length&&c.options.autoAdd&&c.options.autoAdd.helpBlocks&&(h=a('
'),e.find(".controls").append(h),d.push(h[0])),c.options.sniffHtml){var k;if(b.data("validationPatternPattern")&&b.attr("pattern",b.data("validationPatternPattern")),void 0!==b.attr("pattern")&&(k="Not in the expected format",b.data("validationPatternMessage")&&(k=b.data("validationPatternMessage")),b.data("validationPatternMessage",k),b.data("validationPatternRegex",b.attr("pattern"))),void 0!==b.attr("max")||void 0!==b.attr("aria-valuemax")){var l=b.attr(void 0!==b.attr("max")?"max":"aria-valuemax");k="Too high: Maximum of '"+l+"'",b.data("validationMaxMessage")&&(k=b.data("validationMaxMessage")),b.data("validationMaxMessage",k),b.data("validationMaxMax",l)}if(void 0!==b.attr("min")||void 0!==b.attr("aria-valuemin")){var m=b.attr(void 0!==b.attr("min")?"min":"aria-valuemin");k="Too low: Minimum of '"+m+"'",b.data("validationMinMessage")&&(k=b.data("validationMinMessage")),b.data("validationMinMessage",k),b.data("validationMinMin",m)}if(void 0!==b.attr("maxlength")&&(k="Too long: Maximum of '"+b.attr("maxlength")+"' characters",b.data("validationMaxlengthMessage")&&(k=b.data("validationMaxlengthMessage")),b.data("validationMaxlengthMessage",k),b.data("validationMaxlengthMaxlength",b.attr("maxlength"))),void 0!==b.attr("minlength")&&(k="Too short: Minimum of '"+b.attr("minlength")+"' characters",b.data("validationMinlengthMessage")&&(k=b.data("validationMinlengthMessage")),b.data("validationMinlengthMessage",k),b.data("validationMinlengthMinlength",b.attr("minlength"))),(void 0!==b.attr("required")||void 0!==b.attr("aria-required"))&&(k=c.builtInValidators.required.message,b.data("validationRequiredMessage")&&(k=b.data("validationRequiredMessage")),b.data("validationRequiredMessage",k)),void 0!==b.attr("type")&&"number"===b.attr("type").toLowerCase()){k=c.validatorTypes.number.message,b.data("validationNumberMessage")&&(k=b.data("validationNumberMessage")),b.data("validationNumberMessage",k);var n=c.validatorTypes.number.step;b.data("validationNumberStep")&&(n=b.data("validationNumberStep")),b.data("validationNumberStep",n);var o=c.validatorTypes.number.decimal;b.data("validationNumberDecimal")&&(o=b.data("validationNumberDecimal")),b.data("validationNumberDecimal",o)}void 0!==b.attr("type")&&"email"===b.attr("type").toLowerCase()&&(k="Not a valid email address",b.data("validationEmailMessage")&&(k=b.data("validationEmailMessage")),b.data("validationEmailMessage",k)),void 0!==b.attr("minchecked")&&(k="Not enough options checked; Minimum of '"+b.attr("minchecked")+"' required",b.data("validationMincheckedMessage")&&(k=b.data("validationMincheckedMessage")),b.data("validationMincheckedMessage",k),b.data("validationMincheckedMinchecked",b.attr("minchecked"))),void 0!==b.attr("maxchecked")&&(k="Too many options checked; Maximum of '"+b.attr("maxchecked")+"' required",b.data("validationMaxcheckedMessage")&&(k=b.data("validationMaxcheckedMessage")),b.data("validationMaxcheckedMessage",k),b.data("validationMaxcheckedMaxchecked",b.attr("maxchecked")))}void 0!==b.data("validation")&&(j=b.data("validation").split(",")),a.each(b.data(),function(a){var b=a.replace(/([A-Z])/g,",$1").split(",");"validation"===b[0]&&b[1]&&j.push(b[1])});var p=j,q=[],r=function(a,b){j[a]=f(b)},s=function(d,e){if(void 0!==b.data("validation"+e+"Shortcut"))a.each(b.data("validation"+e+"Shortcut").split(","),function(a,b){q.push(b)});else if(c.builtInValidators[e.toLowerCase()]){var g=c.builtInValidators[e.toLowerCase()];"shortcut"===g.type.toLowerCase()&&a.each(g.shortcut.split(","),function(a,b){b=f(b),q.push(b),j.push(b)})}};do a.each(j,r),j=a.unique(j),q=[],a.each(p,s),p=q;while(p.length>0);var t={};a.each(j,function(d,e){var g=b.data("validation"+e+"Message"),h=!!g,i=!1;if(g||(g="'"+e+"' validation failed "),a.each(c.validatorTypes,function(c,d){if(void 0===t[c]&&(t[c]=[]),!i&&void 0!==b.data("validation"+e+f(d.name))){var j=d.init(b,e);h&&(j.message=g),t[c].push(a.extend(!0,{name:f(d.name),message:g},j)),i=!0}}),!i&&c.builtInValidators[e.toLowerCase()]){var j=a.extend(!0,{},c.builtInValidators[e.toLowerCase()]);h&&(j.message=g);var k=j.type.toLowerCase();"shortcut"===k?i=!0:a.each(c.validatorTypes,function(c,d){void 0===t[c]&&(t[c]=[]),i||k!==c.toLowerCase()||(b.data("validation"+e+f(d.name),j[d.name.toLowerCase()]),t[k].push(a.extend(j,d.init(b,e))),i=!0)})}i||a.error("Cannot find validation info for '"+e+"'")}),h.data("original-contents",h.data("original-contents")?h.data("original-contents"):h.html()),h.data("original-role",h.data("original-role")?h.data("original-role"):h.attr("role")),e.data("original-classes",e.data("original-clases")?e.data("original-classes"):e.attr("class")),b.data("original-aria-invalid",b.data("original-aria-invalid")?b.data("original-aria-invalid"):b.attr("aria-invalid")),b.bind("validation.validation",function(d,e){var f=g(b),h=[];return a.each(t,function(d,g){(f||f.length||e&&e.includeEmpty||c.validatorTypes[d].includeEmpty||c.validatorTypes[d].blockSubmit&&e&&e.submitting)&&a.each(g,function(a,e){c.validatorTypes[d].validate(b,f,e)&&h.push(e.message)})}),h}),b.bind("getValidators.validation",function(){return t});var u=0;a.each(t,function(a,b){u+=b.length}),b.bind("getValidatorCount.validation",function(){return u}),b.bind("submit.validation",function(){return b.triggerHandler("change.validation",{submitting:!0})}),b.bind((c.options.bindEvents.length>0?c.options.bindEvents:["keyup","focus","blur","click","keydown","keypress","change"]).concat(["revalidate"]).join(".validation ")+".validation",function(d,f){var j=g(b),k=[];f&&f.submitting?e.data("jqbvIsSubmitting",!0):"revalidate"!==d.type&&e.data("jqbvIsSubmitting",!1);var l=!!e.data("jqbvIsSubmitting");e.find("input,textarea,select").not("[type=submit]").each(function(c,d){var e=k.length;if(a.each(a(d).triggerHandler("validation.validation",f)||[],function(a,b){k.push(b)}),k.length>e)a(d).attr("aria-invalid","true");else{var g=b.data("original-aria-invalid");a(d).attr("aria-invalid",void 0!==g?g:!1)}}),i.find("input,select,textarea").not(b).not('[name="'+b.attr("name")+'"]').trigger("validationLostFocus.validation"),k=a.unique(k.sort()),k.length?(e.removeClass("success error warning").addClass(l?"error":"warning"),h.html(c.options.semanticallyStrict&&1===k.length?k[0]+(c.options.prependExistingHelpBlock?h.data("original-contents"):""):'
  • '+k.join("
  • ")+"
"+(c.options.prependExistingHelpBlock?h.data("original-contents"):""))):(e.removeClass("warning error success"),j.length>0&&e.addClass("success"),h.html(h.data("original-contents"))),"blur"===d.type&&c.options.removeSuccess&&e.removeClass("success")}),b.bind("validationLostFocus.validation",function(){c.options.removeSuccess&&e.removeClass("success")})})},destroy:function(){return this.each(function(){var b=a(this),c=b.parents(".form-group").first(),e=c.find(".help-block").first(),f=b.parents("form").first();b.unbind(".validation"),f.unbind(".validationSubmit"),e.html(e.data("original-contents")),c.attr("class",c.data("original-classes")),b.attr("aria-invalid",b.data("original-aria-invalid")),e.attr("role",b.data("original-role")),a.inArray(e[0],d)>-1&&e.remove()})},collectErrors:function(){var b={};return this.each(function(c,d){var e=a(d),f=e.attr("name"),g=e.triggerHandler("validation.validation",{includeEmpty:!0});b[f]=a.extend(!0,g,b[f])}),a.each(b,function(a,c){0===c.length&&delete b[a]}),b},hasErrors:function(){var b=[];return this.find("input,select,textarea").add(this).each(function(c,d){b=b.concat(a(d).triggerHandler("getValidators.validation")?a(d).triggerHandler("validation.validation",{submitting:!0}):[])}),b.length>0},override:function(b){e=a.extend(!0,e,b)}},validatorTypes:{callback:{name:"callback",init:function(a,b){var c={validatorName:b,callback:a.data("validation"+b+"Callback"),lastValue:a.val(),lastValid:!0,lastFinished:!0},d="Not valid";return a.data("validation"+b+"Message")&&(d=a.data("validation"+b+"Message")),c.message=d,c},validate:function(a,b,d){if(d.lastValue===b&&d.lastFinished)return!d.lastValid;if(d.lastFinished===!0){d.lastValue=b,d.lastValid=!0,d.lastFinished=!1;var e=d,f=a;c(d.callback,window,a,b,function(b){e.lastValue===b.value&&(e.lastValid=b.valid,b.message&&(e.message=b.message),e.lastFinished=!0,f.data("validation"+e.validatorName+"Message",e.message),setTimeout(function(){f.trigger(!a.is(":focus")&&a.parents("form").first().data("jqbvIsSubmitting")?"blur.validation":"revalidate.validation")},1))})}return!1}},ajax:{name:"ajax",init:function(a,b){return{validatorName:b,url:a.data("validation"+b+"Ajax"),lastValue:a.val(),lastValid:!0,lastFinished:!0}},validate:function(b,c,d){return""+d.lastValue==""+c&&d.lastFinished===!0?d.lastValid===!1:(d.lastFinished===!0&&(d.lastValue=c,d.lastValid=!0,d.lastFinished=!1,a.ajax({url:d.url,data:"value="+encodeURIComponent(c)+"&field="+b.attr("name"),dataType:"json",success:function(a){""+d.lastValue==""+a.value&&(d.lastValid=!!a.valid,a.message&&(d.message=a.message),d.lastFinished=!0,b.data("validation"+d.validatorName+"Message",d.message),setTimeout(function(){b.trigger("revalidate.validation")},1))},failure:function(){d.lastValid=!0,d.message="ajax call failed",d.lastFinished=!0,b.data("validation"+d.validatorName+"Message",d.message),setTimeout(function(){b.trigger("revalidate.validation")},1)}})),!1)}},regex:{name:"regex",init:function(c,d){var e={},f=c.data("validation"+d+"Regex");e.regex=b(f),void 0===f&&a.error("Can't find regex for '"+d+"' validator on '"+c.attr("name")+"'");var g="Not in the expected format";return c.data("validation"+d+"Message")&&(g=c.data("validation"+d+"Message")),e.message=g,e.originalName=d,e},validate:function(a,b,c){return!c.regex.test(b)&&!c.negative||c.regex.test(b)&&c.negative}},email:{name:"email",init:function(a,c){var d={};d.regex=b("[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");var e="Not a valid email address";return a.data("validation"+c+"Message")&&(e=a.data("validation"+c+"Message")),d.message=e,d.originalName=c,d},validate:function(a,b,c){return!c.regex.test(b)&&!c.negative||c.regex.test(b)&&c.negative}},required:{name:"required",init:function(a,b){var c="This is required";return a.data("validation"+b+"Message")&&(c=a.data("validation"+b+"Message")),{message:c,includeEmpty:!0}},validate:function(a,b,c){return!!(0===b.length&&!c.negative||b.length>0&&c.negative)},blockSubmit:!0},match:{name:"match",init:function(b,c){var d=b.data("validation"+c+"Match"),e=b.parents("form").first(),f=e.find('[name="'+d+'"]').first();f.bind("validation.validation",function(){b.trigger("revalidate.validation",{submitting:!0})});var g={};g.element=f,0===f.length&&a.error("Can't find field '"+d+"' to match '"+b.attr("name")+"' against in '"+c+"' validator");var h="Must match",i=null;return(i=e.find('label[for="'+d+'"]')).length?h+=" '"+i.text()+"'":(i=f.parents(".form-group").first().find("label")).length&&(h+=" '"+i.first().text()+"'"),b.data("validation"+c+"Message")&&(h=b.data("validation"+c+"Message")),g.message=h,g},validate:function(a,b,c){return b!==c.element.val()&&!c.negative||b===c.element.val()&&c.negative},blockSubmit:!0,includeEmpty:!0},max:{name:"max",init:function(a,b){var c={};return c.max=a.data("validation"+b+"Max"),c.message="Too high: Maximum of '"+c.max+"'",a.data("validation"+b+"Message")&&(c.message=a.data("validation"+b+"Message")),c},validate:function(a,b,c){return parseFloat(b,10)>parseFloat(c.max,10)&&!c.negative||parseFloat(b,10)<=parseFloat(c.max,10)&&c.negative}},min:{name:"min",init:function(a,b){var c={};return c.min=a.data("validation"+b+"Min"),c.message="Too low: Minimum of '"+c.min+"'",a.data("validation"+b+"Message")&&(c.message=a.data("validation"+b+"Message")),c},validate:function(a,b,c){return parseFloat(b)=parseFloat(c.min)&&c.negative}},maxlength:{name:"maxlength",init:function(a,b){var c={};return c.maxlength=a.data("validation"+b+"Maxlength"),c.message="Too long: Maximum of '"+c.maxlength+"' characters",a.data("validation"+b+"Message")&&(c.message=a.data("validation"+b+"Message")),c},validate:function(a,b,c){return b.length>c.maxlength&&!c.negative||b.length<=c.maxlength&&c.negative}},minlength:{name:"minlength",init:function(a,b){var c={};return c.minlength=a.data("validation"+b+"Minlength"),c.message="Too short: Minimum of '"+c.minlength+"' characters",a.data("validation"+b+"Message")&&(c.message=a.data("validation"+b+"Message")),c},validate:function(a,b,c){return b.length=c.minlength&&c.negative}},maxchecked:{name:"maxchecked",init:function(a,b){var c={},d=a.parents("form").first().find('[name="'+a.attr("name")+'"]');d.bind("change.validation click.validation",function(){a.trigger("revalidate.validation",{includeEmpty:!0})}),c.elements=d,c.maxchecked=a.data("validation"+b+"Maxchecked");var e="Too many: Max '"+c.maxchecked+"' checked";return a.data("validation"+b+"Message")&&(e=a.data("validation"+b+"Message")),c.message=e,c},validate:function(a,b,c){return c.elements.filter(":checked").length>c.maxchecked&&!c.negative||c.elements.filter(":checked").length<=c.maxchecked&&c.negative},blockSubmit:!0},minchecked:{name:"minchecked",init:function(a,b){var c={},d=a.parents("form").first().find('[name="'+a.attr("name")+'"]');d.bind("change.validation click.validation",function(){a.trigger("revalidate.validation",{includeEmpty:!0})}),c.elements=d,c.minchecked=a.data("validation"+b+"Minchecked");var e="Too few: Min '"+c.minchecked+"' checked";return a.data("validation"+b+"Message")&&(e=a.data("validation"+b+"Message")),c.message=e,c},validate:function(a,b,c){return c.elements.filter(":checked").length=c.minchecked&&c.negative},blockSubmit:!0,includeEmpty:!0},number:{name:"number",init:function(a,c){var d={};d.step=1,a.attr("step")&&(d.step=a.attr("step")),a.data("validation"+c+"Step")&&(d.step=a.data("validation"+c+"Step")),d.decimal=".",a.data("validation"+c+"Decimal")&&(d.decimal=a.data("validation"+c+"Decimal")),d.thousands="",a.data("validation"+c+"Thousands")&&(d.thousands=a.data("validation"+c+"Thousands")),d.regex=b("([+-]?\\d+(\\"+d.decimal+"\\d+)?)?"),d.message="Must be a number";var e=a.data("validation"+c+"Message");return e&&(d.message=e),d},validate:function(a,b,c){for(var d=b.replace(c.decimal,".").replace(c.thousands,""),e=parseFloat(d),f=parseFloat(c.step);f%1!==0;)f=10*parseFloat(f.toPrecision(12)),e=10*parseFloat(e.toPrecision(12));var g=c.regex.test(b),h=parseFloat(e)%parseFloat(f)===0,i=!isNaN(parseFloat(d))&&isFinite(d),j=!(g&&h&&i);return j},message:"Must be a number"}},builtInValidators:{email:{name:"Email",type:"email"},passwordagain:{name:"Passwordagain",type:"match",match:"password",message:"Does not match the given password"},positive:{name:"Positive",type:"shortcut",shortcut:"number,positivenumber"},negative:{name:"Negative",type:"shortcut",shortcut:"number,negativenumber"},integer:{name:"Integer",type:"regex",regex:"[+-]?\\d+",message:"No decimal places allowed"},positivenumber:{name:"Positivenumber",type:"min",min:0,message:"Must be a positive number"},negativenumber:{name:"Negativenumber",type:"max",max:0,message:"Must be a negative number"},required:{name:"Required",type:"required",message:"This is required"},checkone:{name:"Checkone",type:"minchecked",minchecked:1,message:"Check at least one option"},number:{name:"Number",type:"number",decimal:".",step:"1"},pattern:{name:"Pattern",type:"regex",message:"Not in expected format"}}},f=function(a){return a.toLowerCase().replace(/(^|\s)([a-z])/g,function(a,b,c){return b+c.toUpperCase()})},g=function(b){var c=null,d=b.attr("type");if("checkbox"===d){c=b.is(":checked")?c:"";var e=b.parents("form").first()||b.parents(".form-group").first();e&&(c=e.find("input[name='"+b.attr("name")+"']:checked").map(function(b,c){return a(c).val()}).toArray().join(","))}else if("radio"===d){c=a('input[name="'+b.attr("name")+'"]:checked').length>0?b.val():"";var f=b.parents("form").first()||b.parents(".form-group").first();f&&(c=f.find("input[name='"+b.attr("name")+"']:checked").map(function(b,c){return a(c).val()}).toArray().join(","))}else c="number"===d?b[0].validity.valid?b.val():b[0].validity.badInput||b[0].validity.stepMismatch?"NaN":"":b.val();return c};a.fn.jqBootstrapValidation=function(b){return e.methods[b]?e.methods[b].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof b&&b?(a.error("Method "+b+" does not exist on jQuery.jqBootstrapValidation"),null):e.methods.init.apply(this,arguments)},a.jqBootstrapValidation=function(){a(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments)}}(jQuery); \ No newline at end of file diff --git a/dist/jqBootstrapValidation.zip b/dist/jqBootstrapValidation.zip index 188aabea8022bf236b5f021356a7fdcdd6c32618..66d552e03ba02a3577ef79f6f0e4a6d085b2fe2c 100644 GIT binary patch literal 17232 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 aXUAt2WE4HXo0ScuhY1Mh0O@&7ARYk9B@yoc literal 14067 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 H|7-Oh$T%tp diff --git a/test/issues/39/test.js b/test/issues/39/test.js index 8b17107..fda1f88 100644 --- a/test/issues/39/test.js +++ b/test/issues/39/test.js @@ -29,7 +29,7 @@ setup: function() { $("#qunit-fixture").append("\
\ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ 1); @@ -143,7 +143,7 @@ } $input.trigger("change.validation"); - var changeClassExpected = ["control-group"].concat(classChange); + var changeClassExpected = ["form-group"].concat(classChange); var changeClassActual = $controlGroup.attr("class").split(" "); deepEqual(changeClassActual, changeClassExpected, "classes as expected on change - " + valueJson); @@ -156,7 +156,7 @@ var nowErrors = window.number_of_submit_errors; var nowSuccess = window.number_of_submit_successes; - var submitClassExpected = ["control-group"].concat(classSubmit); + var submitClassExpected = ["form-group"].concat(classSubmit); var submitClassActual = $controlGroup.attr("class").split(" "); deepEqual(submitClassActual, submitClassExpected, "classes as expected on submit - " + valueJson); @@ -183,7 +183,7 @@ window.runJQBVTestAsync = function(value, classChange, classSubmit, messageChange, messageSubmit, callback) { var $input = $("#qunit-fixture").find("[name=input]"); - var $controlGroup = $($input.parents(".control-group")[0]); + var $controlGroup = $($input.parents(".form-group")[0]); var $form = $input.parents("form").first(); var isMulti = ($input.length > 1); @@ -235,7 +235,7 @@ $input.trigger("change.validation"); setTimeout( function() { - var changeClassExpected = ["control-group"].concat(classChange); + var changeClassExpected = ["form-group"].concat(classChange); var changeClassActual = $controlGroup.attr("class").split(" "); deepEqual(changeClassActual, changeClassExpected, "classes as expected on change - " + valueJson); @@ -251,7 +251,7 @@ var nowErrors = window.number_of_submit_errors; var nowSuccess = window.number_of_submit_successes; - var submitClassExpected = ["control-group"].concat(classSubmit); + var submitClassExpected = ["form-group"].concat(classSubmit); var submitClassActual = $controlGroup.attr("class").split(" "); deepEqual(submitClassActual, submitClassExpected, "classes as expected on submit - " + valueJson); @@ -273,7 +273,7 @@ $form.trigger("submit"); setTimeout( function() { - var submitClassExpected = ["control-group"].concat(classSubmit); + var submitClassExpected = ["form-group"].concat(classSubmit); var submitClassActual = $controlGroup.attr("class").split(" "); deepEqual(submitClassActual, submitClassExpected, "classes as expected on submit - " + valueJson); diff --git a/test/jqBootstrapValidation_test.js b/test/jqBootstrapValidation_test.js index c025a05..7d70166 100644 --- a/test/jqBootstrapValidation_test.js +++ b/test/jqBootstrapValidation_test.js @@ -29,7 +29,7 @@ setup: function() { $("#qunit-fixture").append("\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \ -
\ +
\ \
\ \
\
\ -
\ +
\ \
\ \ -
\ +
\ \
\ \
\
\ -
\ +
\ \
\ \ -
\ +
\ \
\ \
\
\ -
\ +
\ \
\ \ -
\ +
\
\ \
\
\ -
\ +
\ \
\ \ -
\ +
\ \
\