rebuild GUI structure(only changed modules' name)
[vnfsdk/refrepo.git] / extsys / src / main / webapp / extsys / vim / js / jqBootstrapValidation.js
1 /*
2  * Copyright 2016-2017 ZTE Corporation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /* jqBootstrapValidation
17  * A plugin for automating validation on Twitter Bootstrap formatted forms.
18  *
19  * v1.3.6
20  *
21  * License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
22  *
23  * http://ReactiveRaven.github.com/jqBootstrapValidation/
24  */
25
26 (function ($) {
27
28     var createdElements = [];
29
30     var defaults = {
31         options: {
32             prependExistingHelpBlock: false,
33             sniffHtml: true, // sniff for 'required', 'maxlength', etc
34             preventSubmit: true, // stop the form submit event from firing if validation fails
35             submitError: false, // function called if there is an error when trying to submit
36             submitSuccess: false, // function called just before a successful submit event is sent to the server
37             semanticallyStrict: false, // set to true to tidy up generated HTML output
38             autoAdd: {
39                 helpBlocks: true
40             },
41             filter: function () {
42                 // return $(this).is(":visible"); // only validate elements you can see
43                 return true; // validate everything
44             }
45         },
46         methods: {
47             init: function (options) {
48
49                 var settings = $.extend(true, {}, defaults);
50
51                 settings.options = $.extend(true, settings.options, options);
52
53                 var $siblingElements = this;
54
55                 var uniqueForms = $.unique(
56                     $siblingElements.map(function () {
57                         return $(this).parents("form")[0];
58                     }).toArray()
59                 );
60
61                 $(uniqueForms).bind("submit", function (e) {
62                     var $form = $(this);
63                     var warningsFound = 0;
64                     var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
65                     $inputs.trigger("submit.validation").trigger("validationLostFocus.validation");
66
67                     $inputs.each(function (i, el) {
68                         var $this = $(el),
69                             $controlGroup = $this.parents(".control-group").first();
70                         if (
71                             $controlGroup.hasClass("warning")
72                         ) {
73                             $controlGroup.removeClass("warning").addClass("error");
74                             warningsFound++;
75                         }
76                     });
77
78                     $inputs.trigger("validationLostFocus.validation");
79
80                     if (warningsFound) {
81                         if (settings.options.preventSubmit) {
82                             e.preventDefault();
83                         }
84                         $form.addClass("error");
85                         if ($.isFunction(settings.options.submitError)) {
86                             settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
87                         }
88                     } else {
89                         $form.removeClass("error");
90                         if ($.isFunction(settings.options.submitSuccess)) {
91                             settings.options.submitSuccess($form, e);
92                         }
93                     }
94                 });
95
96                 return this.each(function () {
97
98                     // Get references to everything we're interested in
99                     var $this = $(this),
100                         $controlGroup = $this.parents(".control-group").first(),
101                         $helpBlock = $controlGroup.find(".help-block").first(),
102                         $form = $this.parents("form").first(),
103                         validatorNames = [];
104
105                     // create message container if not exists
106                     if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
107                         $helpBlock = $('<div class="help-block" />');
108                         $controlGroup.find('.controls').append($helpBlock);
109                         createdElements.push($helpBlock[0]);
110                     }
111
112                     // =============================================================
113                     //                                     SNIFF HTML FOR VALIDATORS
114                     // =============================================================
115
116                     // *snort sniff snuffle*
117
118                     if (settings.options.sniffHtml) {
119                         var message = "";
120                         // ---------------------------------------------------------
121                         //                                                   PATTERN
122                         // ---------------------------------------------------------
123                         if ($this.attr("pattern") !== undefined) {
124                             message = "Not in the expected format<!-- data-validation-pattern-message to override -->";
125                             if ($this.data("validationPatternMessage")) {
126                                 message = $this.data("validationPatternMessage");
127                             }
128                             $this.data("validationPatternMessage", message);
129                             $this.data("validationPatternRegex", $this.attr("pattern"));
130                         }
131                         // ---------------------------------------------------------
132                         //                                                       MAX
133                         // ---------------------------------------------------------
134                         if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
135                             var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
136                             message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->";
137                             if ($this.data("validationMaxMessage")) {
138                                 message = $this.data("validationMaxMessage");
139                             }
140                             $this.data("validationMaxMessage", message);
141                             $this.data("validationMaxMax", max);
142                         }
143                         // ---------------------------------------------------------
144                         //                                                       MIN
145                         // ---------------------------------------------------------
146                         if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
147                             var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
148                             message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->";
149                             if ($this.data("validationMinMessage")) {
150                                 message = $this.data("validationMinMessage");
151                             }
152                             $this.data("validationMinMessage", message);
153                             $this.data("validationMinMin", min);
154                         }
155                         // ---------------------------------------------------------
156                         //                                                 MAXLENGTH
157                         // ---------------------------------------------------------
158                         if ($this.attr("maxlength") !== undefined) {
159                             message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
160                             if ($this.data("validationMaxlengthMessage")) {
161                                 message = $this.data("validationMaxlengthMessage");
162                             }
163                             $this.data("validationMaxlengthMessage", message);
164                             $this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
165                         }
166                         // ---------------------------------------------------------
167                         //                                                 MINLENGTH
168                         // ---------------------------------------------------------
169                         if ($this.attr("minlength") !== undefined) {
170                             message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
171                             if ($this.data("validationMinlengthMessage")) {
172                                 message = $this.data("validationMinlengthMessage");
173                             }
174                             $this.data("validationMinlengthMessage", message);
175                             $this.data("validationMinlengthMinlength", $this.attr("minlength"));
176                         }
177                         // ---------------------------------------------------------
178                         //                                                  REQUIRED
179                         // ---------------------------------------------------------
180                         if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
181                             message = settings.builtInValidators.required.message;
182                             if ($this.data("validationRequiredMessage")) {
183                                 message = $this.data("validationRequiredMessage");
184                             }
185                             $this.data("validationRequiredMessage", message);
186                         }
187                         // ---------------------------------------------------------
188                         //                                                    NUMBER
189                         // ---------------------------------------------------------
190                         if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
191                             message = settings.builtInValidators.number.message;
192                             if ($this.data("validationNumberMessage")) {
193                                 message = $this.data("validationNumberMessage");
194                             }
195                             $this.data("validationNumberMessage", message);
196                         }
197                         // ---------------------------------------------------------
198                         //                                                     EMAIL
199                         // ---------------------------------------------------------
200                         if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
201                             message = "Not a valid email address<!-- data-validator-validemail-message to override -->";
202                             if ($this.data("validationValidemailMessage")) {
203                                 message = $this.data("validationValidemailMessage");
204                             } else if ($this.data("validationEmailMessage")) {
205                                 message = $this.data("validationEmailMessage");
206                             }
207                             $this.data("validationValidemailMessage", message);
208                         }
209                         // ---------------------------------------------------------
210                         //                                                MINCHECKED
211                         // ---------------------------------------------------------
212                         if ($this.attr("minchecked") !== undefined) {
213                             message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->";
214                             if ($this.data("validationMincheckedMessage")) {
215                                 message = $this.data("validationMincheckedMessage");
216                             }
217                             $this.data("validationMincheckedMessage", message);
218                             $this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
219                         }
220                         // ---------------------------------------------------------
221                         //                                                MAXCHECKED
222                         // ---------------------------------------------------------
223                         if ($this.attr("maxchecked") !== undefined) {
224                             message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
225                             if ($this.data("validationMaxcheckedMessage")) {
226                                 message = $this.data("validationMaxcheckedMessage");
227                             }
228                             $this.data("validationMaxcheckedMessage", message);
229                             $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
230                         }
231                     }
232
233                     // =============================================================
234                     //                                       COLLECT VALIDATOR NAMES
235                     // =============================================================
236
237                     // Get named validators
238                     if ($this.data("validation") !== undefined) {
239                         validatorNames = $this.data("validation").split(",");
240                     }
241
242                     // Get extra ones defined on the element's data attributes
243                     $.each($this.data(), function (i, el) {
244                         var parts = i.replace(/([A-Z])/g, ",$1").split(",");
245                         if (parts[0] === "validation" && parts[1]) {
246                             validatorNames.push(parts[1]);
247                         }
248                     });
249
250                     // =============================================================
251                     //                                     NORMALISE VALIDATOR NAMES
252                     // =============================================================
253
254                     var validatorNamesToInspect = validatorNames;
255                     var newValidatorNamesToInspect = [];
256
257                     do // repeatedly expand 'shortcut' validators into their real validators
258                     {
259                         // Uppercase only the first letter of each name
260                         $.each(validatorNames, function (i, el) {
261                             validatorNames[i] = formatValidatorName(el);
262                         });
263
264                         // Remove duplicate validator names
265                         validatorNames = $.unique(validatorNames);
266
267                         // Pull out the new validator names from each shortcut
268                         newValidatorNamesToInspect = [];
269                         $.each(validatorNamesToInspect, function (i, el) {
270                             if ($this.data("validation" + el + "Shortcut") !== undefined) {
271                                 // Are these custom validators?
272                                 // Pull them out!
273                                 $.each($this.data("validation" + el + "Shortcut").split(","), function (i2, el2) {
274                                     newValidatorNamesToInspect.push(el2);
275                                 });
276                             } else if (settings.builtInValidators[el.toLowerCase()]) {
277                                 // Is this a recognised built-in?
278                                 // Pull it out!
279                                 var validator = settings.builtInValidators[el.toLowerCase()];
280                                 if (validator.type.toLowerCase() === "shortcut") {
281                                     $.each(validator.shortcut.split(","), function (i, el) {
282                                         el = formatValidatorName(el);
283                                         newValidatorNamesToInspect.push(el);
284                                         validatorNames.push(el);
285                                     });
286                                 }
287                             }
288                         });
289
290                         validatorNamesToInspect = newValidatorNamesToInspect;
291
292                     } while (validatorNamesToInspect.length > 0)
293
294                     // =============================================================
295                     //                                       SET UP VALIDATOR ARRAYS
296                     // =============================================================
297
298                     var validators = {};
299
300                     $.each(validatorNames, function (i, el) {
301                         // Set up the 'override' message
302                         var message = $this.data("validation" + el + "Message");
303                         var hasOverrideMessage = (message !== undefined);
304                         var foundValidator = false;
305                         message =
306                             (
307                                 message
308                                     ? message
309                                     : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->"
310                             )
311                         ;
312
313                         $.each(
314                             settings.validatorTypes,
315                             function (validatorType, validatorTemplate) {
316                                 if (validators[validatorType] === undefined) {
317                                     validators[validatorType] = [];
318                                 }
319                                 if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
320                                     validators[validatorType].push(
321                                         $.extend(
322                                             true,
323                                             {
324                                                 name: formatValidatorName(validatorTemplate.name),
325                                                 message: message
326                                             },
327                                             validatorTemplate.init($this, el)
328                                         )
329                                     );
330                                     foundValidator = true;
331                                 }
332                             }
333                         );
334
335                         if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {
336
337                             var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
338                             if (hasOverrideMessage) {
339                                 validator.message = message;
340                             }
341                             var validatorType = validator.type.toLowerCase();
342
343                             if (validatorType === "shortcut") {
344                                 foundValidator = true;
345                             } else {
346                                 $.each(
347                                     settings.validatorTypes,
348                                     function (validatorTemplateType, validatorTemplate) {
349                                         if (validators[validatorTemplateType] === undefined) {
350                                             validators[validatorTemplateType] = [];
351                                         }
352                                         if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
353                                             $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
354                                             validators[validatorType].push(
355                                                 $.extend(
356                                                     validator,
357                                                     validatorTemplate.init($this, el)
358                                                 )
359                                             );
360                                             foundValidator = true;
361                                         }
362                                     }
363                                 );
364                             }
365                         }
366
367                         if (!foundValidator) {
368                             $.error("Cannot find validation info for '" + el + "'");
369                         }
370                     });
371
372                     // =============================================================
373                     //                                         STORE FALLBACK VALUES
374                     // =============================================================
375
376                     $helpBlock.data(
377                         "original-contents",
378                         (
379                             $helpBlock.data("original-contents")
380                                 ? $helpBlock.data("original-contents")
381                                 : $helpBlock.html()
382                         )
383                     );
384
385                     $helpBlock.data(
386                         "original-role",
387                         (
388                             $helpBlock.data("original-role")
389                                 ? $helpBlock.data("original-role")
390                                 : $helpBlock.attr("role")
391                         )
392                     );
393
394                     $controlGroup.data(
395                         "original-classes",
396                         (
397                             $controlGroup.data("original-clases")
398                                 ? $controlGroup.data("original-classes")
399                                 : $controlGroup.attr("class")
400                         )
401                     );
402
403                     $this.data(
404                         "original-aria-invalid",
405                         (
406                             $this.data("original-aria-invalid")
407                                 ? $this.data("original-aria-invalid")
408                                 : $this.attr("aria-invalid")
409                         )
410                     );
411
412                     // =============================================================
413                     //                                                    VALIDATION
414                     // =============================================================
415
416                     $this.bind(
417                         "validation.validation",
418                         function (event, params) {
419
420                             var value = getValue($this);
421
422                             // Get a list of the errors to apply
423                             var errorsFound = [];
424
425                             $.each(validators, function (validatorType, validatorTypeArray) {
426                                 if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
427                                     $.each(validatorTypeArray, function (i, validator) {
428                                         if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
429                                             errorsFound.push(validator.message);
430                                         }
431                                     });
432                                 }
433                             });
434
435                             return errorsFound;
436                         }
437                     );
438
439                     $this.bind(
440                         "getValidators.validation",
441                         function () {
442                             return validators;
443                         }
444                     );
445
446                     // =============================================================
447                     //                                             WATCH FOR CHANGES
448                     // =============================================================
449                     $this.bind(
450                         "submit.validation",
451                         function () {
452                             return $this.triggerHandler("change.validation", {submitting: true});
453                         }
454                     );
455                     $this.bind(
456                         [
457                             "keyup",
458                             "focus",
459                             "blur",
460                             "click",
461                             "keydown",
462                             "keypress",
463                             "change"
464                         ].join(".validation ") + ".validation",
465                         function (e, params) {
466
467                             var value = getValue($this);
468
469                             var errorsFound = [];
470
471                             $controlGroup.find("input,textarea,select").each(function (i, el) {
472                                 var oldCount = errorsFound.length;
473                                 $.each($(el).triggerHandler("validation.validation", params), function (j, message) {
474                                     errorsFound.push(message);
475                                 });
476                                 if (errorsFound.length > oldCount) {
477                                     $(el).attr("aria-invalid", "true");
478                                 } else {
479                                     var original = $this.data("original-aria-invalid");
480                                     $(el).attr("aria-invalid", (original !== undefined ? original : false));
481                                 }
482                             });
483
484                             $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");
485
486                             errorsFound = $.unique(errorsFound.sort());
487
488                             // Were there any errors?
489                             if (errorsFound.length) {
490                                 // Better flag it up as a warning.
491                                 $controlGroup.removeClass("success error").addClass("warning");
492
493                                 // How many errors did we find?
494                                 if (settings.options.semanticallyStrict && errorsFound.length === 1) {
495                                     // Only one? Being strict? Just output it.
496                                     $helpBlock.html(errorsFound[0] +
497                                         ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
498                                 } else {
499                                     // Multiple? Being sloppy? Glue them together into an UL.
500                                     $helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" +
501                                         ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
502                                 }
503                             } else {
504                                 $controlGroup.removeClass("warning error success");
505                                 if (value.length > 0) {
506                                     $controlGroup.addClass("success");
507                                 }
508                                 $helpBlock.html($helpBlock.data("original-contents"));
509                             }
510
511                             if (e.type === "blur") {
512                                 $controlGroup.removeClass("success");
513                             }
514                         }
515                     );
516                     $this.bind("validationLostFocus.validation", function () {
517                         $controlGroup.removeClass("success");
518                     });
519                 });
520             },
521             destroy: function () {
522
523                 return this.each(
524                     function () {
525
526                         var
527                             $this = $(this),
528                             $controlGroup = $this.parents(".control-group").first(),
529                             $helpBlock = $controlGroup.find(".help-block").first();
530
531                         // remove our events
532                         $this.unbind('.validation'); // events are namespaced.
533                         // reset help text
534                         $helpBlock.html($helpBlock.data("original-contents"));
535                         // reset classes
536                         $controlGroup.attr("class", $controlGroup.data("original-classes"));
537                         // reset aria
538                         $this.attr("aria-invalid", $this.data("original-aria-invalid"));
539                         // reset role
540                         $helpBlock.attr("role", $this.data("original-role"));
541                         // remove all elements we created
542                         if (createdElements.indexOf($helpBlock[0]) > -1) {
543                             $helpBlock.remove();
544                         }
545
546                     }
547                 );
548
549             },
550             collectErrors: function (includeEmpty) {
551
552                 var errorMessages = {};
553                 this.each(function (i, el) {
554                     var $el = $(el);
555                     var name = $el.attr("name");
556                     var errors = $el.triggerHandler("validation.validation", {includeEmpty: true});
557                     errorMessages[name] = $.extend(true, errors, errorMessages[name]);
558                 });
559
560                 $.each(errorMessages, function (i, el) {
561                     if (el.length === 0) {
562                         delete errorMessages[i];
563                     }
564                 });
565
566                 return errorMessages;
567
568             },
569             hasErrors: function () {
570
571                 var errorMessages = [];
572
573                 this.each(function (i, el) {
574                     errorMessages = errorMessages.concat(
575                         $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : []
576                     );
577                 });
578
579                 return (errorMessages.length > 0);
580             },
581             override: function (newDefaults) {
582                 defaults = $.extend(true, defaults, newDefaults);
583             }
584         },
585         validatorTypes: {
586             callback: {
587                 name: "callback",
588                 init: function ($this, name) {
589                     return {
590                         validatorName: name,
591                         callback: $this.data("validation" + name + "Callback"),
592                         lastValue: $this.val(),
593                         lastValid: true,
594                         lastFinished: true
595                     };
596                 },
597                 validate: function ($this, value, validator) {
598                     if (validator.lastValue === value && validator.lastFinished) {
599                         return !validator.lastValid;
600                     }
601
602                     if (validator.lastFinished === true) {
603                         validator.lastValue = value;
604                         validator.lastValid = true;
605                         validator.lastFinished = false;
606
607                         var rrjqbvValidator = validator;
608                         var rrjqbvThis = $this;
609                         executeFunctionByName(
610                             validator.callback,
611                             window,
612                             $this,
613                             value,
614                             function (data) {
615                                 if (rrjqbvValidator.lastValue === data.value) {
616                                     rrjqbvValidator.lastValid = data.valid;
617                                     if (data.message) {
618                                         rrjqbvValidator.message = data.message;
619                                     }
620                                     rrjqbvValidator.lastFinished = true;
621                                     rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
622                                     // Timeout is set to avoid problems with the events being considered 'already fired'
623                                     setTimeout(function () {
624                                         rrjqbvThis.trigger("change.validation");
625                                     }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
626                                 }
627                             }
628                         );
629                     }
630
631                     return false;
632
633                 }
634             },
635             ajax: {
636                 name: "ajax",
637                 init: function ($this, name) {
638                     return {
639                         validatorName: name,
640                         url: $this.data("validation" + name + "Ajax"),
641                         lastValue: $this.val(),
642                         lastValid: true,
643                         lastFinished: true
644                     };
645                 },
646                 validate: function ($this, value, validator) {
647                     if ("" + validator.lastValue === "" + value && validator.lastFinished === true) {
648                         return validator.lastValid === false;
649                     }
650
651                     if (validator.lastFinished === true) {
652                         validator.lastValue = value;
653                         validator.lastValid = true;
654                         validator.lastFinished = false;
655                         $.ajax({
656                             url: validator.url,
657                             data: "value=" + value + "&field=" + $this.attr("name"),
658                             dataType: "json",
659                             success: function (data) {
660                                 if ("" + validator.lastValue === "" + data.value) {
661                                     validator.lastValid = !!(data.valid);
662                                     if (data.message) {
663                                         validator.message = data.message;
664                                     }
665                                     validator.lastFinished = true;
666                                     $this.data("validation" + validator.validatorName + "Message", validator.message);
667                                     // Timeout is set to avoid problems with the events being considered 'already fired'
668                                     setTimeout(function () {
669                                         $this.trigger("change.validation");
670                                     }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
671                                 }
672                             },
673                             failure: function () {
674                                 validator.lastValid = true;
675                                 validator.message = "ajax call failed";
676                                 validator.lastFinished = true;
677                                 $this.data("validation" + validator.validatorName + "Message", validator.message);
678                                 // Timeout is set to avoid problems with the events being considered 'already fired'
679                                 setTimeout(function () {
680                                     $this.trigger("change.validation");
681                                 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
682                             }
683                         });
684                     }
685
686                     return false;
687
688                 }
689             },
690             regex: {
691                 name: "regex",
692                 init: function ($this, name) {
693                     return {regex: regexFromString($this.data("validation" + name + "Regex"))};
694                 },
695                 validate: function ($this, value, validator) {
696                     return (!validator.regex.test(value) && !validator.negative)
697                         || (validator.regex.test(value) && validator.negative);
698                 }
699             },
700             required: {
701                 name: "required",
702                 init: function ($this, name) {
703                     return {};
704                 },
705                 validate: function ($this, value, validator) {
706                     return !!(value.length === 0 && !validator.negative)
707                         || !!(value.length > 0 && validator.negative);
708                 },
709                 blockSubmit: true
710             },
711             match: {
712                 name: "match",
713                 init: function ($this, name) {
714                     var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
715                     element.bind("validation.validation", function () {
716                         $this.trigger("change.validation", {submitting: true});
717                     });
718                     return {"element": element};
719                 },
720                 validate: function ($this, value, validator) {
721                     return (value !== validator.element.val() && !validator.negative)
722                         || (value === validator.element.val() && validator.negative);
723                 },
724                 blockSubmit: true
725             },
726             max: {
727                 name: "max",
728                 init: function ($this, name) {
729                     return {max: $this.data("validation" + name + "Max")};
730                 },
731                 validate: function ($this, value, validator) {
732                     return (parseFloat(value, 10) > parseFloat(validator.max, 10) && !validator.negative)
733                         || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
734                 }
735             },
736             min: {
737                 name: "min",
738                 init: function ($this, name) {
739                     return {min: $this.data("validation" + name + "Min")};
740                 },
741                 validate: function ($this, value, validator) {
742                     return (parseFloat(value) < parseFloat(validator.min) && !validator.negative)
743                         || (parseFloat(value) >= parseFloat(validator.min) && validator.negative);
744                 }
745             },
746             maxlength: {
747                 name: "maxlength",
748                 init: function ($this, name) {
749                     return {maxlength: $this.data("validation" + name + "Maxlength")};
750                 },
751                 validate: function ($this, value, validator) {
752                     return ((value.length > validator.maxlength) && !validator.negative)
753                         || ((value.length <= validator.maxlength) && validator.negative);
754                 }
755             },
756             minlength: {
757                 name: "minlength",
758                 init: function ($this, name) {
759                     return {minlength: $this.data("validation" + name + "Minlength")};
760                 },
761                 validate: function ($this, value, validator) {
762                     return ((value.length < validator.minlength) && !validator.negative)
763                         || ((value.length >= validator.minlength) && validator.negative);
764                 }
765             },
766             maxchecked: {
767                 name: "maxchecked",
768                 init: function ($this, name) {
769                     var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
770                     elements.bind("click.validation", function () {
771                         $this.trigger("change.validation", {includeEmpty: true});
772                     });
773                     return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements};
774                 },
775                 validate: function ($this, value, validator) {
776                     return (validator.elements.filter(":checked").length > validator.maxchecked && !validator.negative)
777                         || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
778                 },
779                 blockSubmit: true
780             },
781             minchecked: {
782                 name: "minchecked",
783                 init: function ($this, name) {
784                     var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
785                     elements.bind("click.validation", function () {
786                         $this.trigger("change.validation", {includeEmpty: true});
787                     });
788                     return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements};
789                 },
790                 validate: function ($this, value, validator) {
791                     return (validator.elements.filter(":checked").length < validator.minchecked && !validator.negative)
792                         || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
793                 },
794                 blockSubmit: true
795             }
796         },
797         builtInValidators: {
798             email: {
799                 name: "Email",
800                 type: "shortcut",
801                 shortcut: "validemail"
802             },
803             validemail: {
804                 name: "Validemail",
805                 type: "regex",
806                 regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
807                 message: "Not a valid email address<!-- data-validator-validemail-message to override -->"
808             },
809             passwordagain: {
810                 name: "Passwordagain",
811                 type: "match",
812                 match: "password",
813                 message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->"
814             },
815             positive: {
816                 name: "Positive",
817                 type: "shortcut",
818                 shortcut: "number,positivenumber"
819             },
820             negative: {
821                 name: "Negative",
822                 type: "shortcut",
823                 shortcut: "number,negativenumber"
824             },
825             number: {
826                 name: "Number",
827                 type: "regex",
828                 regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
829                 message: "Must be a number<!-- data-validator-number-message to override -->"
830             },
831             integer: {
832                 name: "Integer",
833                 type: "regex",
834                 regex: "[+-]?\\\d+",
835                 message: "No decimal places allowed<!-- data-validator-integer-message to override -->"
836             },
837             positivenumber: {
838                 name: "Positivenumber",
839                 type: "min",
840                 min: 0,
841                 message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->"
842             },
843             negativenumber: {
844                 name: "Negativenumber",
845                 type: "max",
846                 max: 0,
847                 message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->"
848             },
849             required: {
850                 name: "Required",
851                 type: "required",
852                 message: "This is required<!-- data-validator-required-message to override -->"
853             },
854             checkone: {
855                 name: "Checkone",
856                 type: "minchecked",
857                 minchecked: 1,
858                 message: "Check at least one option<!-- data-validation-checkone-message to override -->"
859             }
860         }
861     };
862
863     var formatValidatorName = function (name) {
864         return name
865             .toLowerCase()
866             .replace(
867                 /(^|\s)([a-z])/g,
868                 function (m, p1, p2) {
869                     return p1 + p2.toUpperCase();
870                 }
871             )
872             ;
873     };
874
875     var getValue = function ($this) {
876         // Extract the value we're talking about
877         var value = $this.val();
878         var type = $this.attr("type");
879         if (type === "checkbox") {
880             value = ($this.is(":checked") ? value : "");
881         }
882         if (type === "radio") {
883             value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
884         }
885         return value;
886     };
887
888     function regexFromString(inputstring) {
889         return new RegExp("^" + inputstring + "$");
890     }
891
892     /**
893      * Thanks to Jason Bunting via StackOverflow.com
894      *
895      * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
896      * Short link: http://tinyurl.com/executeFunctionByName
897      **/
898     function executeFunctionByName(functionName, context /*, args*/) {
899         var args = Array.prototype.slice.call(arguments).splice(2);
900         var namespaces = functionName.split(".");
901         var func = namespaces.pop();
902         for (var i = 0; i < namespaces.length; i++) {
903             context = context[namespaces[i]];
904         }
905         return context[func].apply(this, args);
906     }
907
908     $.fn.jqBootstrapValidation = function (method) {
909
910         if (defaults.methods[method]) {
911             return defaults.methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
912         } else if (typeof method === 'object' || !method) {
913             return defaults.methods.init.apply(this, arguments);
914         } else {
915             $.error('Method ' + method + ' does not exist on jQuery.jqBootstrapValidation');
916             return null;
917         }
918
919     };
920
921     $.jqBootstrapValidation = function (options) {
922         $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this, arguments);
923     };
924
925 })(jQuery);