| /* jqBootstrapValidation |
| * A plugin for automating validation on Twitter Bootstrap formatted forms. |
| * |
| * v1.3.6 |
| * |
| * License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file |
| * |
| * http://ReactiveRaven.github.com/jqBootstrapValidation/ |
| */ |
| |
| (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 |
| autoAdd: { |
| helpBlocks: true |
| }, |
| filter: function () { |
| // return $(this).is(":visible"); // only validate elements you can see |
| return true; // validate everything |
| } |
| }, |
| methods: { |
| init : function( options ) { |
| |
| var settings = $.extend(true, {}, defaults); |
| |
| 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", function (e) { |
| var $form = $(this); |
| var warningsFound = 0; |
| var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); |
| $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); |
| |
| $inputs.each(function (i, el) { |
| var $this = $(el), |
| $controlGroup = $this.parents(".control-group").first(); |
| if ( |
| $controlGroup.hasClass("warning") |
| ) { |
| $controlGroup.removeClass("warning").addClass("error"); |
| warningsFound++; |
| } |
| }); |
| |
| $inputs.trigger("validationLostFocus.validation"); |
| |
| if (warningsFound) { |
| if (settings.options.preventSubmit) { |
| e.preventDefault(); |
| } |
| $form.addClass("error"); |
| if ($.isFunction(settings.options.submitError)) { |
| settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); |
| } |
| } else { |
| $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(".control-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 = $('<div class="help-block" />'); |
| $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.attr("pattern") !== undefined) { |
| message = "Not in the expected format<!-- data-validation-pattern-message to override -->"; |
| 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 + "'<!-- data-validation-max-message to override -->"; |
| 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 + "'<!-- data-validation-min-message to override -->"; |
| 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<!-- data-validation-maxlength-message to override -->"; |
| 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<!-- data-validation-minlength-message to override -->"; |
| 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.builtInValidators.number.message; |
| if ($this.data("validationNumberMessage")) { |
| message = $this.data("validationNumberMessage"); |
| } |
| $this.data("validationNumberMessage", message); |
| } |
| // --------------------------------------------------------- |
| // EMAIL |
| // --------------------------------------------------------- |
| if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { |
| message = "Not a valid email address<!-- data-validation-validemail-message to override -->"; |
| if ($this.data("validationValidemailMessage")) { |
| message = $this.data("validationValidemailMessage"); |
| } else if ($this.data("validationEmailMessage")) { |
| message = $this.data("validationEmailMessage"); |
| } |
| $this.data("validationValidemailMessage", message); |
| } |
| // --------------------------------------------------------- |
| // MINCHECKED |
| // --------------------------------------------------------- |
| if ($this.attr("minchecked") !== undefined) { |
| message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->"; |
| 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<!-- data-validation-maxchecked-message to override -->"; |
| 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 = []; |
| |
| do // repeatedly expand 'shortcut' validators into their real validators |
| { |
| // Uppercase only the first letter of each name |
| $.each(validatorNames, function (i, el) { |
| validatorNames[i] = formatValidatorName(el); |
| }); |
| |
| // Remove duplicate validator names |
| validatorNames = $.unique(validatorNames); |
| |
| // Pull out the new validator names from each shortcut |
| newValidatorNamesToInspect = []; |
| $.each(validatorNamesToInspect, 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); |
| }); |
| } |
| } |
| }); |
| |
| validatorNamesToInspect = newValidatorNamesToInspect; |
| |
| } while (validatorNamesToInspect.length > 0) |
| |
| // ============================================================= |
| // SET UP VALIDATOR ARRAYS |
| // ============================================================= |
| |
| var validators = {}; |
| |
| $.each(validatorNames, function (i, el) { |
| // Set up the 'override' message |
| var message = $this.data("validation" + el + "Message"); |
| var hasOverrideMessage = (message !== undefined); |
| var foundValidator = false; |
| message = |
| ( |
| message |
| ? message |
| : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->" |
| ) |
| ; |
| |
| $.each( |
| settings.validatorTypes, |
| function (validatorType, validatorTemplate) { |
| if (validators[validatorType] === undefined) { |
| validators[validatorType] = []; |
| } |
| if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { |
| validators[validatorType].push( |
| $.extend( |
| true, |
| { |
| name: formatValidatorName(validatorTemplate.name), |
| message: message |
| }, |
| validatorTemplate.init($this, el) |
| ) |
| ); |
| 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 || value.length || (params && params.includeEmpty) || (!!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; |
| } |
| ); |
| |
| // ============================================================= |
| // WATCH FOR CHANGES |
| // ============================================================= |
| $this.bind( |
| "submit.validation", |
| function () { |
| return $this.triggerHandler("change.validation", {submitting: true}); |
| } |
| ); |
| $this.bind( |
| [ |
| "keyup", |
| "focus", |
| "blur", |
| "click", |
| "keydown", |
| "keypress", |
| "change" |
| ].join(".validation ") + ".validation", |
| function (e, params) { |
| |
| var value = getValue($this); |
| |
| var errorsFound = []; |
| |
| $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); |
| }); |
| 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").addClass("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("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" + |
| ( 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") { |
| $controlGroup.removeClass("success"); |
| } |
| } |
| ); |
| $this.bind("validationLostFocus.validation", function () { |
| $controlGroup.removeClass("success"); |
| }); |
| }); |
| }, |
| destroy : function( ) { |
| |
| return this.each( |
| function() { |
| |
| var |
| $this = $(this), |
| $controlGroup = $this.parents(".control-group").first(), |
| $helpBlock = $controlGroup.find(".help-block").first(); |
| |
| // remove our events |
| $this.unbind('.validation'); // events are namespaced. |
| // 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 (createdElements.indexOf($helpBlock[0]) > -1) { |
| $helpBlock.remove(); |
| } |
| |
| } |
| ); |
| |
| }, |
| 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.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: { |
| name: "callback", |
| init: function ($this, name) { |
| return { |
| validatorName: name, |
| callback: $this.data("validation" + name + "Callback"), |
| lastValue: $this.val(), |
| lastValid: true, |
| lastFinished: true |
| }; |
| }, |
| validate: function ($this, value, validator) { |
| if (validator.lastValue === value && validator.lastFinished) { |
| return !validator.lastValid; |
| } |
| |
| if (validator.lastFinished === true) |
| { |
| validator.lastValue = value; |
| validator.lastValid = true; |
| validator.lastFinished = false; |
| |
| var rrjqbvValidator = validator; |
| var rrjqbvThis = $this; |
| executeFunctionByName( |
| validator.callback, |
| window, |
| $this, |
| value, |
| function (data) { |
| if (rrjqbvValidator.lastValue === data.value) { |
| rrjqbvValidator.lastValid = data.valid; |
| if (data.message) { |
| rrjqbvValidator.message = data.message; |
| } |
| rrjqbvValidator.lastFinished = true; |
| rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); |
| // Timeout is set to avoid problems with the events being considered 'already fired' |
| setTimeout(function () { |
| rrjqbvThis.trigger("change.validation"); |
| }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst |
| } |
| } |
| ); |
| } |
| |
| 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=" + 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("change.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("change.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) { |
| return {regex: regexFromString($this.data("validation" + name + "Regex"))}; |
| }, |
| 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) { |
| return {}; |
| }, |
| 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 element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); |
| element.bind("validation.validation", function () { |
| $this.trigger("change.validation", {submitting: true}); |
| }); |
| return {"element": element}; |
| }, |
| validate: function ($this, value, validator) { |
| return (value !== validator.element.val() && ! validator.negative) |
| || (value === validator.element.val() && validator.negative); |
| }, |
| blockSubmit: true |
| }, |
| max: { |
| name: "max", |
| init: function ($this, name) { |
| return {max: $this.data("validation" + name + "Max")}; |
| }, |
| 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) { |
| return {min: $this.data("validation" + name + "Min")}; |
| }, |
| 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) { |
| return {maxlength: $this.data("validation" + name + "Maxlength")}; |
| }, |
| 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) { |
| return {minlength: $this.data("validation" + name + "Minlength")}; |
| }, |
| 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 elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); |
| elements.bind("click.validation", function () { |
| $this.trigger("change.validation", {includeEmpty: true}); |
| }); |
| return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; |
| }, |
| 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 elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); |
| elements.bind("click.validation", function () { |
| $this.trigger("change.validation", {includeEmpty: true}); |
| }); |
| return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; |
| }, |
| 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 |
| } |
| }, |
| builtInValidators: { |
| email: { |
| name: "Email", |
| type: "shortcut", |
| shortcut: "validemail" |
| }, |
| validemail: { |
| name: "Validemail", |
| type: "regex", |
| regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", |
| message: "Not a valid email address<!-- data-validation-validemail-message to override -->" |
| }, |
| passwordagain: { |
| name: "Passwordagain", |
| type: "match", |
| match: "password", |
| message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->" |
| }, |
| positive: { |
| name: "Positive", |
| type: "shortcut", |
| shortcut: "number,positivenumber" |
| }, |
| negative: { |
| name: "Negative", |
| type: "shortcut", |
| shortcut: "number,negativenumber" |
| }, |
| number: { |
| name: "Number", |
| type: "regex", |
| regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", |
| message: "Must be a number<!-- data-validator-number-message to override -->" |
| }, |
| integer: { |
| name: "Integer", |
| type: "regex", |
| regex: "[+-]?\\\d+", |
| message: "No decimal places allowed<!-- data-validator-integer-message to override -->" |
| }, |
| positivenumber: { |
| name: "Positivenumber", |
| type: "min", |
| min: 0, |
| message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->" |
| }, |
| negativenumber: { |
| name: "Negativenumber", |
| type: "max", |
| max: 0, |
| message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->" |
| }, |
| required: { |
| name: "Required", |
| type: "required", |
| message: "This is required<!-- data-validator-required-message to override -->" |
| }, |
| checkone: { |
| name: "Checkone", |
| type: "minchecked", |
| minchecked: 1, |
| message: "Check at least one option<!-- data-validation-checkone-message to override -->" |
| } |
| } |
| }; |
| |
| 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 = $this.val(); |
| var type = $this.attr("type"); |
| if (type === "checkbox") { |
| value = ($this.is(":checked") ? value : ""); |
| } |
| if (type === "radio") { |
| value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); |
| } |
| return value; |
| }; |
| |
| function regexFromString(inputstring) { |
| return new RegExp("^" + inputstring + "$"); |
| } |
| |
| /** |
| * Thanks to Jason Bunting via StackOverflow.com |
| * |
| * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 |
| * Short link: http://tinyurl.com/executeFunctionByName |
| **/ |
| function executeFunctionByName(functionName, context /*, args*/) { |
| var args = Array.prototype.slice.call(arguments).splice(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(this, args); |
| } |
| |
| $.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; |
| } |
| |
| }; |
| |
| $.jqBootstrapValidation = function (options) { |
| $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); |
| }; |
| |
| })( jQuery ); |