[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/posabsolute-jQuery-Validation-Engine/js/ -> jquery.validationEngine.js (source)

   1  /*

   2   * Inline Form Validation Engine 2.6.2, jQuery plugin

   3   *

   4   * Copyright(c) 2010, Cedric Dugas

   5   * http://www.position-absolute.com

   6   *

   7   * 2.0 Rewrite by Olivier Refalo

   8   * http://www.crionics.com

   9   *

  10   * Form validation engine allowing custom regex rules to be added.

  11   * Licensed under the MIT License

  12   */
  13   (function($) {
  14  
  15       "use strict";
  16  
  17       var methods = {
  18  
  19           /**

  20           * Kind of the constructor, called before any action

  21           * @param {Map} user options

  22           */
  23           init: function(options) {
  24               var form = this;
  25               if (!form.data('jqv') || form.data('jqv') == null ) {
  26                   options = methods._saveOptions(form, options);
  27                   // bind all formError elements to close on click

  28                   $(".formError").live("click", function() {
  29                       $(this).fadeOut(150, function() {
  30                           // remove prompt once invisible

  31                           $(this).parent('.formErrorOuter').remove();
  32                           $(this).remove();
  33                       });
  34                   });
  35               }
  36               return this;
  37           },
  38          /**

  39          * Attachs jQuery.validationEngine to form.submit and field.blur events

  40          * Takes an optional params: a list of options

  41          * ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});

  42          */
  43          attach: function(userOptions) {
  44  
  45              var form = this;
  46              var options;
  47  
  48              if(userOptions)
  49                  options = methods._saveOptions(form, userOptions);
  50              else
  51                  options = form.data('jqv');
  52  
  53              options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" : "class";
  54              if (options.binded) {
  55  
  56                  // delegate fields

  57                  form.on(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
  58                  form.on("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent);
  59                  form.on(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", {"delay": 300}, methods._onFieldEvent);
  60              }
  61              if (options.autoPositionUpdate) {
  62                  $(window).bind("resize", {
  63                      "noAnimation": true,
  64                      "formElem": form
  65                  }, methods.updatePromptsPosition);
  66              }
  67              form.on("click","a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
  68              form.removeData('jqv_submitButton');
  69  
  70              // bind form.submit

  71              form.on("submit", methods._onSubmitEvent);
  72              return this;
  73          },
  74          /**

  75          * Unregisters any bindings that may point to jQuery.validaitonEngine

  76          */
  77          detach: function() {
  78  
  79              var form = this;
  80              var options = form.data('jqv');
  81  
  82              // unbind fields

  83              form.find("["+options.validateAttribute+"*=validate]").not("[type=checkbox]").off(options.validationEventTrigger, methods._onFieldEvent);
  84              form.find("["+options.validateAttribute+"*=validate][type=checkbox],[class*=validate][type=radio]").off("click", methods._onFieldEvent);
  85  
  86              // unbind form.submit

  87              form.off("submit", methods.onAjaxFormComplete);
  88  
  89              // unbind form.submit

  90              form.die("submit", methods.onAjaxFormComplete);
  91              form.removeData('jqv');
  92              
  93              form.off("click", "a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
  94              form.removeData('jqv_submitButton');
  95  
  96              if (options.autoPositionUpdate)
  97                  $(window).unbind("resize", methods.updatePromptsPosition);
  98  
  99              return this;
 100          },
 101          /**

 102          * Validates either a form or a list of fields, shows prompts accordingly.

 103          * Note: There is no ajax form validation with this method, only field ajax validation are evaluated

 104          *

 105          * @return true if the form validates, false if it fails

 106          */
 107          validate: function() {
 108              var element = $(this);
 109              var valid = null;
 110  
 111              if((element.is("form") || element.hasClass("validationEngineContainer")) && !element.hasClass('validating')) {
 112                  element.addClass('validating');
 113                  var options = element.data('jqv');
 114                  var valid = methods._validateFields(this);
 115                  
 116                  // If the form doesn't validate, clear the 'validating' class before the user has a chance to submit again

 117                  setTimeout(function(){
 118                      element.removeClass('validating');
 119                  }, 100);
 120                  if (valid && options.onSuccess) {
 121                      options.onSuccess();
 122                  } else if (!valid && options.onFailure) {
 123                      options.onFailure();
 124                  }
 125              } else if (element.is('form') || element.hasClass('validationEngineContainer')) {
 126                  element.removeClass('validating');
 127              } else {
 128                  // field validation

 129                  var form = element.closest('form, .validationEngineContainer'),
 130                      options = (form.data('jqv')) ? form.data('jqv') : $.validationEngine.defaults,
 131                      valid = methods._validateField(element, options);
 132  
 133                  if (valid && options.onFieldSuccess)
 134                      options.onFieldSuccess();
 135                  else if (options.onFieldFailure && options.InvalidFields.length > 0) {
 136                      options.onFieldFailure();
 137                  }
 138              }
 139              if(options && options.onValidationComplete) {
 140                  // !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing

 141                  return !!options.onValidationComplete(form, valid);
 142              }
 143              return valid;
 144          },
 145          /**

 146          *  Redraw prompts position, useful when you change the DOM state when validating

 147          */
 148          updatePromptsPosition: function(event) {
 149  
 150              if (event && this == window) {
 151                  var form = event.data.formElem;
 152                  var noAnimation = event.data.noAnimation;
 153              }
 154              else
 155                  var form = $(this.closest('form, .validationEngineContainer'));
 156  
 157              var options = form.data('jqv');
 158              // No option, take default one

 159              form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each(function(){
 160                  var field = $(this);
 161                  if (options.prettySelect && field.is(":hidden")){
 162                      var jqSelector = methods._jqSelector(field.attr('id'));
 163                      field = form.find("#" + options.usePrefix + jqSelector);
 164                      if(field.length <= 0){
 165                          field = form.find("#" + jqSelector + options.useSuffix);
 166                      }
 167                    //field = form.find("#" + options.usePrefix + field.attr('id') + options.useSuffix);

 168                  }
 169                  var prompt = methods._getPrompt(field);
 170                  var promptText = $(prompt).find(".formErrorContent").html();
 171  
 172                  if(prompt)
 173                      methods._updatePrompt(field, $(prompt), promptText, undefined, false, options, noAnimation);
 174              });
 175              return this;
 176          },
 177          /**

 178          * Displays a prompt on a element.

 179          * Note that the element needs an id!

 180          *

 181          * @param {String} promptText html text to display type

 182          * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)

 183          * @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight

 184          */
 185          showPrompt: function(promptText, type, promptPosition, showArrow) {
 186              var form = this.closest('form, .validationEngineContainer');
 187              var options = form.data('jqv');
 188              // No option, take default one

 189              if(!options)
 190                  options = methods._saveOptions(this, options);
 191              if(promptPosition)
 192                  options.promptPosition=promptPosition;
 193              options.showArrow = showArrow==true;
 194  
 195              methods._showPrompt(this, promptText, type, false, options);
 196              return this;
 197          },
 198          /**

 199          * Closes form error prompts, CAN be invidual

 200          */
 201          hide: function() {
 202               var form = $(this).closest('form, .validationEngineContainer');
 203               var options = form.data('jqv');
 204               var fadeDuration = (options && options.fadeDuration) ? options.fadeDuration : 0.3;
 205               var closingtag;
 206               
 207               if($(this).is("form") || $(this).hasClass("validationEngineContainer")) {
 208                   closingtag = "parentForm"+methods._getClassName($(this).attr("id"));
 209               } else {
 210                   closingtag = methods._getClassName($(this).attr("id")) +"formError";
 211               }
 212               $('.'+closingtag).fadeTo(fadeDuration, 0.3, function() {
 213                   $(this).parent('.formErrorOuter').remove();
 214                   $(this).remove();
 215               });
 216               return this;
 217           },
 218           /**

 219           * Closes all error prompts on the page

 220           */
 221           hideAll: function() {
 222  
 223               var form = this;
 224               var options = form.data('jqv');
 225               var duration = options ? options.fadeDuration:300;
 226               $('.formError').fadeTo(duration, 300, function() {
 227                   $(this).parent('.formErrorOuter').remove();
 228                   $(this).remove();
 229               });
 230               return this;
 231           },
 232          /**

 233          * Typically called when user exists a field using tab or a mouse click, triggers a field

 234          * validation

 235          */
 236          _onFieldEvent: function(event) {
 237              var field = $(this);
 238              var form = field.closest('form, .validationEngineContainer');
 239              var options = form.data('jqv');
 240              options.eventTrigger = "field";
 241              // validate the current field

 242              window.setTimeout(function() {
 243                  methods._validateField(field, options);
 244                  if (options.InvalidFields.length == 0 && options.onFieldSuccess) {
 245                      options.onFieldSuccess();
 246                  } else if (options.InvalidFields.length > 0 && options.onFieldFailure) {
 247                      options.onFieldFailure();
 248                  }
 249              }, (event.data) ? event.data.delay : 0);
 250  
 251          },
 252          /**

 253          * Called when the form is submited, shows prompts accordingly

 254          *

 255          * @param {jqObject}

 256          *            form

 257          * @return false if form submission needs to be cancelled

 258          */
 259          _onSubmitEvent: function() {
 260              var form = $(this);
 261              var options = form.data('jqv');
 262              
 263              //check if it is trigger from skipped button

 264              if (form.data("jqv_submitButton")){
 265                  var submitButton = $("#" + form.data("jqv_submitButton"));
 266                  if (submitButton){
 267                      if (submitButton.length > 0){
 268                          if (submitButton.hasClass("validate-skip") || submitButton.attr("data-validation-engine-skip") == "true")
 269                              return true;
 270                      }
 271                  }
 272              }
 273  
 274              options.eventTrigger = "submit";
 275  
 276              // validate each field 

 277              // (- skip field ajax validation, not necessary IF we will perform an ajax form validation)

 278              var r=methods._validateFields(form);
 279  
 280              if (r && options.ajaxFormValidation) {
 281                  methods._validateFormWithAjax(form, options);
 282                  // cancel form auto-submission - process with async call onAjaxFormComplete

 283                  return false;
 284              }
 285  
 286              if(options && options.onValidationComplete) {
 287                  // !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing

 288                  return !!options.onValidationComplete(form, r);
 289              }
 290              return r;
 291          },
 292          /**

 293          * Return true if the ajax field validations passed so far

 294          * @param {Object} options

 295          * @return true, is all ajax validation passed so far (remember ajax is async)

 296          */
 297          _checkAjaxStatus: function(options) {
 298              var status = true;
 299              $.each(options.ajaxValidCache, function(key, value) {
 300                  if (!value) {
 301                      status = false;
 302                      // break the each

 303                      return false;
 304                  }
 305              });
 306              return status;
 307          },
 308          
 309          /**

 310          * Return true if the ajax field is validated

 311          * @param {String} fieldid

 312          * @param {Object} options

 313          * @return true, if validation passed, false if false or doesn't exist

 314          */
 315          _checkAjaxFieldStatus: function(fieldid, options) {
 316              return options.ajaxValidCache[fieldid] == true;
 317          },
 318          /**

 319          * Validates form fields, shows prompts accordingly

 320          *

 321          * @param {jqObject}

 322          *            form

 323          * @param {skipAjaxFieldValidation}

 324          *            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked

 325          *

 326          * @return true if form is valid, false if not, undefined if ajax form validation is done

 327          */
 328          _validateFields: function(form) {
 329              var options = form.data('jqv');
 330  
 331              // this variable is set to true if an error is found

 332              var errorFound = false;
 333  
 334              // Trigger hook, start validation

 335              form.trigger("jqv.form.validating");
 336              // first, evaluate status of non ajax fields

 337              var first_err=null;
 338              form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each( function() {
 339                  var field = $(this);
 340                  var names = [];
 341                  if ($.inArray(field.attr('name'), names) < 0) {
 342                      errorFound |= methods._validateField(field, options);
 343                      if (errorFound && first_err==null)
 344                          if (field.is(":hidden") && options.prettySelect){
 345                                          var jqSelector = methods._jqSelector(field.attr('id'));
 346                                          first_err = field = form.find("#" + options.usePrefix + jqSelector);
 347                                          if(field.length <= 0){
 348                                              first_err = field = form.find("#" + jqSelector + options.useSuffix);
 349                                          }
 350                                           //first_err = field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);

 351                          }
 352                                      else
 353                                           first_err=field;
 354                      if (options.doNotShowAllErrosOnSubmit)
 355                          return false;
 356                      names.push(field.attr('name'));
 357  
 358                      //if option set, stop checking validation rules after one error is found

 359                      if(options.showOneMessage == true && errorFound){
 360                          return false;
 361                      }
 362                  }
 363              });
 364  
 365              // second, check to see if all ajax calls completed ok

 366              // errorFound |= !methods._checkAjaxStatus(options);

 367  
 368              // third, check status and scroll the container accordingly

 369              form.trigger("jqv.form.result", [errorFound]);
 370  
 371              if (errorFound) {
 372                  if (options.scroll) {
 373                      var destination=first_err.offset().top;
 374                      var fixleft = first_err.offset().left;
 375  
 376                      //prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)

 377                      var positionType=options.promptPosition;
 378                      if (typeof(positionType)=='string' && positionType.indexOf(":")!=-1)
 379                          positionType=positionType.substring(0,positionType.indexOf(":"));
 380  
 381                      if (positionType!="bottomRight" && positionType!="bottomLeft") {
 382                          var prompt_err= methods._getPrompt(first_err);
 383                          if (prompt_err) {
 384                              destination=prompt_err.offset().top;
 385                          }
 386                      }
 387                      
 388                      // Offset the amount the page scrolls by an amount in px to accomodate fixed elements at top of page

 389                      if (options.scrollOffset) {
 390                          destination -= options.scrollOffset;
 391                      }
 392  
 393                      // get the position of the first error, there should be at least one, no need to check this

 394                      //var destination = form.find(".formError:not('.greenPopup'):first").offset().top;

 395                      if (options.isOverflown) {
 396                          var overflowDIV = $(options.overflownDIV);
 397                          if(!overflowDIV.length) return false;
 398                          var scrollContainerScroll = overflowDIV.scrollTop();
 399                          var scrollContainerPos = -parseInt(overflowDIV.offset().top);
 400  
 401                          destination += scrollContainerScroll + scrollContainerPos - 5;
 402                          var scrollContainer = $(options.overflownDIV + ":not(:animated)");
 403  
 404                          scrollContainer.animate({ scrollTop: destination }, 1100, function(){
 405                              if(options.focusFirstField) first_err.focus();
 406                          });
 407  
 408                      } else {
 409                          $("html, body").animate({
 410                              scrollTop: destination
 411                          }, 1100, function(){
 412                              if(options.focusFirstField) first_err.focus();
 413                          });
 414                          $("html, body").animate({scrollLeft: fixleft},1100)
 415                      }
 416  
 417                  } else if(options.focusFirstField)
 418                      first_err.focus();
 419                  return false;
 420              }
 421              return true;
 422          },
 423          /**

 424          * This method is called to perform an ajax form validation.

 425          * During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true

 426          *

 427          * @param {jqObject} form

 428          * @param {Map} options

 429          */
 430          _validateFormWithAjax: function(form, options) {
 431  
 432              var data = form.serialize();
 433                                      var type = (options.ajaxFormValidationMethod) ? options.ajaxFormValidationMethod : "GET";
 434              var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
 435                                      var dataType = (options.dataType) ? options.dataType : "json";
 436              $.ajax({
 437                  type: type,
 438                  url: url,
 439                  cache: false,
 440                  dataType: dataType,
 441                  data: data,
 442                  form: form,
 443                  methods: methods,
 444                  options: options,
 445                  beforeSend: function() {
 446                      return options.onBeforeAjaxFormValidation(form, options);
 447                  },
 448                  error: function(data, transport) {
 449                      methods._ajaxError(data, transport);
 450                  },
 451                  success: function(json) {
 452                      if ((dataType == "json") && (json !== true)) {
 453                          // getting to this case doesn't necessary means that the form is invalid

 454                          // the server may return green or closing prompt actions

 455                          // this flag helps figuring it out

 456                          var errorInForm=false;
 457                          for (var i = 0; i < json.length; i++) {
 458                              var value = json[i];
 459  
 460                              var errorFieldId = value[0];
 461                              var errorField = $($("#" + errorFieldId)[0]);
 462  
 463                              // make sure we found the element

 464                              if (errorField.length == 1) {
 465  
 466                                  // promptText or selector

 467                                  var msg = value[2];
 468                                  // if the field is valid

 469                                  if (value[1] == true) {
 470  
 471                                      if (msg == ""  || !msg){
 472                                          // if for some reason, status==true and error="", just close the prompt

 473                                          methods._closePrompt(errorField);
 474                                      } else {
 475                                          // the field is valid, but we are displaying a green prompt

 476                                          if (options.allrules[msg]) {
 477                                              var txt = options.allrules[msg].alertTextOk;
 478                                              if (txt)
 479                                                  msg = txt;
 480                                          }
 481                                          if (options.showPrompts) methods._showPrompt(errorField, msg, "pass", false, options, true);
 482                                      }
 483                                  } else {
 484                                      // the field is invalid, show the red error prompt

 485                                      errorInForm|=true;
 486                                      if (options.allrules[msg]) {
 487                                          var txt = options.allrules[msg].alertText;
 488                                          if (txt)
 489                                              msg = txt;
 490                                      }
 491                                      if(options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
 492                                  }
 493                              }
 494                          }
 495                          options.onAjaxFormComplete(!errorInForm, form, json, options);
 496                      } else
 497                          options.onAjaxFormComplete(true, form, json, options);
 498  
 499                  }
 500              });
 501  
 502          },
 503          /**

 504          * Validates field, shows prompts accordingly

 505          *

 506          * @param {jqObject}

 507          *            field

 508          * @param {Array[String]}

 509          *            field's validation rules

 510          * @param {Map}

 511          *            user options

 512          * @return false if field is valid (It is inversed for *fields*, it return false on validate and true on errors.)

 513          */
 514          _validateField: function(field, options, skipAjaxValidation) {
 515              if (!field.attr("id")) {
 516                  field.attr("id", "form-validation-field-" + $.validationEngine.fieldIdCounter);
 517                  ++$.validationEngine.fieldIdCounter;
 518              }
 519  
 520             if (!options.validateNonVisibleFields && (field.is(":hidden") && !options.prettySelect || field.parent().is(":hidden")))
 521                  return false;
 522  
 523              var rulesParsing = field.attr(options.validateAttribute);
 524              var getRules = /validate\[(.*)\]/.exec(rulesParsing);
 525  
 526              if (!getRules)
 527                  return false;
 528              var str = getRules[1];
 529              var rules = str.split(/\[|,|\]/);
 530  
 531              // true if we ran the ajax validation, tells the logic to stop messing with prompts

 532              var isAjaxValidator = false;
 533              var fieldName = field.attr("name");
 534              var promptText = "";
 535              var promptType = "";
 536              var required = false;
 537              var limitErrors = false;
 538              options.isError = false;
 539              options.showArrow = true;
 540              
 541              // If the programmer wants to limit the amount of error messages per field,

 542              if (options.maxErrorsPerField > 0) {
 543                  limitErrors = true;
 544              }
 545  
 546              var form = $(field.closest("form, .validationEngineContainer"));
 547              // Fix for adding spaces in the rules

 548              for (var i = 0; i < rules.length; i++) {
 549                  rules[i] = rules[i].replace(" ", "");
 550                  // Remove any parsing errors

 551                  if (rules[i] === '') {
 552                      delete rules[i];
 553                  }
 554              }
 555  
 556              for (var i = 0, field_errors = 0; i < rules.length; i++) {
 557                  
 558                  // If we are limiting errors, and have hit the max, break

 559                  if (limitErrors && field_errors >= options.maxErrorsPerField) {
 560                      // If we haven't hit a required yet, check to see if there is one in the validation rules for this

 561                      // field and that it's index is greater or equal to our current index

 562                      if (!required) {
 563                          var have_required = $.inArray('required', rules);
 564                          required = (have_required != -1 &&  have_required >= i);
 565                      }
 566                      break;
 567                  }
 568                  
 569                  
 570                  var errorMsg = undefined;
 571                  switch (rules[i]) {
 572  
 573                      case "required":
 574                          required = true;
 575                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._required);
 576                          break;
 577                      case "custom":
 578                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._custom);
 579                          break;
 580                      case "groupRequired":
 581                          // Check is its the first of group, if not, reload validation with first field

 582                          // AND continue normal validation on present field

 583                          var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
 584                          var firstOfGroup = form.find(classGroup).eq(0);
 585                          if(firstOfGroup[0] != field[0]){
 586  
 587                              methods._validateField(firstOfGroup, options, skipAjaxValidation); 
 588                              options.showArrow = true;
 589  
 590                          }
 591                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._groupRequired);
 592                          if(errorMsg)  required = true;
 593                          options.showArrow = false;
 594                          break;
 595                      case "ajax":
 596                          // AJAX defaults to returning it's loading message

 597                          errorMsg = methods._ajax(field, rules, i, options);
 598                          if (errorMsg) {
 599                              promptType = "load";
 600                          }
 601                          break;
 602                      case "minSize":
 603                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minSize);
 604                          break;
 605                      case "maxSize":
 606                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxSize);
 607                          break;
 608                      case "min":
 609                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._min);
 610                          break;
 611                      case "max":
 612                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._max);
 613                          break;
 614                      case "past":
 615                          errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._past);
 616                          break;
 617                      case "future":
 618                          errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._future);
 619                          break;
 620                      case "dateRange":
 621                          var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
 622                          options.firstOfGroup = form.find(classGroup).eq(0);
 623                          options.secondOfGroup = form.find(classGroup).eq(1);
 624  
 625                          //if one entry out of the pair has value then proceed to run through validation

 626                          if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
 627                              errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateRange);
 628                          }
 629                          if (errorMsg) required = true;
 630                          options.showArrow = false;
 631                          break;
 632  
 633                      case "dateTimeRange":
 634                          var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
 635                          options.firstOfGroup = form.find(classGroup).eq(0);
 636                          options.secondOfGroup = form.find(classGroup).eq(1);
 637  
 638                          //if one entry out of the pair has value then proceed to run through validation

 639                          if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
 640                              errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateTimeRange);
 641                          }
 642                          if (errorMsg) required = true;
 643                          options.showArrow = false;
 644                          break;
 645                      case "maxCheckbox":
 646                          field = $(form.find("input[name='" + fieldName + "']"));
 647                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxCheckbox);
 648                          break;
 649                      case "minCheckbox":
 650                          field = $(form.find("input[name='" + fieldName + "']"));
 651                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minCheckbox);
 652                          break;
 653                      case "equals":
 654                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._equals);
 655                          break;
 656                      case "funcCall":
 657                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCall);
 658                          break;
 659                      case "creditCard":
 660                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._creditCard);
 661                          break;
 662                      case "condRequired":
 663                          errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._condRequired);
 664                          if (errorMsg !== undefined) {
 665                              required = true;
 666                          }
 667                          break;
 668  
 669                      default:
 670                  }
 671                  
 672                  var end_validation = false;
 673                  
 674                  // If we were passed back an message object, check what the status was to determine what to do

 675                  if (typeof errorMsg == "object") {
 676                      switch (errorMsg.status) {
 677                          case "_break":
 678                              end_validation = true;
 679                              break;
 680                          // If we have an error message, set errorMsg to the error message

 681                          case "_error":
 682                              errorMsg = errorMsg.message;
 683                              break;
 684                          // If we want to throw an error, but not show a prompt, return early with true

 685                          case "_error_no_prompt":
 686                              return true;
 687                              break;
 688                          // Anything else we continue on

 689                          default:
 690                              break;
 691                      }
 692                  }
 693                  
 694                  // If it has been specified that validation should end now, break

 695                  if (end_validation) {
 696                      break;
 697                  }
 698                  
 699                  // If we have a string, that means that we have an error, so add it to the error message.

 700                  if (typeof errorMsg == 'string') {
 701                      promptText += errorMsg + "<br/>";
 702                      options.isError = true;
 703                      field_errors++;
 704                  }    
 705              }
 706              // If the rules required is not added, an empty field is not validated

 707              if(!required && !(field.val()) && field.val().length < 1) options.isError = false;
 708  
 709              // Hack for radio/checkbox group button, the validation go into the

 710              // first radio/checkbox of the group

 711              var fieldType = field.prop("type");
 712              var positionType=field.data("promptPosition") || options.promptPosition;
 713  
 714              if ((fieldType == "radio" || fieldType == "checkbox") && form.find("input[name='" + fieldName + "']").size() > 1) {
 715                  if(positionType === 'inline') {
 716                      field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:last"));
 717                  } else {
 718                  field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:first"));
 719                  }
 720                  options.showArrow = false;
 721              }
 722  
 723              if(field.is(":hidden") && options.prettySelect) {
 724                  var jqSelector = methods._jqSelector(field.attr('id'));
 725                  field = form.find("#" + options.usePrefix + jqSelector);
 726                  if(field.length <= 0){
 727                      field = form.find("#" + jqSelector + options.useSuffix);
 728                  }
 729                  //field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);

 730              }
 731  
 732              if (options.isError && options.showPrompts){
 733                  methods._showPrompt(field, promptText, promptType, false, options);
 734              }else{
 735                  if (!isAjaxValidator) methods._closePrompt(field);
 736              }
 737  
 738              if (!isAjaxValidator) {
 739                  field.trigger("jqv.field.result", [field, options.isError, promptText]);
 740              }
 741  
 742              /* Record error */

 743              var errindex = $.inArray(field[0], options.InvalidFields);
 744              if (errindex == -1) {
 745                  if (options.isError)
 746                  options.InvalidFields.push(field[0]);
 747              } else if (!options.isError) {
 748                  options.InvalidFields.splice(errindex, 1);
 749              }
 750                  
 751              methods._handleStatusCssClasses(field, options);
 752      
 753              /* run callback function for each field */

 754              if (options.isError && options.onFieldFailure)
 755                  options.onFieldFailure(field);
 756  
 757              if (!options.isError && options.onFieldSuccess)
 758                  options.onFieldSuccess(field);
 759  
 760              return options.isError;
 761          },
 762          /**

 763          * Handling css classes of fields indicating result of validation 

 764          *

 765          * @param {jqObject}

 766          *            field

 767          * @param {Array[String]}

 768          *            field's validation rules            

 769          * @private

 770          */
 771          _handleStatusCssClasses: function(field, options) {
 772              /* remove all classes */

 773              if(options.addSuccessCssClassToField)
 774                  field.removeClass(options.addSuccessCssClassToField);
 775              
 776              if(options.addFailureCssClassToField)
 777                  field.removeClass(options.addFailureCssClassToField);
 778              
 779              /* Add classes */

 780              if (options.addSuccessCssClassToField && !options.isError)
 781                  field.addClass(options.addSuccessCssClassToField);
 782              
 783              if (options.addFailureCssClassToField && options.isError)
 784                  field.addClass(options.addFailureCssClassToField);        
 785          },
 786          
 787           /********************

 788            * _getErrorMessage

 789            *

 790            * @param form

 791            * @param field

 792            * @param rule

 793            * @param rules

 794            * @param i

 795            * @param options

 796            * @param originalValidationMethod

 797            * @return {*}

 798            * @private

 799            */
 800           _getErrorMessage:function (form, field, rule, rules, i, options, originalValidationMethod) {
 801               // If we are using the custon validation type, build the index for the rule.

 802               // Otherwise if we are doing a function call, make the call and return the object

 803               // that is passed back.

 804                var rule_index = jQuery.inArray(rule, rules);
 805               if (rule === "custom" || rule === "funcCall") {
 806                   var custom_validation_type = rules[rule_index + 1];
 807                   rule = rule + "[" + custom_validation_type + "]";
 808                   // Delete the rule from the rules array so that it doesn't try to call the

 809                  // same rule over again

 810                  delete(rules[rule_index]);
 811               }
 812               // Change the rule to the composite rule, if it was different from the original

 813               var alteredRule = rule;
 814  
 815  
 816               var element_classes = (field.attr("data-validation-engine")) ? field.attr("data-validation-engine") : field.attr("class");
 817               var element_classes_array = element_classes.split(" ");
 818  
 819               // Call the original validation method. If we are dealing with dates or checkboxes, also pass the form

 820               var errorMsg;
 821               if (rule == "future" || rule == "past"  || rule == "maxCheckbox" || rule == "minCheckbox") {
 822                   errorMsg = originalValidationMethod(form, field, rules, i, options);
 823               } else {
 824                   errorMsg = originalValidationMethod(field, rules, i, options);
 825               }
 826  
 827               // If the original validation method returned an error and we have a custom error message,

 828               // return the custom message instead. Otherwise return the original error message.

 829               if (errorMsg != undefined) {
 830                   var custom_message = methods._getCustomErrorMessage($(field), element_classes_array, alteredRule, options);
 831                   if (custom_message) errorMsg = custom_message;
 832               }
 833               return errorMsg;
 834  
 835           },
 836           _getCustomErrorMessage:function (field, classes, rule, options) {
 837              var custom_message = false;
 838              var validityProp = methods._validityProp[rule];
 839               // If there is a validityProp for this rule, check to see if the field has an attribute for it

 840              if (validityProp != undefined) {
 841                  custom_message = field.attr("data-errormessage-"+validityProp);
 842                  // If there was an error message for it, return the message

 843                  if (custom_message != undefined) 
 844                      return custom_message;
 845              }
 846              custom_message = field.attr("data-errormessage");
 847               // If there is an inline custom error message, return it

 848              if (custom_message != undefined) 
 849                  return custom_message;
 850              var id = '#' + field.attr("id");
 851              // If we have custom messages for the element's id, get the message for the rule from the id.

 852              // Otherwise, if we have custom messages for the element's classes, use the first class message we find instead.

 853              if (typeof options.custom_error_messages[id] != "undefined" &&
 854                  typeof options.custom_error_messages[id][rule] != "undefined" ) {
 855                            custom_message = options.custom_error_messages[id][rule]['message'];
 856              } else if (classes.length > 0) {
 857                  for (var i = 0; i < classes.length && classes.length > 0; i++) {
 858                       var element_class = "." + classes[i];
 859                      if (typeof options.custom_error_messages[element_class] != "undefined" &&
 860                          typeof options.custom_error_messages[element_class][rule] != "undefined") {
 861                              custom_message = options.custom_error_messages[element_class][rule]['message'];
 862                              break;
 863                      }
 864                  }
 865              }
 866              if (!custom_message &&
 867                  typeof options.custom_error_messages[rule] != "undefined" &&
 868                  typeof options.custom_error_messages[rule]['message'] != "undefined"){
 869                       custom_message = options.custom_error_messages[rule]['message'];
 870               }
 871               return custom_message;
 872           },
 873           _validityProp: {
 874               "required": "value-missing",
 875               "custom": "custom-error",
 876               "groupRequired": "value-missing",
 877               "ajax": "custom-error",
 878               "minSize": "range-underflow",
 879               "maxSize": "range-overflow",
 880               "min": "range-underflow",
 881               "max": "range-overflow",
 882               "past": "type-mismatch",
 883               "future": "type-mismatch",
 884               "dateRange": "type-mismatch",
 885               "dateTimeRange": "type-mismatch",
 886               "maxCheckbox": "range-overflow",
 887               "minCheckbox": "range-underflow",
 888               "equals": "pattern-mismatch",
 889               "funcCall": "custom-error",
 890               "creditCard": "pattern-mismatch",
 891               "condRequired": "value-missing"
 892           },
 893          /**

 894          * Required validation

 895          *

 896          * @param {jqObject} field

 897          * @param {Array[String]} rules

 898          * @param {int} i rules index

 899          * @param {Map}

 900          *            user options

 901          * @param {bool} condRequired flag when method is used for internal purpose in condRequired check

 902          * @return an error string if validation failed

 903          */
 904          _required: function(field, rules, i, options, condRequired) {
 905              switch (field.prop("type")) {
 906                  case "text":
 907                  case "password":
 908                  case "textarea":
 909                  case "file":
 910                  case "select-one":
 911                  case "select-multiple":
 912                  default:
 913                      var field_val      = $.trim( field.val()                               );
 914                      var dv_placeholder = $.trim( field.attr("data-validation-placeholder") );
 915                      var placeholder    = $.trim( field.attr("placeholder")                 );
 916                      if (
 917                             ( !field_val                                    )
 918                          || ( dv_placeholder && field_val == dv_placeholder )
 919                          || ( placeholder    && field_val == placeholder    )
 920                      ) {
 921                          return options.allrules[rules[i]].alertText;
 922                      }
 923                      break;
 924                  case "radio":
 925                  case "checkbox":
 926                      // new validation style to only check dependent field

 927                      if (condRequired) {
 928                          if (!field.attr('checked')) {
 929                              return options.allrules[rules[i]].alertTextCheckboxMultiple;
 930                          }
 931                          break;
 932                      }
 933                      // old validation style

 934                      var form = field.closest("form, .validationEngineContainer");
 935                      var name = field.attr("name");
 936                      if (form.find("input[name='" + name + "']:checked").size() == 0) {
 937                          if (form.find("input[name='" + name + "']:visible").size() == 1)
 938                              return options.allrules[rules[i]].alertTextCheckboxe;
 939                          else
 940                              return options.allrules[rules[i]].alertTextCheckboxMultiple;
 941                      }
 942                      break;
 943              }
 944          },
 945          /**

 946          * Validate that 1 from the group field is required

 947          *

 948          * @param {jqObject} field

 949          * @param {Array[String]} rules

 950          * @param {int} i rules index

 951          * @param {Map}

 952          *            user options

 953          * @return an error string if validation failed

 954          */
 955          _groupRequired: function(field, rules, i, options) {
 956              var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
 957              var isValid = false;
 958              // Check all fields from the group

 959              field.closest("form, .validationEngineContainer").find(classGroup).each(function(){
 960                  if(!methods._required($(this), rules, i, options)){
 961                      isValid = true;
 962                      return false;
 963                  }
 964              }); 
 965  
 966              if(!isValid) {
 967            return options.allrules[rules[i]].alertText;
 968          }
 969          },
 970          /**

 971          * Validate rules

 972          *

 973          * @param {jqObject} field

 974          * @param {Array[String]} rules

 975          * @param {int} i rules index

 976          * @param {Map}

 977          *            user options

 978          * @return an error string if validation failed

 979          */
 980          _custom: function(field, rules, i, options) {
 981              var customRule = rules[i + 1];
 982              var rule = options.allrules[customRule];
 983              var fn;
 984              if(!rule) {
 985                  alert("jqv:custom rule not found - "+customRule);
 986                  return;
 987              }
 988              
 989              if(rule["regex"]) {
 990                   var ex=rule.regex;
 991                      if(!ex) {
 992                          alert("jqv:custom regex not found - "+customRule);
 993                          return;
 994                      }
 995                      var pattern = new RegExp(ex);
 996  
 997                      if (!pattern.test(field.val())) return options.allrules[customRule].alertText;
 998                      
 999              } else if(rule["func"]) {
1000                  fn = rule["func"]; 
1001                   
1002                  if (typeof(fn) !== "function") {
1003                      alert("jqv:custom parameter 'function' is no function - "+customRule);
1004                          return;
1005                  }
1006                   
1007                  if (!fn(field, rules, i, options))
1008                      return options.allrules[customRule].alertText;
1009              } else {
1010                  alert("jqv:custom type not allowed "+customRule);
1011                      return;
1012              }
1013          },
1014          /**

1015          * Validate custom function outside of the engine scope

1016          *

1017          * @param {jqObject} field

1018          * @param {Array[String]} rules

1019          * @param {int} i rules index

1020          * @param {Map}

1021          *            user options

1022          * @return an error string if validation failed

1023          */
1024          _funcCall: function(field, rules, i, options) {
1025              var functionName = rules[i + 1];
1026              var fn;
1027              if(functionName.indexOf('.') >-1)
1028              {
1029                  var namespaces = functionName.split('.');
1030                  var scope = window;
1031                  while(namespaces.length)
1032                  {
1033                      scope = scope[namespaces.shift()];
1034                  }
1035                  fn = scope;
1036              }
1037              else
1038                  fn = window[functionName] || options.customFunctions[functionName];
1039              if (typeof(fn) == 'function')
1040                  return fn(field, rules, i, options);
1041  
1042          },
1043          /**

1044          * Field match

1045          *

1046          * @param {jqObject} field

1047          * @param {Array[String]} rules

1048          * @param {int} i rules index

1049          * @param {Map}

1050          *            user options

1051          * @return an error string if validation failed

1052          */
1053          _equals: function(field, rules, i, options) {
1054              var equalsField = rules[i + 1];
1055  
1056              if (field.val() != $("#" + equalsField).val())
1057                  return options.allrules.equals.alertText;
1058          },
1059          /**

1060          * Check the maximum size (in characters)

1061          *

1062          * @param {jqObject} field

1063          * @param {Array[String]} rules

1064          * @param {int} i rules index

1065          * @param {Map}

1066          *            user options

1067          * @return an error string if validation failed

1068          */
1069          _maxSize: function(field, rules, i, options) {
1070              var max = rules[i + 1];
1071              var len = field.val().length;
1072  
1073              if (len > max) {
1074                  var rule = options.allrules.maxSize;
1075                  return rule.alertText + max + rule.alertText2;
1076              }
1077          },
1078          /**

1079          * Check the minimum size (in characters)

1080          *

1081          * @param {jqObject} field

1082          * @param {Array[String]} rules

1083          * @param {int} i rules index

1084          * @param {Map}

1085          *            user options

1086          * @return an error string if validation failed

1087          */
1088          _minSize: function(field, rules, i, options) {
1089              var min = rules[i + 1];
1090              var len = field.val().length;
1091  
1092              if (len < min) {
1093                  var rule = options.allrules.minSize;
1094                  return rule.alertText + min + rule.alertText2;
1095              }
1096          },
1097          /**

1098          * Check number minimum value

1099          *

1100          * @param {jqObject} field

1101          * @param {Array[String]} rules

1102          * @param {int} i rules index

1103          * @param {Map}

1104          *            user options

1105          * @return an error string if validation failed

1106          */
1107          _min: function(field, rules, i, options) {
1108              var min = parseFloat(rules[i + 1]);
1109              var len = parseFloat(field.val());
1110  
1111              if (len < min) {
1112                  var rule = options.allrules.min;
1113                  if (rule.alertText2) return rule.alertText + min + rule.alertText2;
1114                  return rule.alertText + min;
1115              }
1116          },
1117          /**

1118          * Check number maximum value

1119          *

1120          * @param {jqObject} field

1121          * @param {Array[String]} rules

1122          * @param {int} i rules index

1123          * @param {Map}

1124          *            user options

1125          * @return an error string if validation failed

1126          */
1127          _max: function(field, rules, i, options) {
1128              var max = parseFloat(rules[i + 1]);
1129              var len = parseFloat(field.val());
1130  
1131              if (len >max ) {
1132                  var rule = options.allrules.max;
1133                  if (rule.alertText2) return rule.alertText + max + rule.alertText2;
1134                  //orefalo: to review, also do the translations

1135                  return rule.alertText + max;
1136              }
1137          },
1138          /**

1139          * Checks date is in the past

1140          *

1141          * @param {jqObject} field

1142          * @param {Array[String]} rules

1143          * @param {int} i rules index

1144          * @param {Map}

1145          *            user options

1146          * @return an error string if validation failed

1147          */
1148          _past: function(form, field, rules, i, options) {
1149  
1150              var p=rules[i + 1];
1151              var fieldAlt = $(form.find("input[name='" + p.replace(/^#+/, '') + "']"));
1152              var pdate;
1153  
1154              if (p.toLowerCase() == "now") {
1155                  pdate = new Date();
1156              } else if (undefined != fieldAlt.val()) {
1157                  if (fieldAlt.is(":disabled"))
1158                      return;
1159                  pdate = methods._parseDate(fieldAlt.val());
1160              } else {
1161                  pdate = methods._parseDate(p);
1162              }
1163              var vdate = methods._parseDate(field.val());
1164  
1165              if (vdate > pdate ) {
1166                  var rule = options.allrules.past;
1167                  if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1168                  return rule.alertText + methods._dateToString(pdate);
1169              }
1170          },
1171          /**

1172          * Checks date is in the future

1173          *

1174          * @param {jqObject} field

1175          * @param {Array[String]} rules

1176          * @param {int} i rules index

1177          * @param {Map}

1178          *            user options

1179          * @return an error string if validation failed

1180          */
1181          _future: function(form, field, rules, i, options) {
1182  
1183              var p=rules[i + 1];
1184              var fieldAlt = $(form.find("input[name='" + p.replace(/^#+/, '') + "']"));
1185              var pdate;
1186  
1187              if (p.toLowerCase() == "now") {
1188                  pdate = new Date();
1189              } else if (undefined != fieldAlt.val()) {
1190                  if (fieldAlt.is(":disabled"))
1191                      return;
1192                  pdate = methods._parseDate(fieldAlt.val());
1193              } else {
1194                  pdate = methods._parseDate(p);
1195              }
1196              var vdate = methods._parseDate(field.val());
1197  
1198              if (vdate < pdate ) {
1199                  var rule = options.allrules.future;
1200                  if (rule.alertText2)
1201                      return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1202                  return rule.alertText + methods._dateToString(pdate);
1203              }
1204          },
1205          /**

1206          * Checks if valid date

1207          *

1208          * @param {string} date string

1209          * @return a bool based on determination of valid date

1210          */
1211          _isDate: function (value) {
1212              var dateRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/);
1213              return dateRegEx.test(value);
1214          },
1215          /**

1216          * Checks if valid date time

1217          *

1218          * @param {string} date string

1219          * @return a bool based on determination of valid date time

1220          */
1221          _isDateTime: function (value){
1222              var dateTimeRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/);
1223              return dateTimeRegEx.test(value);
1224          },
1225          //Checks if the start date is before the end date

1226          //returns true if end is later than start

1227          _dateCompare: function (start, end) {
1228              return (new Date(start.toString()) < new Date(end.toString()));
1229          },
1230          /**

1231          * Checks date range

1232          *

1233          * @param {jqObject} first field name

1234          * @param {jqObject} second field name

1235          * @return an error string if validation failed

1236          */
1237          _dateRange: function (field, rules, i, options) {
1238              //are not both populated

1239              if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1240                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1241              }
1242  
1243              //are not both dates

1244              if (!methods._isDate(options.firstOfGroup[0].value) || !methods._isDate(options.secondOfGroup[0].value)) {
1245                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1246              }
1247  
1248              //are both dates but range is off

1249              if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1250                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1251              }
1252          },
1253          /**

1254          * Checks date time range

1255          *

1256          * @param {jqObject} first field name

1257          * @param {jqObject} second field name

1258          * @return an error string if validation failed

1259          */
1260          _dateTimeRange: function (field, rules, i, options) {
1261              //are not both populated

1262              if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1263                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1264              }
1265              //are not both dates

1266              if (!methods._isDateTime(options.firstOfGroup[0].value) || !methods._isDateTime(options.secondOfGroup[0].value)) {
1267                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1268              }
1269              //are both dates but range is off

1270              if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1271                  return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1272              }
1273          },
1274          /**

1275          * Max number of checkbox selected

1276          *

1277          * @param {jqObject} field

1278          * @param {Array[String]} rules

1279          * @param {int} i rules index

1280          * @param {Map}

1281          *            user options

1282          * @return an error string if validation failed

1283          */
1284          _maxCheckbox: function(form, field, rules, i, options) {
1285  
1286              var nbCheck = rules[i + 1];
1287              var groupname = field.attr("name");
1288              var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1289              if (groupSize > nbCheck) {
1290                  options.showArrow = false;
1291                  if (options.allrules.maxCheckbox.alertText2)
1292                       return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
1293                  return options.allrules.maxCheckbox.alertText;
1294              }
1295          },
1296          /**

1297          * Min number of checkbox selected

1298          *

1299          * @param {jqObject} field

1300          * @param {Array[String]} rules

1301          * @param {int} i rules index

1302          * @param {Map}

1303          *            user options

1304          * @return an error string if validation failed

1305          */
1306          _minCheckbox: function(form, field, rules, i, options) {
1307  
1308              var nbCheck = rules[i + 1];
1309              var groupname = field.attr("name");
1310              var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1311              if (groupSize < nbCheck) {
1312                  options.showArrow = false;
1313                  return options.allrules.minCheckbox.alertText + " " + nbCheck + " " + options.allrules.minCheckbox.alertText2;
1314              }
1315          },
1316          /**

1317          * Checks that it is a valid credit card number according to the

1318          * Luhn checksum algorithm.

1319          *

1320          * @param {jqObject} field

1321          * @param {Array[String]} rules

1322          * @param {int} i rules index

1323          * @param {Map}

1324          *            user options

1325          * @return an error string if validation failed

1326          */
1327          _creditCard: function(field, rules, i, options) {
1328              //spaces and dashes may be valid characters, but must be stripped to calculate the checksum.

1329              var valid = false, cardNumber = field.val().replace(/ +/g, '').replace(/-+/g, '');
1330  
1331              var numDigits = cardNumber.length;
1332              if (numDigits >= 14 && numDigits <= 16 && parseInt(cardNumber) > 0) {
1333  
1334                  var sum = 0, i = numDigits - 1, pos = 1, digit, luhn = new String();
1335                  do {
1336                      digit = parseInt(cardNumber.charAt(i));
1337                      luhn += (pos++ % 2 == 0) ? digit * 2 : digit;
1338                  } while (--i >= 0)
1339  
1340                  for (i = 0; i < luhn.length; i++) {
1341                      sum += parseInt(luhn.charAt(i));
1342                  }
1343                  valid = sum % 10 == 0;
1344              }
1345              if (!valid) return options.allrules.creditCard.alertText;
1346          },
1347          /**

1348          * Ajax field validation

1349          *

1350          * @param {jqObject} field

1351          * @param {Array[String]} rules

1352          * @param {int} i rules index

1353          * @param {Map}

1354          *            user options

1355          * @return nothing! the ajax validator handles the prompts itself

1356          */
1357           _ajax: function(field, rules, i, options) {
1358  
1359               var errorSelector = rules[i + 1];
1360               var rule = options.allrules[errorSelector];
1361               var extraData = rule.extraData;
1362               var extraDataDynamic = rule.extraDataDynamic;
1363               var data = {
1364                  "fieldId" : field.attr("id"),
1365                  "fieldValue" : field.val()
1366               };
1367  
1368               if (typeof extraData === "object") {
1369                  $.extend(data, extraData);
1370               } else if (typeof extraData === "string") {
1371                  var tempData = extraData.split("&");
1372                  for(var i = 0; i < tempData.length; i++) {
1373                      var values = tempData[i].split("=");
1374                      if (values[0] && values[0]) {
1375                          data[values[0]] = values[1];
1376                      }
1377                  }
1378               }
1379  
1380               if (extraDataDynamic) {
1381                   var tmpData = [];
1382                   var domIds = String(extraDataDynamic).split(",");
1383                   for (var i = 0; i < domIds.length; i++) {
1384                       var id = domIds[i];
1385                       if ($(id).length) {
1386                           var inputValue = field.closest("form, .validationEngineContainer").find(id).val();
1387                           var keyValue = id.replace('#', '') + '=' + escape(inputValue);
1388                           data[id.replace('#', '')] = inputValue;
1389                       }
1390                   }
1391               }
1392               
1393               // If a field change event triggered this we want to clear the cache for this ID

1394               if (options.eventTrigger == "field") {
1395                  delete(options.ajaxValidCache[field.attr("id")]);
1396               }
1397  
1398               // If there is an error or if the the field is already validated, do not re-execute AJAX

1399               if (!options.isError && !methods._checkAjaxFieldStatus(field.attr("id"), options)) {
1400                   $.ajax({
1401                       type: options.ajaxFormValidationMethod,
1402                       url: rule.url,
1403                       cache: false,
1404                       dataType: "json",
1405                       data: data,
1406                       field: field,
1407                       rule: rule,
1408                       methods: methods,
1409                       options: options,
1410                       beforeSend: function() {},
1411                       error: function(data, transport) {
1412                           methods._ajaxError(data, transport);
1413                       },
1414                       success: function(json) {
1415  
1416                           // asynchronously called on success, data is the json answer from the server

1417                           var errorFieldId = json[0];
1418                           //var errorField = $($("#" + errorFieldId)[0]);

1419                           var errorField = $("#"+ errorFieldId).eq(0);
1420  
1421                           // make sure we found the element

1422                           if (errorField.length == 1) {
1423                               var status = json[1];
1424                               // read the optional msg from the server

1425                               var msg = json[2];
1426                               if (!status) {
1427                                   // Houston we got a problem - display an red prompt

1428                                   options.ajaxValidCache[errorFieldId] = false;
1429                                   options.isError = true;
1430  
1431                                   // resolve the msg prompt

1432                                   if(msg) {
1433                                       if (options.allrules[msg]) {
1434                                           var txt = options.allrules[msg].alertText;
1435                                           if (txt) {
1436                                              msg = txt;
1437                              }
1438                                       }
1439                                   }
1440                                   else
1441                                      msg = rule.alertText;
1442  
1443                                   if (options.showPrompts) methods._showPrompt(errorField, msg, "", true, options);
1444                               } else {
1445                                   options.ajaxValidCache[errorFieldId] = true;
1446  
1447                                   // resolves the msg prompt

1448                                   if(msg) {
1449                                       if (options.allrules[msg]) {
1450                                           var txt = options.allrules[msg].alertTextOk;
1451                                           if (txt) {
1452                                              msg = txt;
1453                              }
1454                                       }
1455                                   }
1456                                   else
1457                                   msg = rule.alertTextOk;
1458  
1459                                   if (options.showPrompts) {
1460                                       // see if we should display a green prompt

1461                                       if (msg)
1462                                          methods._showPrompt(errorField, msg, "pass", true, options);
1463                                       else
1464                                          methods._closePrompt(errorField);
1465                                  }
1466                                  
1467                                   // If a submit form triggered this, we want to re-submit the form

1468                                   if (options.eventTrigger == "submit")
1469                                      field.closest("form").submit();
1470                               }
1471                           }
1472                           errorField.trigger("jqv.field.result", [errorField, options.isError, msg]);
1473                       }
1474                   });
1475                   
1476                   return rule.alertTextLoad;
1477               }
1478           },
1479          /**

1480          * Common method to handle ajax errors

1481          *

1482          * @param {Object} data

1483          * @param {Object} transport

1484          */
1485          _ajaxError: function(data, transport) {
1486              if(data.status == 0 && transport == null)
1487                  alert("The page is not served from a server! ajax call failed");
1488              else if(typeof console != "undefined")
1489                  console.log("Ajax error: " + data.status + " " + transport);
1490          },
1491          /**

1492          * date -> string

1493          *

1494          * @param {Object} date

1495          */
1496          _dateToString: function(date) {
1497              return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
1498          },
1499          /**

1500          * Parses an ISO date

1501          * @param {String} d

1502          */
1503          _parseDate: function(d) {
1504  
1505              var dateParts = d.split("-");
1506              if(dateParts==d)
1507                  dateParts = d.split("/");
1508              return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
1509          },
1510          /**

1511          * Builds or updates a prompt with the given information

1512          *

1513          * @param {jqObject} field

1514          * @param {String} promptText html text to display type

1515          * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)

1516          * @param {boolean} ajaxed - use to mark fields than being validated with ajax

1517          * @param {Map} options user options

1518          */
1519           _showPrompt: function(field, promptText, type, ajaxed, options, ajaxform) {
1520               var prompt = methods._getPrompt(field);
1521               // The ajax submit errors are not see has an error in the form,

1522               // When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time

1523               // Because no error was found befor submitting

1524               if(ajaxform) prompt = false;
1525               // Check that there is indded text

1526               if($.trim(promptText)){ 
1527                   if (prompt)
1528                      methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
1529                   else
1530                      methods._buildPrompt(field, promptText, type, ajaxed, options);
1531              }
1532           },
1533          /**

1534          * Builds and shades a prompt for the given field.

1535          *

1536          * @param {jqObject} field

1537          * @param {String} promptText html text to display type

1538          * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)

1539          * @param {boolean} ajaxed - use to mark fields than being validated with ajax

1540          * @param {Map} options user options

1541          */
1542          _buildPrompt: function(field, promptText, type, ajaxed, options) {
1543  
1544              // create the prompt

1545              var prompt = $('<div>');
1546              prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
1547              // add a class name to identify the parent form of the prompt

1548              prompt.addClass("parentForm"+methods._getClassName(field.closest('form, .validationEngineContainer').attr("id")));
1549              prompt.addClass("formError");
1550  
1551              switch (type) {
1552                  case "pass":
1553                      prompt.addClass("greenPopup");
1554                      break;
1555                  case "load":
1556                      prompt.addClass("blackPopup");
1557                      break;
1558                  default:
1559                      /* it has error  */

1560                      //alert("unknown popup type:"+type);

1561              }
1562              if (ajaxed)
1563                  prompt.addClass("ajaxed");
1564  
1565              // create the prompt content

1566              var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
1567  
1568              // determine position type

1569              var positionType=field.data("promptPosition") || options.promptPosition;
1570  
1571              // create the css arrow pointing at the field

1572              // note that there is no triangle on max-checkbox and radio

1573              if (options.showArrow) {
1574                  var arrow = $('<div>').addClass("formErrorArrow");
1575  
1576                  //prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)

1577                  if (typeof(positionType)=='string') 
1578                  {
1579                      var pos=positionType.indexOf(":");
1580                      if(pos!=-1)
1581                          positionType=positionType.substring(0,pos);
1582                  }
1583  
1584                  switch (positionType) {
1585                      case "bottomLeft":
1586                      case "bottomRight":
1587                          prompt.find(".formErrorContent").before(arrow);
1588                          arrow.addClass("formErrorArrowBottom").html('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
1589                          break;
1590                      case "topLeft":
1591                      case "topRight":
1592                          arrow.html('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');
1593                          prompt.append(arrow);
1594                          break;
1595                  }
1596              }
1597              // Add custom prompt class

1598              if (options.addPromptClass)
1599                  prompt.addClass(options.addPromptClass);
1600  
1601              prompt.css({
1602                  "opacity": 0
1603              });
1604              if(positionType === 'inline') {
1605                  prompt.addClass("inline");
1606                  if(typeof field.attr('data-prompt-target') !== 'undefined' && $('#'+field.attr('data-prompt-target')).length > 0) {
1607                      prompt.appendTo($('#'+field.attr('data-prompt-target')));
1608                  } else {
1609                      field.after(prompt);
1610                  }
1611              } else {
1612                  field.before(prompt);                
1613              }
1614              
1615              var pos = methods._calculatePosition(field, prompt, options);
1616              prompt.css({
1617                  'position': positionType === 'inline' ? 'relative' : 'absolute',
1618                  "top": pos.callerTopPosition,
1619                  "left": pos.callerleftPosition,
1620                  "marginTop": pos.marginTopSize,
1621                  "opacity": 0
1622              }).data("callerField", field);
1623              
1624  
1625              if (options.autoHidePrompt) {
1626                  setTimeout(function(){
1627                      prompt.animate({
1628                          "opacity": 0
1629                      },function(){
1630                          prompt.closest('.formErrorOuter').remove();
1631                          prompt.remove();
1632                      });
1633                  }, options.autoHideDelay);
1634              } 
1635              return prompt.animate({
1636                  "opacity": 0.87
1637              });
1638          },
1639          /**

1640          * Updates the prompt text field - the field for which the prompt

1641          * @param {jqObject} field

1642          * @param {String} promptText html text to display type

1643          * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)

1644          * @param {boolean} ajaxed - use to mark fields than being validated with ajax

1645          * @param {Map} options user options

1646          */
1647          _updatePrompt: function(field, prompt, promptText, type, ajaxed, options, noAnimation) {
1648  
1649              if (prompt) {
1650                  if (typeof type !== "undefined") {
1651                      if (type == "pass")
1652                          prompt.addClass("greenPopup");
1653                      else
1654                          prompt.removeClass("greenPopup");
1655  
1656                      if (type == "load")
1657                          prompt.addClass("blackPopup");
1658                      else
1659                          prompt.removeClass("blackPopup");
1660                  }
1661                  if (ajaxed)
1662                      prompt.addClass("ajaxed");
1663                  else
1664                      prompt.removeClass("ajaxed");
1665  
1666                  prompt.find(".formErrorContent").html(promptText);
1667  
1668                  var pos = methods._calculatePosition(field, prompt, options);
1669                  var css = {"top": pos.callerTopPosition,
1670                  "left": pos.callerleftPosition,
1671                  "marginTop": pos.marginTopSize};
1672  
1673                  if (noAnimation)
1674                      prompt.css(css);
1675                  else
1676                      prompt.animate(css);
1677              }
1678          },
1679          /**

1680          * Closes the prompt associated with the given field

1681          *

1682          * @param {jqObject}

1683          *            field

1684          */
1685           _closePrompt: function(field) {
1686               var prompt = methods._getPrompt(field);
1687               if (prompt)
1688                   prompt.fadeTo("fast", 0, function() {
1689                       prompt.parent('.formErrorOuter').remove();
1690                       prompt.remove();
1691                   });
1692           },
1693           closePrompt: function(field) {
1694               return methods._closePrompt(field);
1695           },
1696          /**

1697          * Returns the error prompt matching the field if any

1698          *

1699          * @param {jqObject}

1700          *            field

1701          * @return undefined or the error prompt (jqObject)

1702          */
1703          _getPrompt: function(field) {
1704                  var formId = $(field).closest('form, .validationEngineContainer').attr('id');
1705              var className = methods._getClassName(field.attr("id")) + "formError";
1706                  var match = $("." + methods._escapeExpression(className) + '.parentForm' + formId)[0];
1707              if (match)
1708              return $(match);
1709          },
1710          /**

1711            * Returns the escapade classname

1712            *

1713            * @param {selector}

1714            *            className

1715            */
1716            _escapeExpression: function (selector) {
1717                return selector.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "\\$1");
1718            },
1719          /**

1720           * returns true if we are in a RTLed document

1721           *

1722           * @param {jqObject} field

1723           */
1724          isRTL: function(field)
1725          {
1726              var $document = $(document);
1727              var $body = $('body');
1728              var rtl =
1729                  (field && field.hasClass('rtl')) ||
1730                  (field && (field.attr('dir') || '').toLowerCase()==='rtl') ||
1731                  $document.hasClass('rtl') ||
1732                  ($document.attr('dir') || '').toLowerCase()==='rtl' ||
1733                  $body.hasClass('rtl') ||
1734                  ($body.attr('dir') || '').toLowerCase()==='rtl';
1735              return Boolean(rtl);
1736          },
1737          /**

1738          * Calculates prompt position

1739          *

1740          * @param {jqObject}

1741          *            field

1742          * @param {jqObject}

1743          *            the prompt

1744          * @param {Map}

1745          *            options

1746          * @return positions

1747          */
1748          _calculatePosition: function (field, promptElmt, options) {
1749  
1750              var promptTopPosition, promptleftPosition, marginTopSize;
1751              var fieldWidth     = field.width();
1752              var fieldLeft     = field.position().left;
1753              var fieldTop     =  field.position().top;
1754              var fieldHeight     =  field.height();    
1755              var promptHeight = promptElmt.height();
1756  
1757  
1758              // is the form contained in an overflown container?

1759              promptTopPosition = promptleftPosition = 0;
1760              // compensation for the arrow

1761              marginTopSize = -promptHeight;
1762          
1763  
1764              //prompt positioning adjustment support

1765              //now you can adjust prompt position

1766              //usage: positionType:Xshift,Yshift

1767              //for example:

1768              //   bottomLeft:+20 means bottomLeft position shifted by 20 pixels right horizontally

1769              //   topRight:20, -15 means topRight position shifted by 20 pixels to right and 15 pixels to top

1770              //You can use +pixels, - pixels. If no sign is provided than + is default.

1771              var positionType=field.data("promptPosition") || options.promptPosition;
1772              var shift1="";
1773              var shift2="";
1774              var shiftX=0;
1775              var shiftY=0;
1776              if (typeof(positionType)=='string') {
1777                  //do we have any position adjustments ?

1778                  if (positionType.indexOf(":")!=-1) {
1779                      shift1=positionType.substring(positionType.indexOf(":")+1);
1780                      positionType=positionType.substring(0,positionType.indexOf(":"));
1781  
1782                      //if any advanced positioning will be needed (percents or something else) - parser should be added here

1783                      //for now we use simple parseInt()

1784  
1785                      //do we have second parameter?

1786                      if (shift1.indexOf(",") !=-1) {
1787                          shift2=shift1.substring(shift1.indexOf(",") +1);
1788                          shift1=shift1.substring(0,shift1.indexOf(","));
1789                          shiftY=parseInt(shift2);
1790                          if (isNaN(shiftY)) shiftY=0;
1791                      };
1792  
1793                      shiftX=parseInt(shift1);
1794                      if (isNaN(shift1)) shift1=0;
1795  
1796                  };
1797              };
1798  
1799              
1800              switch (positionType) {
1801                  default:
1802                  case "topRight":
1803                      promptleftPosition +=  fieldLeft + fieldWidth - 30;
1804                      promptTopPosition +=  fieldTop;
1805                      break;
1806  
1807                  case "topLeft":
1808                      promptTopPosition +=  fieldTop;
1809                      promptleftPosition += fieldLeft; 
1810                      break;
1811  
1812                  case "centerRight":
1813                      promptTopPosition = fieldTop+4;
1814                      marginTopSize = 0;
1815                      promptleftPosition= fieldLeft + field.outerWidth(true)+5;
1816                      break;
1817                  case "centerLeft":
1818                      promptleftPosition = fieldLeft - (promptElmt.width() + 2);
1819                      promptTopPosition = fieldTop+4;
1820                      marginTopSize = 0;
1821                      
1822                      break;
1823  
1824                  case "bottomLeft":
1825                      promptTopPosition = fieldTop + field.height() + 5;
1826                      marginTopSize = 0;
1827                      promptleftPosition = fieldLeft;
1828                      break;
1829                  case "bottomRight":
1830                      promptleftPosition = fieldLeft + fieldWidth - 30;
1831                      promptTopPosition =  fieldTop +  field.height() + 5;
1832                      marginTopSize = 0;
1833                      break;
1834                  case "inline":
1835                      promptleftPosition = 0;
1836                      promptTopPosition = 0;
1837                      marginTopSize = 0;
1838              };
1839  
1840          
1841  
1842              //apply adjusments if any

1843              promptleftPosition += shiftX;
1844              promptTopPosition  += shiftY;
1845  
1846              return {
1847                  "callerTopPosition": promptTopPosition + "px",
1848                  "callerleftPosition": promptleftPosition + "px",
1849                  "marginTopSize": marginTopSize + "px"
1850              };
1851          },
1852          /**

1853          * Saves the user options and variables in the form.data

1854          *

1855          * @param {jqObject}

1856          *            form - the form where the user option should be saved

1857          * @param {Map}

1858          *            options - the user options

1859          * @return the user options (extended from the defaults)

1860          */
1861           _saveOptions: function(form, options) {
1862  
1863               // is there a language localisation ?

1864               if ($.validationEngineLanguage)
1865               var allRules = $.validationEngineLanguage.allRules;
1866               else
1867               $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
1868               // --- Internals DO NOT TOUCH or OVERLOAD ---

1869               // validation rules and i18

1870               $.validationEngine.defaults.allrules = allRules;
1871  
1872               var userOptions = $.extend(true,{},$.validationEngine.defaults,options);
1873  
1874               form.data('jqv', userOptions);
1875               return userOptions;
1876           },
1877  
1878           /**

1879           * Removes forbidden characters from class name

1880           * @param {String} className

1881           */
1882           _getClassName: function(className) {
1883               if(className)
1884                   return className.replace(/:/g, "_").replace(/\./g, "_");
1885                        },
1886          /**

1887           * Escape special character for jQuery selector

1888           * http://totaldev.com/content/escaping-characters-get-valid-jquery-id

1889           * @param {String} selector

1890           */
1891           _jqSelector: function(str){
1892              return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
1893          },
1894          /**

1895          * Conditionally required field

1896          *

1897          * @param {jqObject} field

1898          * @param {Array[String]} rules

1899          * @param {int} i rules index

1900          * @param {Map}

1901          * user options

1902          * @return an error string if validation failed

1903          */
1904          _condRequired: function(field, rules, i, options) {
1905              var idx, dependingField;
1906  
1907              for(idx = (i + 1); idx < rules.length; idx++) {
1908                  dependingField = jQuery("#" + rules[idx]).first();
1909  
1910                  /* Use _required for determining wether dependingField has a value.

1911                   * There is logic there for handling all field types, and default value; so we won't replicate that here

1912                   * Indicate this special use by setting the last parameter to true so we only validate the dependingField on chackboxes and radio buttons (#462)

1913                   */
1914                  if (dependingField.length && methods._required(dependingField, ["required"], 0, options, true) == undefined) {
1915                      /* We now know any of the depending fields has a value,

1916                       * so we can validate this field as per normal required code

1917                       */
1918                      return methods._required(field, ["required"], 0, options);
1919                  }
1920              }
1921          },
1922  
1923          _submitButtonClick: function(event) {
1924              var button = $(this);
1925              var form = button.closest('form, .validationEngineContainer');
1926              form.data("jqv_submitButton", button.attr("id"));
1927          }
1928            };
1929  
1930       /**

1931       * Plugin entry point.

1932       * You may pass an action as a parameter or a list of options.

1933       * if none, the init and attach methods are being called.

1934       * Remember: if you pass options, the attached method is NOT called automatically

1935       *

1936       * @param {String}

1937       *            method (optional) action

1938       */
1939       $.fn.validationEngine = function(method) {
1940  
1941           var form = $(this);
1942           if(!form[0]) return form;  // stop here if the form does not exist

1943  
1944           if (typeof(method) == 'string' && method.charAt(0) != '_' && methods[method]) {
1945  
1946               // make sure init is called once

1947               if(method != "showPrompt" && method != "hide" && method != "hideAll")
1948               methods.init.apply(form);
1949  
1950               return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
1951           } else if (typeof method == 'object' || !method) {
1952  
1953               // default constructor with or without arguments

1954               methods.init.apply(form, arguments);
1955               return methods.attach.apply(form);
1956           } else {
1957               $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
1958           }
1959      };
1960  
1961  
1962  
1963      // LEAK GLOBAL OPTIONS

1964      $.validationEngine= {fieldIdCounter: 0,defaults:{
1965  
1966          // Name of the event triggering field validation

1967          validationEventTrigger: "blur",
1968          // Automatically scroll viewport to the first error

1969          scroll: true,
1970          // Focus on the first input

1971          focusFirstField:true,
1972          // Show prompts, set to false to disable prompts

1973          showPrompts: true,
1974         // Should we attempt to validate non-visible input fields contained in the form? (Useful in cases of tabbed containers, e.g. jQuery-UI tabs)

1975         validateNonVisibleFields: false,
1976          // Opening box position, possible locations are: topLeft,

1977          // topRight, bottomLeft, centerRight, bottomRight, inline

1978          // inline gets inserted after the validated field or into an element specified in data-prompt-target

1979          promptPosition: "topRight",
1980          bindMethod:"bind",
1981          // internal, automatically set to true when it parse a _ajax rule

1982          inlineAjax: false,
1983          // if set to true, the form data is sent asynchronously via ajax to the form.action url (get)

1984          ajaxFormValidation: false,
1985          // The url to send the submit ajax validation (default to action)

1986          ajaxFormValidationURL: false,
1987          // HTTP method used for ajax validation

1988          ajaxFormValidationMethod: 'get',
1989          // Ajax form validation callback method: boolean onComplete(form, status, errors, options)

1990          // retuns false if the form.submit event needs to be canceled.

1991          onAjaxFormComplete: $.noop,
1992          // called right before the ajax call, may return false to cancel

1993          onBeforeAjaxFormValidation: $.noop,
1994          // Stops form from submitting and execute function assiciated with it

1995          onValidationComplete: false,
1996  
1997          // Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages

1998          doNotShowAllErrosOnSubmit: false,
1999          // Object where you store custom messages to override the default error messages

2000          custom_error_messages:{},
2001          // true if you want to vind the input fields

2002          binded: true,
2003          // set to true, when the prompt arrow needs to be displayed

2004          showArrow: true,
2005          // did one of the validation fail ? kept global to stop further ajax validations

2006          isError: false,
2007          // Limit how many displayed errors a field can have

2008          maxErrorsPerField: false,
2009          
2010          // Caches field validation status, typically only bad status are created.

2011          // the array is used during ajax form validation to detect issues early and prevent an expensive submit

2012          ajaxValidCache: {},
2013          // Auto update prompt position after window resize

2014          autoPositionUpdate: false,
2015  
2016          InvalidFields: [],
2017          onFieldSuccess: false,
2018          onFieldFailure: false,
2019          onSuccess: false,
2020          onFailure: false,
2021          validateAttribute: "class",
2022          addSuccessCssClassToField: "",
2023          addFailureCssClassToField: "",
2024          
2025          // Auto-hide prompt

2026          autoHidePrompt: false,
2027          // Delay before auto-hide

2028          autoHideDelay: 10000,
2029          // Fade out duration while hiding the validations

2030          fadeDuration: 0.3,
2031       // Use Prettify select library

2032       prettySelect: false,
2033       // Add css class on prompt

2034       addPromptClass : "",
2035       // Custom ID uses prefix

2036       usePrefix: "",
2037       // Custom ID uses suffix

2038       useSuffix: "",
2039       // Only show one message per error prompt

2040       showOneMessage: false
2041      }};
2042      $(function(){$.validationEngine.defaults.promptPosition = methods.isRTL()?'topLeft':"topRight"});
2043  })(jQuery);
2044  
2045  


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1