github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/semantic/dist/components/form.js (about)

     1  /*!
     2   * # Semantic UI x.x - Form Validation
     3   * http://github.com/semantic-org/semantic-ui/
     4   *
     5   *
     6   * Copyright 2014 Contributors
     7   * Released under the MIT license
     8   * http://opensource.org/licenses/MIT
     9   *
    10   */
    11  
    12  ;(function ( $, window, document, undefined ) {
    13  
    14  "use strict";
    15  
    16  $.fn.form = function(fields, parameters) {
    17    var
    18      $allModules     = $(this),
    19  
    20      settings        = $.extend(true, {}, $.fn.form.settings, parameters),
    21      validation      = $.extend({}, $.fn.form.settings.defaults, fields),
    22  
    23      namespace       = settings.namespace,
    24      metadata        = settings.metadata,
    25      selector        = settings.selector,
    26      className       = settings.className,
    27      error           = settings.error,
    28  
    29      eventNamespace  = '.' + namespace,
    30      moduleNamespace = 'module-' + namespace,
    31  
    32      moduleSelector  = $allModules.selector || '',
    33  
    34      time            = new Date().getTime(),
    35      performance     = [],
    36  
    37      query           = arguments[0],
    38      methodInvoked   = (typeof query == 'string'),
    39      queryArguments  = [].slice.call(arguments, 1),
    40      returnedValue
    41    ;
    42    $allModules
    43      .each(function() {
    44        var
    45          $module     = $(this),
    46          $field      = $(this).find(selector.field),
    47          $group      = $(this).find(selector.group),
    48          $message    = $(this).find(selector.message),
    49          $prompt     = $(this).find(selector.prompt),
    50  
    51          $submit     = $(this).find(selector.submit),
    52          $clear      = $(this).find(selector.clear),
    53          $reset      = $(this).find(selector.reset),
    54  
    55          formErrors  = [],
    56          keyHeldDown = false,
    57  
    58          element     = this,
    59          instance    = $module.data(moduleNamespace),
    60          module
    61        ;
    62  
    63        module      = {
    64  
    65          initialize: function() {
    66            module.verbose('Initializing form validation', $module, validation, settings);
    67            module.bindEvents();
    68            module.set.defaults();
    69            module.instantiate();
    70          },
    71  
    72          instantiate: function() {
    73            module.verbose('Storing instance of module', module);
    74            instance = module;
    75            $module
    76              .data(moduleNamespace, module)
    77            ;
    78          },
    79  
    80          destroy: function() {
    81            module.verbose('Destroying previous module', instance);
    82            module.removeEvents();
    83            $module
    84              .removeData(moduleNamespace)
    85            ;
    86          },
    87  
    88          refresh: function() {
    89            module.verbose('Refreshing selector cache');
    90            $field = $module.find(selector.field);
    91          },
    92  
    93          submit: function() {
    94            module.verbose('Submitting form', $module);
    95            $module
    96              .submit()
    97            ;
    98          },
    99  
   100          attachEvents: function(selector, action) {
   101            action = action || 'submit';
   102            $(selector)
   103              .on('click', function(event) {
   104                module[action]();
   105                event.preventDefault();
   106              })
   107            ;
   108          },
   109  
   110          bindEvents: function() {
   111            if(settings.keyboardShortcuts) {
   112              $field
   113                .on('keydown' + eventNamespace, module.event.field.keydown)
   114              ;
   115            }
   116            $module
   117              .on('submit' + eventNamespace, module.validate.form)
   118            ;
   119            $field
   120              .on('blur' + eventNamespace, module.event.field.blur)
   121            ;
   122  
   123            // attach events to common elements
   124            module.attachEvents($submit, 'submit');
   125            module.attachEvents($reset, 'reset');
   126            module.attachEvents($clear, 'clear');
   127  
   128            $field
   129              .each(function() {
   130                var
   131                  type       = $(this).prop('type'),
   132                  inputEvent = module.get.changeEvent(type)
   133                ;
   134                $(this)
   135                  .on(inputEvent + eventNamespace, module.event.field.change)
   136                ;
   137              })
   138            ;
   139          },
   140  
   141          clear: function() {
   142            $field
   143              .each(function () {
   144                var
   145                  $field       = $(this),
   146                  $element     = $field.parent(),
   147                  $fieldGroup  = $field.closest($group),
   148                  $prompt      = $fieldGroup.find(selector.prompt),
   149                  defaultValue = $field.data(metadata.defaultValue) || '',
   150                  isCheckbox   = $element.is(selector.uiCheckbox),
   151                  isDropdown   = $element.is(selector.uiDropdown),
   152                  isErrored    = $fieldGroup.hasClass(className.error)
   153                ;
   154                if(isErrored) {
   155                  module.verbose('Resetting error on field', $fieldGroup);
   156                  $fieldGroup.removeClass(className.error);
   157                  $prompt.remove();
   158                }
   159                if(isDropdown) {
   160                  module.verbose('Resetting dropdown value', $element, defaultValue);
   161                  $element.dropdown('clear');
   162                }
   163                else if(isCheckbox) {
   164                  $element.checkbox('uncheck');
   165                }
   166                else {
   167                  module.verbose('Resetting field value', $field, defaultValue);
   168                  $field.val('');
   169                }
   170              })
   171            ;
   172          },
   173  
   174          reset: function() {
   175            $field
   176              .each(function () {
   177                var
   178                  $field       = $(this),
   179                  $element     = $field.parent(),
   180                  $fieldGroup  = $field.closest($group),
   181                  $prompt      = $fieldGroup.find(selector.prompt),
   182                  defaultValue = $field.data(metadata.defaultValue) || '',
   183                  isCheckbox   = $element.is(selector.uiCheckbox),
   184                  isDropdown   = $element.is(selector.uiDropdown),
   185                  isErrored    = $fieldGroup.hasClass(className.error)
   186                ;
   187                if(isErrored) {
   188                  module.verbose('Resetting error on field', $fieldGroup);
   189                  $fieldGroup.removeClass(className.error);
   190                  $prompt.remove();
   191                }
   192                if(isDropdown) {
   193                  module.verbose('Resetting dropdown value', $element, defaultValue);
   194                  $element.dropdown('restore defaults');
   195                }
   196                else if(isCheckbox) {
   197                  module.verbose('Resetting checkbox value', $element, defaultValue);
   198                  if(defaultValue === true) {
   199                    $element.checkbox('check');
   200                  }
   201                  else {
   202                    $element.checkbox('uncheck');
   203                  }
   204                }
   205                else {
   206                  module.verbose('Resetting field value', $field, defaultValue);
   207                  $field.val(defaultValue);
   208                }
   209              })
   210            ;
   211          },
   212  
   213          removeEvents: function() {
   214            $module
   215              .off(eventNamespace)
   216            ;
   217            $field
   218              .off(eventNamespace)
   219            ;
   220            $submit
   221              .off(eventNamespace)
   222            ;
   223            $field
   224              .off(eventNamespace)
   225            ;
   226          },
   227  
   228          event: {
   229            field: {
   230              keydown: function(event) {
   231                var
   232                  $field  = $(this),
   233                  key     = event.which,
   234                  keyCode = {
   235                    enter  : 13,
   236                    escape : 27
   237                  }
   238                ;
   239                if( key == keyCode.escape) {
   240                  module.verbose('Escape key pressed blurring field');
   241                  $field
   242                    .blur()
   243                  ;
   244                }
   245                if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
   246                  $submit
   247                    .addClass(className.pressed)
   248                  ;
   249                  if(!keyHeldDown) {
   250                    $field
   251                      .one('keyup' + eventNamespace, module.event.field.keyup)
   252                    ;
   253                    module.submit();
   254                    module.debug('Enter pressed on input submitting form');
   255                  }
   256                  keyHeldDown = true;
   257                }
   258              },
   259              keyup: function() {
   260                keyHeldDown = false;
   261                $submit.removeClass(className.pressed);
   262              },
   263              blur: function() {
   264                var
   265                  $field      = $(this),
   266                  $fieldGroup = $field.closest($group)
   267                ;
   268                if( $fieldGroup.hasClass(className.error) ) {
   269                  module.debug('Revalidating field', $field,  module.get.validation($field));
   270                  module.validate.field( module.get.validation($field) );
   271                }
   272                else if(settings.on == 'blur' || settings.on == 'change') {
   273                  module.validate.field( module.get.validation($field) );
   274                }
   275              },
   276              change: function() {
   277                var
   278                  $field      = $(this),
   279                  $fieldGroup = $field.closest($group)
   280                ;
   281                if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
   282                  clearTimeout(module.timer);
   283                  module.timer = setTimeout(function() {
   284                    module.debug('Revalidating field', $field,  module.get.validation($field));
   285                    module.validate.field( module.get.validation($field) );
   286                  }, settings.delay);
   287                }
   288              }
   289            }
   290  
   291          },
   292  
   293          get: {
   294            changeEvent: function(type) {
   295              if(type == 'checkbox' || type == 'radio' || type == 'hidden') {
   296                return 'change';
   297              }
   298              else {
   299                return module.get.inputEvent();
   300              }
   301            },
   302            inputEvent: function() {
   303              return (document.createElement('input').oninput !== undefined)
   304                ? 'input'
   305                : (document.createElement('input').onpropertychange !== undefined)
   306                  ? 'propertychange'
   307                  : 'keyup'
   308              ;
   309            },
   310            field: function(identifier) {
   311              module.verbose('Finding field with identifier', identifier);
   312              if( $field.filter('#' + identifier).length > 0 ) {
   313                return $field.filter('#' + identifier);
   314              }
   315              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
   316                return $field.filter('[name="' + identifier +'"]');
   317              }
   318              else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
   319                return $field.filter('[name="' + identifier +'[]"]');
   320              }
   321              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
   322                return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
   323              }
   324              return $('<input/>');
   325            },
   326            fields: function(fields) {
   327              var
   328                $fields = $()
   329              ;
   330              $.each(fields, function(index, name) {
   331                $fields = $fields.add( module.get.field(name) );
   332              });
   333              return $fields;
   334            },
   335            validation: function($field) {
   336              var
   337                rules
   338              ;
   339              $.each(validation, function(fieldName, field) {
   340                if( module.get.field(field.identifier).get(0) == $field.get(0) ) {
   341                  rules = field;
   342                }
   343              });
   344              return rules || false;
   345            },
   346            value: function (field) {
   347              var
   348                fields = [],
   349                results
   350              ;
   351              fields.push(field);
   352              results = module.get.values.call(element, fields);
   353              return results[field];
   354            },
   355            values: function (fields) {
   356              var
   357                $fields = $.isArray(fields)
   358                  ? module.get.fields(fields)
   359                  : $field,
   360                values = {}
   361              ;
   362              $fields.each(function(index, field) {
   363                var
   364                  $field     = $(field),
   365                  type       = $field.prop('type'),
   366                  name       = $field.prop('name'),
   367                  value      = $field.val(),
   368                  isCheckbox = $field.is(selector.checkbox),
   369                  isRadio    = $field.is(selector.radio),
   370                  isMultiple = (name.indexOf('[]') !== -1),
   371                  isChecked  = (isCheckbox)
   372                    ? $field.is(':checked')
   373                    : false
   374                ;
   375                if(name) {
   376                  if(isMultiple) {
   377                    name = name.replace('[]', '');
   378                    if(!values[name]) {
   379                      values[name] = [];
   380                    }
   381                    if(isCheckbox) {
   382                      if(isChecked) {
   383                        values[name].push(value)
   384                      }
   385                      else {
   386                        module.debug('Omitted unchecked checkbox', $field);
   387                        return true;
   388                      }
   389                    }
   390                    else {
   391                      values[name].push(value);
   392                    }
   393                  }
   394                  else {
   395                    if(isRadio) {
   396                      if(isChecked) {
   397                        values[name] = value;
   398                      }
   399                    }
   400                    else if(isCheckbox) {
   401                      if(isChecked) {
   402                        values[name] = true;
   403                      }
   404                      else {
   405                        module.debug('Omitted unchecked checkbox', $field);
   406                        return true;
   407                      }
   408                    }
   409                    else {
   410                      values[name] = value;
   411                    }
   412                  }
   413                }
   414              });
   415              return values;
   416            }
   417          },
   418  
   419          has: {
   420  
   421            field: function(identifier) {
   422              module.verbose('Checking for existence of a field with identifier', identifier);
   423              if( $field.filter('#' + identifier).length > 0 ) {
   424                return true;
   425              }
   426              else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
   427                return true;
   428              }
   429              else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
   430                return true;
   431              }
   432              return false;
   433            }
   434  
   435          },
   436  
   437          add: {
   438            prompt: function(identifier, errors) {
   439              var
   440                $field       = module.get.field(identifier),
   441                $fieldGroup  = $field.closest($group),
   442                $prompt      = $fieldGroup.children(selector.prompt),
   443                promptExists = ($prompt.length !== 0)
   444              ;
   445              errors = (typeof errors == 'string')
   446                ? [errors]
   447                : errors
   448              ;
   449              module.verbose('Adding field error state', identifier);
   450              $fieldGroup
   451                .addClass(className.error)
   452              ;
   453              if(settings.inline) {
   454                if(!promptExists) {
   455                  $prompt = settings.templates.prompt(errors);
   456                  $prompt
   457                    .appendTo($fieldGroup)
   458                  ;
   459                }
   460                $prompt
   461                  .html(errors[0])
   462                ;
   463                if(!promptExists) {
   464                  if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
   465                    module.verbose('Displaying error with css transition', settings.transition);
   466                    $prompt.transition(settings.transition + ' in', settings.duration);
   467                  }
   468                  else {
   469                    module.verbose('Displaying error with fallback javascript animation');
   470                    $prompt
   471                      .fadeIn(settings.duration)
   472                    ;
   473                  }
   474                }
   475                else {
   476                  module.verbose('Inline errors are disabled, no inline error added', identifier);
   477                }
   478              }
   479            },
   480            errors: function(errors) {
   481              module.debug('Adding form error messages', errors);
   482              $message
   483                .html( settings.templates.error(errors) )
   484              ;
   485            }
   486          },
   487  
   488          remove: {
   489            prompt: function(field) {
   490              var
   491                $field      = module.get.field(field.identifier),
   492                $fieldGroup = $field.closest($group),
   493                $prompt     = $fieldGroup.children(selector.prompt)
   494              ;
   495              $fieldGroup
   496                .removeClass(className.error)
   497              ;
   498              if(settings.inline && $prompt.is(':visible')) {
   499                module.verbose('Removing prompt for field', field);
   500                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
   501                  $prompt.transition(settings.transition + ' out', settings.duration, function() {
   502                    $prompt.remove();
   503                  });
   504                }
   505                else {
   506                  $prompt
   507                    .fadeOut(settings.duration, function(){
   508                      $prompt.remove();
   509                    })
   510                  ;
   511                }
   512              }
   513            }
   514          },
   515  
   516          set: {
   517            success: function() {
   518              $module
   519                .removeClass(className.error)
   520                .addClass(className.success)
   521              ;
   522            },
   523            defaults: function () {
   524              $field
   525                .each(function () {
   526                  var
   527                    $field     = $(this),
   528                    isCheckbox = ($field.filter(selector.checkbox).length > 0),
   529                    value      = (isCheckbox)
   530                      ? $field.is(':checked')
   531                      : $field.val()
   532                  ;
   533                  $field.data(metadata.defaultValue, value);
   534                })
   535              ;
   536            },
   537            error: function() {
   538              $module
   539                .removeClass(className.success)
   540                .addClass(className.error)
   541              ;
   542            },
   543            value: function (field, value) {
   544              var
   545                fields = {}
   546              ;
   547              fields[field] = value;
   548              return module.set.values.call(element, fields);
   549            },
   550            values: function (fields) {
   551              if($.isEmptyObject(fields)) {
   552                return;
   553              }
   554              $.each(fields, function(key, value) {
   555                var
   556                  $field      = module.get.field(key),
   557                  $element    = $field.parent(),
   558                  isMultiple  = $.isArray(value),
   559                  isCheckbox  = $element.is(selector.uiCheckbox),
   560                  isDropdown  = $element.is(selector.uiDropdown),
   561                  isRadio     = ($field.is(selector.radio) && isCheckbox),
   562                  fieldExists = ($field.length > 0),
   563                  $multipleField
   564                ;
   565                if(fieldExists) {
   566                  if(isMultiple && isCheckbox) {
   567                    module.verbose('Selecting multiple', value, $field);
   568                    $element.checkbox('uncheck');
   569                    $.each(value, function(index, value) {
   570                      $multipleField = $field.filter('[value="' + value + '"]');
   571                      $element       = $multipleField.parent();
   572                      if($multipleField.length > 0) {
   573                        $element.checkbox('check');
   574                      }
   575                    });
   576                  }
   577                  else if(isRadio) {
   578                    module.verbose('Selecting radio value', value, $field);
   579                    $field.filter('[value="' + value + '"]')
   580                      .parent(selector.uiCheckbox)
   581                        .checkbox('check')
   582                    ;
   583                  }
   584                  else if(isCheckbox) {
   585                    module.verbose('Setting checkbox value', value, $element);
   586                    if(value === true) {
   587                      $element.checkbox('check');
   588                    }
   589                    else {
   590                      $element.checkbox('uncheck');
   591                    }
   592                  }
   593                  else if(isDropdown) {
   594                    module.verbose('Setting dropdown value', value, $element);
   595                    $element.dropdown('set selected', value);
   596                  }
   597                  else {
   598                    module.verbose('Setting field value', value, $field);
   599                    $field.val(value);
   600                  }
   601                }
   602              });
   603              module.validate.form();
   604            }
   605          },
   606  
   607          validate: {
   608  
   609            form: function(event) {
   610              var
   611                allValid = true,
   612                apiRequest
   613              ;
   614  
   615              // input keydown event will fire submit repeatedly by browser default
   616              if(keyHeldDown) {
   617                return false;
   618              }
   619  
   620              // reset errors
   621              formErrors = [];
   622              $.each(validation, function(fieldName, field) {
   623                if( !( module.validate.field(field) ) ) {
   624                  allValid = false;
   625                }
   626              });
   627              if(allValid) {
   628                module.debug('Form has no validation errors, submitting');
   629                module.set.success();
   630                return settings.onSuccess.call(element, event);
   631              }
   632              else {
   633                module.debug('Form has errors');
   634                module.set.error();
   635                if(!settings.inline) {
   636                  module.add.errors(formErrors);
   637                }
   638                // prevent ajax submit
   639                if($module.data('moduleApi') !== undefined) {
   640                  event.stopImmediatePropagation();
   641                }
   642                return settings.onFailure.call(element, formErrors);
   643              }
   644            },
   645  
   646            // takes a validation object and returns whether field passes validation
   647            field: function(field) {
   648              var
   649                $field      = module.get.field(field.identifier),
   650                fieldValid  = true,
   651                fieldErrors = []
   652              ;
   653              if($field.prop('disabled')) {
   654                module.debug('Field is disabled. Skipping', field.identifier);
   655                fieldValid = true;
   656              }
   657              else if(field.optional && $.trim($field.val()) === ''){
   658                module.debug('Field is optional and empty. Skipping', field.identifier);
   659                fieldValid = true;
   660              }
   661              else if(field.rules !== undefined) {
   662                $.each(field.rules, function(index, rule) {
   663                  if( module.has.field(field.identifier) && !( module.validate.rule(field, rule) ) ) {
   664                    module.debug('Field is invalid', field.identifier, rule.type);
   665                    fieldErrors.push(rule.prompt);
   666                    fieldValid = false;
   667                  }
   668                });
   669              }
   670              if(fieldValid) {
   671                module.remove.prompt(field, fieldErrors);
   672                settings.onValid.call($field);
   673              }
   674              else {
   675                formErrors = formErrors.concat(fieldErrors);
   676                module.add.prompt(field.identifier, fieldErrors);
   677                settings.onInvalid.call($field, fieldErrors);
   678                return false;
   679              }
   680              return true;
   681            },
   682  
   683            // takes validation rule and returns whether field passes rule
   684            rule: function(field, validation) {
   685              var
   686                $field        = module.get.field(field.identifier),
   687                type          = validation.type,
   688                value         = $.trim($field.val() + ''),
   689  
   690                bracketRegExp = /\[(.*)\]/i,
   691                bracket       = bracketRegExp.exec(type),
   692                isValid       = true,
   693                ancillary,
   694                functionType
   695              ;
   696              // if bracket notation is used, pass in extra parameters
   697              if(bracket !== undefined && bracket !== null) {
   698                ancillary    = '' + bracket[1];
   699                functionType = type.replace(bracket[0], '');
   700                isValid      = settings.rules[functionType].call(element, value, ancillary);
   701              }
   702              // normal notation
   703              else {
   704                isValid = settings.rules[type].call($field, value);
   705              }
   706              return isValid;
   707            }
   708          },
   709  
   710          setting: function(name, value) {
   711            if( $.isPlainObject(name) ) {
   712              $.extend(true, settings, name);
   713            }
   714            else if(value !== undefined) {
   715              settings[name] = value;
   716            }
   717            else {
   718              return settings[name];
   719            }
   720          },
   721          internal: function(name, value) {
   722            if( $.isPlainObject(name) ) {
   723              $.extend(true, module, name);
   724            }
   725            else if(value !== undefined) {
   726              module[name] = value;
   727            }
   728            else {
   729              return module[name];
   730            }
   731          },
   732          debug: function() {
   733            if(settings.debug) {
   734              if(settings.performance) {
   735                module.performance.log(arguments);
   736              }
   737              else {
   738                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
   739                module.debug.apply(console, arguments);
   740              }
   741            }
   742          },
   743          verbose: function() {
   744            if(settings.verbose && settings.debug) {
   745              if(settings.performance) {
   746                module.performance.log(arguments);
   747              }
   748              else {
   749                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
   750                module.verbose.apply(console, arguments);
   751              }
   752            }
   753          },
   754          error: function() {
   755            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
   756            module.error.apply(console, arguments);
   757          },
   758          performance: {
   759            log: function(message) {
   760              var
   761                currentTime,
   762                executionTime,
   763                previousTime
   764              ;
   765              if(settings.performance) {
   766                currentTime   = new Date().getTime();
   767                previousTime  = time || currentTime;
   768                executionTime = currentTime - previousTime;
   769                time          = currentTime;
   770                performance.push({
   771                  'Name'           : message[0],
   772                  'Arguments'      : [].slice.call(message, 1) || '',
   773                  'Element'        : element,
   774                  'Execution Time' : executionTime
   775                });
   776              }
   777              clearTimeout(module.performance.timer);
   778              module.performance.timer = setTimeout(module.performance.display, 100);
   779            },
   780            display: function() {
   781              var
   782                title = settings.name + ':',
   783                totalTime = 0
   784              ;
   785              time = false;
   786              clearTimeout(module.performance.timer);
   787              $.each(performance, function(index, data) {
   788                totalTime += data['Execution Time'];
   789              });
   790              title += ' ' + totalTime + 'ms';
   791              if(moduleSelector) {
   792                title += ' \'' + moduleSelector + '\'';
   793              }
   794              if($allModules.length > 1) {
   795                title += ' ' + '(' + $allModules.length + ')';
   796              }
   797              if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
   798                console.groupCollapsed(title);
   799                if(console.table) {
   800                  console.table(performance);
   801                }
   802                else {
   803                  $.each(performance, function(index, data) {
   804                    console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
   805                  });
   806                }
   807                console.groupEnd();
   808              }
   809              performance = [];
   810            }
   811          },
   812          invoke: function(query, passedArguments, context) {
   813            var
   814              object = instance,
   815              maxDepth,
   816              found,
   817              response
   818            ;
   819            passedArguments = passedArguments || queryArguments;
   820            context         = element         || context;
   821            if(typeof query == 'string' && object !== undefined) {
   822              query    = query.split(/[\. ]/);
   823              maxDepth = query.length - 1;
   824              $.each(query, function(depth, value) {
   825                var camelCaseValue = (depth != maxDepth)
   826                  ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
   827                  : query
   828                ;
   829                if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
   830                  object = object[camelCaseValue];
   831                }
   832                else if( object[camelCaseValue] !== undefined ) {
   833                  found = object[camelCaseValue];
   834                  return false;
   835                }
   836                else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
   837                  object = object[value];
   838                }
   839                else if( object[value] !== undefined ) {
   840                  found = object[value];
   841                  return false;
   842                }
   843                else {
   844                  return false;
   845                }
   846              });
   847            }
   848            if( $.isFunction( found ) ) {
   849              response = found.apply(context, passedArguments);
   850            }
   851            else if(found !== undefined) {
   852              response = found;
   853            }
   854            if($.isArray(returnedValue)) {
   855              returnedValue.push(response);
   856            }
   857            else if(returnedValue !== undefined) {
   858              returnedValue = [returnedValue, response];
   859            }
   860            else if(response !== undefined) {
   861              returnedValue = response;
   862            }
   863            return found;
   864          }
   865        };
   866        if(methodInvoked) {
   867          if(instance === undefined) {
   868            module.initialize();
   869          }
   870          module.invoke(query);
   871        }
   872        else {
   873          if(instance !== undefined) {
   874            instance.invoke('destroy');
   875          }
   876          module.initialize();
   877        }
   878  
   879      })
   880    ;
   881  
   882    return (returnedValue !== undefined)
   883      ? returnedValue
   884      : this
   885    ;
   886  };
   887  
   888  $.fn.form.settings = {
   889  
   890    name              : 'Form',
   891    namespace         : 'form',
   892  
   893    debug             : false,
   894    verbose           : true,
   895    performance       : true,
   896  
   897  
   898    keyboardShortcuts : true,
   899    on                : 'submit',
   900    inline            : false,
   901  
   902    delay             : 200,
   903    revalidate        : true,
   904  
   905    transition        : 'scale',
   906    duration          : 200,
   907  
   908    onValid           : function() {},
   909    onInvalid         : function() {},
   910    onSuccess         : function() { return true; },
   911    onFailure         : function() { return false; },
   912  
   913    metadata : {
   914      defaultValue : 'default',
   915      validate     : 'validate'
   916    },
   917  
   918    selector : {
   919      checkbox   : 'input[type="checkbox"], input[type="radio"]',
   920      clear      : '.clear',
   921      field      : 'input, textarea, select',
   922      group      : '.field',
   923      input      : 'input',
   924      message    : '.error.message',
   925      prompt     : '.prompt.label',
   926      radio      : 'input[type="radio"]',
   927      reset      : '.reset',
   928      submit     : '.submit',
   929      uiCheckbox : '.ui.checkbox',
   930      uiDropdown : '.ui.dropdown'
   931    },
   932  
   933    className : {
   934      error   : 'error',
   935      label   : 'ui prompt label',
   936      pressed : 'down',
   937      success : 'success'
   938    },
   939  
   940    error: {
   941      method   : 'The method you called is not defined.'
   942    },
   943  
   944    templates: {
   945  
   946      // template that produces error message
   947      error: function(errors) {
   948        var
   949          html = '<ul class="list">'
   950        ;
   951        $.each(errors, function(index, value) {
   952          html += '<li>' + value + '</li>';
   953        });
   954        html += '</ul>';
   955        return $(html);
   956      },
   957  
   958      // template that produces label
   959      prompt: function(errors) {
   960        return $('<div/>')
   961          .addClass('ui red pointing prompt label')
   962          .html(errors[0])
   963        ;
   964      }
   965    },
   966  
   967    rules: {
   968  
   969      // checkbox checked
   970      checked: function() {
   971        return ($(this).filter(':checked').length > 0);
   972      },
   973  
   974      // value contains text (insensitive)
   975      contains: function(value, text) {
   976        // escape regex characters
   977        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
   978        return (value.search( new RegExp(text, 'i') ) !== -1);
   979      },
   980  
   981      // value contains text (case sensitive)
   982      containsExactly: function(value, text) {
   983        // escape regex characters
   984        text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
   985        return (value.search( new RegExp(text) ) !== -1);
   986      },
   987  
   988      // is most likely an email
   989      email: function(value){
   990        var
   991          emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "i")
   992        ;
   993        return emailRegExp.test(value);
   994      },
   995  
   996      // is not empty or blank string
   997      empty: function(value) {
   998        return !(value === undefined || '' === value);
   999      },
  1000  
  1001      // is valid integer
  1002      integer: function(value, range) {
  1003        var
  1004          intRegExp = /^\-?\d+$/,
  1005          min,
  1006          max,
  1007          parts
  1008        ;
  1009        if(range === undefined || range === '' || range === '..') {
  1010          // do nothing
  1011        }
  1012        else if(range.indexOf('..') == -1) {
  1013          if(intRegExp.test(range)) {
  1014            min = max = range - 0;
  1015          }
  1016        }
  1017        else {
  1018          parts = range.split('..', 2);
  1019          if(intRegExp.test(parts[0])) {
  1020            min = parts[0] - 0;
  1021          }
  1022          if(intRegExp.test(parts[1])) {
  1023            max = parts[1] - 0;
  1024          }
  1025        }
  1026        return (
  1027          intRegExp.test(value) &&
  1028          (min === undefined || value >= min) &&
  1029          (max === undefined || value <= max)
  1030        );
  1031      },
  1032  
  1033      // is value (case insensitive)
  1034      is: function(value, text) {
  1035        text = (typeof text == 'string')
  1036          ? text.toLowerCase()
  1037          : text
  1038        ;
  1039        value = (typeof value == 'string')
  1040          ? value.toLowerCase()
  1041          : value
  1042        ;
  1043        return (value == text);
  1044      },
  1045  
  1046      // is value
  1047      isExactly: function(value, text) {
  1048        return (value == text);
  1049      },
  1050  
  1051      // is at least string length
  1052      length: function(value, requiredLength) {
  1053        return (value !== undefined)
  1054          ? (value.length >= requiredLength)
  1055          : false
  1056        ;
  1057      },
  1058  
  1059      // matches another field
  1060      match: function(value, fieldIdentifier) {
  1061        // use either id or name of field
  1062        var
  1063          $form = $(this),
  1064          matchingValue
  1065        ;
  1066        if($form.find('#' + fieldIdentifier).length > 0) {
  1067          matchingValue = $form.find('#' + fieldIdentifier).val();
  1068        }
  1069        else if($form.find('[name="' + fieldIdentifier +'"]').length > 0) {
  1070          matchingValue = $form.find('[name="' + fieldIdentifier + '"]').val();
  1071        }
  1072        else if( $form.find('[data-validate="'+ fieldIdentifier +'"]').length > 0 ) {
  1073          matchingValue = $form.find('[data-validate="'+ fieldIdentifier +'"]').val();
  1074        }
  1075        return (matchingValue !== undefined)
  1076          ? ( value.toString() == matchingValue.toString() )
  1077          : false
  1078        ;
  1079      },
  1080  
  1081      // string length is less than max length
  1082      maxLength: function(value, maxLength) {
  1083        return (value !== undefined)
  1084          ? (value.length <= maxLength)
  1085          : false
  1086        ;
  1087      },
  1088  
  1089      // value is not value (case insensitive)
  1090      not: function(value, notValue) {
  1091        value = (typeof value == 'string')
  1092          ? value.toLowerCase()
  1093          : value
  1094        ;
  1095        notValue = (typeof notValue == 'string')
  1096          ? notValue.toLowerCase()
  1097          : notValue
  1098        ;
  1099        return (value != notValue);
  1100      },
  1101  
  1102      // value is not value (case sensitive)
  1103      notExactly: function(value, notValue) {
  1104        return (value != notValue);
  1105      },
  1106  
  1107      // value is most likely url
  1108      url: function(value) {
  1109        var
  1110          urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
  1111        ;
  1112        return urlRegExp.test(value);
  1113      }
  1114    }
  1115  
  1116  };
  1117  
  1118  })( jQuery, window , document );