diff options
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/semantic.js | 14128 | ||||
-rw-r--r-- | src/js/semantic.min.js | 17 |
2 files changed, 10079 insertions, 4066 deletions
diff --git a/src/js/semantic.js b/src/js/semantic.js index c0ea5b7..378108c 100644 --- a/src/js/semantic.js +++ b/src/js/semantic.js @@ -1,5 +1,5 @@ /* - * # Semantic UI + * # Semantic UI - 2.1.6 * https://github.com/Semantic-Org/Semantic-UI * http://www.semantic-ui.com/ * @@ -8,12 +8,12 @@ * http://opensource.org/licenses/MIT * */ -/* - * # Semantic - Site +/*! + * # Semantic UI 2.1.6 - Site * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributor + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * @@ -91,7 +91,7 @@ $.site = $.fn.site = function(parameters) { requestAnimationFrame: function() { module.debug('Normalizing requestAnimationFrame'); if(window.requestAnimationFrame === undefined) { - module.debug('RequestAnimationFrame not available, normailizing event'); + module.debug('RequestAnimationFrame not available, normalizing event'); window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame @@ -160,7 +160,7 @@ $.site = $.fn.site = function(parameters) { $.fn[name].settings[setting] = value; if(modifyExisting && namespace) { $existingModules = $(':data(module-' + namespace + ')'); - if($existingModules.size() > 0) { + if($existingModules.length > 0) { module.verbose('Modifying existing settings', $existingModules); $existingModules[name]('setting', setting, value); } @@ -186,7 +186,7 @@ $.site = $.fn.site = function(parameters) { $.extend(true, $.fn[name].settings, newSettings); if(modifyExisting && namespace) { $existingModules = $(':data(module-' + namespace + ')'); - if($existingModules.size() > 0) { + if($existingModules.length > 0) { module.verbose('Modifying existing settings', $existingModules); $existingModules[name]('setting', newSettings); } @@ -330,7 +330,7 @@ $.site = $.fn.site = function(parameters) { }); } clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 100); + module.performance.timer = setTimeout(module.performance.display, 500); }, display: function() { var @@ -443,7 +443,7 @@ $.site.settings = { }, debug : false, - verbose : true, + verbose : false, performance : true, modules: [ @@ -452,6 +452,7 @@ $.site.settings = { 'checkbox', 'dimmer', 'dropdown', + 'embed', 'form', 'modal', 'nag', @@ -463,7 +464,6 @@ $.site.settings = { 'sticky', 'tab', 'transition', - 'video', 'visit', 'visibility' ], @@ -494,13 +494,14 @@ $.extend($.expr[ ":" ], { }); -})( jQuery, window , document ); -/* - * # Semantic - Form Validation +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.1.6 - Form Validation * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributor + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * @@ -508,55 +509,74 @@ $.extend($.expr[ ":" ], { ;(function ( $, window, document, undefined ) { -$.fn.form = function(fields, parameters) { - var - $allModules = $(this), - - settings = $.extend(true, {}, $.fn.form.settings, parameters), - validation = $.extend({}, $.fn.form.settings.defaults, fields), - - namespace = settings.namespace, - metadata = settings.metadata, - selector = settings.selector, - className = settings.className, - error = settings.error, - - eventNamespace = '.' + namespace, - moduleNamespace = 'module-' + namespace, +"use strict"; - moduleSelector = $allModules.selector || '', +$.fn.form = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', - time = new Date().getTime(), - performance = [], + time = new Date().getTime(), + performance = [], - query = arguments[0], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1), + query = arguments[0], + legacyParameters = arguments[1], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), returnedValue ; $allModules .each(function() { var - $module = $(this), - $field = $(this).find(selector.field), - $group = $(this).find(selector.group), - $message = $(this).find(selector.message), - $prompt = $(this).find(selector.prompt), - $submit = $(this).find(selector.submit), + $module = $(this), + element = this, - formErrors = [], + formErrors = [], + keyHeldDown = false, - element = this, - instance = $module.data(moduleNamespace), + // set at run-time + $field, + $group, + $message, + $prompt, + $submit, + $clear, + $reset, + + settings, + validation, + + metadata, + selector, + className, + error, + + namespace, + moduleNamespace, + eventNamespace, + + instance, module ; module = { initialize: function() { - module.verbose('Initializing form validation', $module, validation, settings); - module.bindEvents(); - module.instantiate(); + + // settings grabbed at run time + module.get.settings(); + if(methodInvoked) { + if(instance === undefined) { + module.instantiate(); + } + module.invoke(query); + } + else { + module.verbose('Initializing form validation', $module, settings); + module.bindEvents(); + module.set.defaults(); + module.instantiate(); + } }, instantiate: function() { @@ -577,7 +597,14 @@ $.fn.form = function(fields, parameters) { refresh: function() { module.verbose('Refreshing selector cache'); - $field = $module.find(selector.field); + $field = $module.find(selector.field); + $group = $module.find(selector.group); + $message = $module.find(selector.message); + $prompt = $module.find(selector.prompt); + + $submit = $module.find(selector.submit); + $clear = $module.find(selector.clear); + $reset = $module.find(selector.reset); }, submit: function() { @@ -590,7 +617,7 @@ $.fn.form = function(fields, parameters) { attachEvents: function(selector, action) { action = action || 'submit'; $(selector) - .on('click', function(event) { + .on('click' + eventNamespace, function(event) { module[action](); event.preventDefault(); }) @@ -598,26 +625,25 @@ $.fn.form = function(fields, parameters) { }, bindEvents: function() { - - if(settings.keyboardShortcuts) { - $field - .on('keydown' + eventNamespace, module.event.field.keydown) - ; - } + module.verbose('Attaching form events'); $module .on('submit' + eventNamespace, module.validate.form) + .on('blur' + eventNamespace, selector.field, module.event.field.blur) + .on('click' + eventNamespace, selector.submit, module.submit) + .on('click' + eventNamespace, selector.reset, module.reset) + .on('click' + eventNamespace, selector.clear, module.clear) ; - $field - .on('blur' + eventNamespace, module.event.field.blur) - ; - // attach submit events - module.attachEvents($submit, 'submit'); - + if(settings.keyboardShortcuts) { + $module + .on('keydown' + eventNamespace, selector.field, module.event.field.keydown) + ; + } $field .each(function() { var - type = $(this).prop('type'), - inputEvent = module.get.changeEvent(type) + $input = $(this), + type = $input.prop('type'), + inputEvent = module.get.changeEvent(type, $input) ; $(this) .on(inputEvent + eventNamespace, module.event.field.change) @@ -626,6 +652,94 @@ $.fn.form = function(fields, parameters) { ; }, + clear: function() { + $field + .each(function () { + var + $field = $(this), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.find(selector.prompt), + defaultValue = $field.data(metadata.defaultValue) || '', + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isErrored = $fieldGroup.hasClass(className.error) + ; + if(isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if(isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('clear'); + } + else if(isCheckbox) { + $field.prop('checked', false); + } + else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(''); + } + }) + ; + }, + + reset: function() { + $field + .each(function () { + var + $field = $(this), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.find(selector.prompt), + defaultValue = $field.data(metadata.defaultValue), + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isErrored = $fieldGroup.hasClass(className.error) + ; + if(defaultValue === undefined) { + return; + } + if(isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if(isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('restore defaults'); + } + else if(isCheckbox) { + module.verbose('Resetting checkbox value', $element, defaultValue); + $field.prop('checked', defaultValue); + } + else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(defaultValue); + } + }) + ; + }, + + is: { + bracketedRule: function(rule) { + return (rule.type && rule.type.match(settings.regExp.bracket)); + }, + valid: function() { + var + allValid = true + ; + module.verbose('Checking if form is valid'); + $.each(validation, function(fieldName, field) { + if( !( module.validate.field(field, fieldName) ) ) { + allValid = false; + } + }); + return allValid; + } + }, + removeEvents: function() { $module .off(eventNamespace) @@ -658,35 +772,37 @@ $.fn.form = function(fields, parameters) { .blur() ; } - if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).size() > 0 ) { - module.debug('Enter key pressed, submitting form'); - $submit - .addClass(className.down) - ; - $field - .one('keyup' + eventNamespace, module.event.field.keyup) - ; + if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) { + if(!keyHeldDown) { + $field + .one('keyup' + eventNamespace, module.event.field.keyup) + ; + module.submit(); + module.debug('Enter pressed on input submitting form'); + } + keyHeldDown = true; } }, keyup: function() { - module.verbose('Doing keyboard shortcut form submit'); - $submit.removeClass(className.down); - module.submit(); + keyHeldDown = false; }, - blur: function() { + blur: function(event) { var - $field = $(this), - $fieldGroup = $field.closest($group) + $field = $(this), + $fieldGroup = $field.closest($group), + validationRules = module.get.validation($field) ; if( $fieldGroup.hasClass(className.error) ) { - module.debug('Revalidating field', $field, module.get.validation($field)); - module.validate.field( module.get.validation($field) ); + module.debug('Revalidating field', $field, validationRules); + module.validate.form.call(module, event, true); } else if(settings.on == 'blur' || settings.on == 'change') { - module.validate.field( module.get.validation($field) ); + if(validationRules) { + module.validate.field( validationRules ); + } } }, - change: function() { + change: function(event) { var $field = $(this), $fieldGroup = $field.closest($group) @@ -695,7 +811,7 @@ $.fn.form = function(fields, parameters) { clearTimeout(module.timer); module.timer = setTimeout(function() { module.debug('Revalidating field', $field, module.get.validation($field)); - module.validate.field( module.get.validation($field) ); + module.validate.form.call(module, event, true); }, settings.delay); } } @@ -704,42 +820,237 @@ $.fn.form = function(fields, parameters) { }, get: { - changeEvent: function(type) { - if(type == 'checkbox' || type == 'radio' || type == 'hidden') { + ancillaryValue: function(rule) { + if(!rule.type || !module.is.bracketedRule(rule)) { + return false; + } + return rule.type.match(settings.regExp.bracket)[1] + ''; + }, + ruleName: function(rule) { + if( module.is.bracketedRule(rule) ) { + return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], ''); + } + return rule.type; + }, + changeEvent: function(type, $input) { + if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) { return 'change'; } else { - return (document.createElement('input').oninput !== undefined) - ? 'input' - : (document.createElement('input').onpropertychange !== undefined) - ? 'propertychange' - : 'keyup' + return module.get.inputEvent(); + } + }, + inputEvent: function() { + return (document.createElement('input').oninput !== undefined) + ? 'input' + : (document.createElement('input').onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + }, + prompt: function(rule, field) { + var + ruleName = module.get.ruleName(rule), + ancillary = module.get.ancillaryValue(rule), + prompt = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule, + requiresValue = (prompt.search('{value}') !== -1), + requiresName = (prompt.search('{name}') !== -1), + $label, + $field, + name + ; + if(requiresName || requiresValue) { + $field = module.get.field(field.identifier); + } + if(requiresValue) { + prompt = prompt.replace('{value}', $field.val()); + } + if(requiresName) { + $label = $field.closest(selector.group).find('label').eq(0); + name = ($label.size() == 1) + ? $label.text() + : $field.prop('placeholder') || settings.text.unspecifiedField ; + prompt = prompt.replace('{name}', name); + } + prompt = prompt.replace('{identifier}', field.identifier); + prompt = prompt.replace('{ruleValue}', ancillary); + if(!rule.prompt) { + module.verbose('Using default validation prompt for type', prompt, ruleName); + } + return prompt; + }, + settings: function() { + if($.isPlainObject(parameters)) { + var + keys = Object.keys(parameters), + isLegacySettings = (keys.length > 0) + ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined) + : false, + ruleKeys + ; + if(isLegacySettings) { + // 1.x (ducktyped) + settings = $.extend(true, {}, $.fn.form.settings, legacyParameters); + validation = $.extend({}, $.fn.form.settings.defaults, parameters); + module.error(settings.error.oldSyntax, element); + module.verbose('Extending settings from legacy parameters', validation, settings); + } + else { + // 2.x + if(parameters.fields) { + ruleKeys = Object.keys(parameters.fields); + if( typeof parameters.fields[ruleKeys[0]] == 'string' || $.isArray(parameters.fields[ruleKeys[0]]) ) { + $.each(parameters.fields, function(name, rules) { + if(typeof rules == 'string') { + rules = [rules]; + } + parameters.fields[name] = { + rules: [] + }; + $.each(rules, function(index, rule) { + parameters.fields[name].rules.push({ type: rule }); + }); + }); + } + } + + settings = $.extend(true, {}, $.fn.form.settings, parameters); + validation = $.extend({}, $.fn.form.settings.defaults, settings.fields); + module.verbose('Extending settings', validation, settings); + } } + else { + settings = $.fn.form.settings; + validation = $.fn.form.settings.defaults; + module.verbose('Using default form validation', validation, settings); + } + + // shorthand + namespace = settings.namespace; + metadata = settings.metadata; + selector = settings.selector; + className = settings.className; + error = settings.error; + moduleNamespace = 'module-' + namespace; + eventNamespace = '.' + namespace; + + // grab instance + instance = $module.data(moduleNamespace); + + // refresh selector cache + module.refresh(); }, field: function(identifier) { module.verbose('Finding field with identifier', identifier); - if( $field.filter('#' + identifier).size() > 0 ) { + if( $field.filter('#' + identifier).length > 0 ) { return $field.filter('#' + identifier); } - else if( $field.filter('[name="' + identifier +'"]').size() > 0 ) { + else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { return $field.filter('[name="' + identifier +'"]'); } - else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').size() > 0 ) { + else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) { + return $field.filter('[name="' + identifier +'[]"]'); + } + else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]'); } return $('<input/>'); }, + fields: function(fields) { + var + $fields = $() + ; + $.each(fields, function(index, name) { + $fields = $fields.add( module.get.field(name) ); + }); + return $fields; + }, validation: function($field) { var - rules + fieldValidation, + identifier ; + if(!validation) { + return false; + } $.each(validation, function(fieldName, field) { - if( module.get.field(field.identifier).get(0) == $field.get(0) ) { - rules = field; + identifier = field.identifier || fieldName; + if( module.get.field(identifier)[0] == $field[0] ) { + field.identifier = identifier; + fieldValidation = field; } }); - return rules || false; + return fieldValidation || false; + }, + value: function (field) { + var + fields = [], + results + ; + fields.push(field); + results = module.get.values.call(element, fields); + return results[field]; + }, + values: function (fields) { + var + $fields = $.isArray(fields) + ? module.get.fields(fields) + : $field, + values = {} + ; + $fields.each(function(index, field) { + var + $field = $(field), + type = $field.prop('type'), + name = $field.prop('name'), + value = $field.val(), + isCheckbox = $field.is(selector.checkbox), + isRadio = $field.is(selector.radio), + isMultiple = (name.indexOf('[]') !== -1), + isChecked = (isCheckbox) + ? $field.is(':checked') + : false + ; + if(name) { + if(isMultiple) { + name = name.replace('[]', ''); + if(!values[name]) { + values[name] = []; + } + if(isCheckbox) { + if(isChecked) { + values[name].push(value || true); + } + else { + values[name].push(false); + } + } + else { + values[name].push(value); + } + } + else { + if(isRadio) { + if(isChecked) { + values[name] = value; + } + } + else if(isCheckbox) { + if(isChecked) { + values[name] = value || true; + } + else { + values[name] = false; + } + } + else { + values[name] = value; + } + } + } + }); + return values; } }, @@ -747,13 +1058,16 @@ $.fn.form = function(fields, parameters) { field: function(identifier) { module.verbose('Checking for existence of a field with identifier', identifier); - if( $field.filter('#' + identifier).size() > 0 ) { + if(typeof identifier !== 'string') { + module.error(error.identifier, identifier); + } + if( $field.filter('#' + identifier).length > 0 ) { return true; } - else if( $field.filter('[name="' + identifier +'"]').size() > 0 ) { + else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { return true; } - else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').size() > 0 ) { + else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { return true; } return false; @@ -766,8 +1080,8 @@ $.fn.form = function(fields, parameters) { var $field = module.get.field(identifier), $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.find(selector.prompt), - promptExists = ($prompt.size() !== 0) + $prompt = $fieldGroup.children(selector.prompt), + promptExists = ($prompt.length !== 0) ; errors = (typeof errors == 'string') ? [errors] @@ -806,6 +1120,7 @@ $.fn.form = function(fields, parameters) { }, errors: function(errors) { module.debug('Adding form error messages', errors); + module.set.error(); $message .html( settings.templates.error(errors) ) ; @@ -813,17 +1128,17 @@ $.fn.form = function(fields, parameters) { }, remove: { - prompt: function(field) { + prompt: function(identifier) { var - $field = module.get.field(field.identifier), + $field = module.get.field(identifier), $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.find(selector.prompt) + $prompt = $fieldGroup.children(selector.prompt) ; $fieldGroup .removeClass(className.error) ; if(settings.inline && $prompt.is(':visible')) { - module.verbose('Removing prompt for field', field); + module.verbose('Removing prompt for field', identifier); if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $prompt.transition(settings.transition + ' out', settings.duration, function() { $prompt.remove(); @@ -847,32 +1162,110 @@ $.fn.form = function(fields, parameters) { .addClass(className.success) ; }, + defaults: function () { + $field + .each(function () { + var + $field = $(this), + isCheckbox = ($field.filter(selector.checkbox).length > 0), + value = (isCheckbox) + ? $field.is(':checked') + : $field.val() + ; + $field.data(metadata.defaultValue, value); + }) + ; + }, error: function() { $module .removeClass(className.success) .addClass(className.error) ; + }, + value: function (field, value) { + var + fields = {} + ; + fields[field] = value; + return module.set.values.call(element, fields); + }, + values: function (fields) { + if($.isEmptyObject(fields)) { + return; + } + $.each(fields, function(key, value) { + var + $field = module.get.field(key), + $element = $field.parent(), + isMultiple = $.isArray(value), + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isRadio = ($field.is(selector.radio) && isCheckbox), + fieldExists = ($field.length > 0), + $multipleField + ; + if(fieldExists) { + if(isMultiple && isCheckbox) { + module.verbose('Selecting multiple', value, $field); + $element.checkbox('uncheck'); + $.each(value, function(index, value) { + $multipleField = $field.filter('[value="' + value + '"]'); + $element = $multipleField.parent(); + if($multipleField.length > 0) { + $element.checkbox('check'); + } + }); + } + else if(isRadio) { + module.verbose('Selecting radio value', value, $field); + $field.filter('[value="' + value + '"]') + .parent(selector.uiCheckbox) + .checkbox('check') + ; + } + else if(isCheckbox) { + module.verbose('Setting checkbox value', value, $element); + if(value === true) { + $element.checkbox('check'); + } + else { + $element.checkbox('uncheck'); + } + } + else if(isDropdown) { + module.verbose('Setting dropdown value', value, $element); + $element.dropdown('set selected', value); + } + else { + module.verbose('Setting field value', value, $field); + $field.val(value); + } + } + }); } }, validate: { - form: function(event) { + form: function(event, ignoreCallbacks) { var - allValid = true, + values = module.get.values(), apiRequest ; + + // input keydown event will fire submit repeatedly by browser default + if(keyHeldDown) { + return false; + } + // reset errors formErrors = []; - $.each(validation, function(fieldName, field) { - if( !( module.validate.field(field) ) ) { - allValid = false; - } - }); - if(allValid) { + if( module.is.valid() ) { module.debug('Form has no validation errors, submitting'); module.set.success(); - return $.proxy(settings.onSuccess, this)(event); + if(ignoreCallbacks !== true) { + return settings.onSuccess.call(element, event, values); + } } else { module.debug('Form has errors'); @@ -884,67 +1277,75 @@ $.fn.form = function(fields, parameters) { if($module.data('moduleApi') !== undefined) { event.stopImmediatePropagation(); } - return $.proxy(settings.onFailure, this)(formErrors); + if(ignoreCallbacks !== true) { + return settings.onFailure.call(element, formErrors, values); + } } }, // takes a validation object and returns whether field passes validation - field: function(field) { + field: function(field, fieldName) { var - $field = module.get.field(field.identifier), + identifier = field.identifier || fieldName, + $field = module.get.field(identifier), fieldValid = true, fieldErrors = [] ; - if(field.optional && $.trim($field.val()) === ''){ - module.debug('Field is optional and empty. Skipping', field.identifier); + if(!field.identifier) { + module.debug('Using field name as identifier', identifier); + field.identifier = identifier; + } + if($field.prop('disabled')) { + module.debug('Field is disabled. Skipping', identifier); + fieldValid = true; + } + else if(field.optional && $.trim($field.val()) === ''){ + module.debug('Field is optional and empty. Skipping', identifier); fieldValid = true; } else if(field.rules !== undefined) { $.each(field.rules, function(index, rule) { - if( module.has.field(field.identifier) && !( module.validate.rule(field, rule) ) ) { - module.debug('Field is invalid', field.identifier, rule.type); - fieldErrors.push(rule.prompt); + if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) { + module.debug('Field is invalid', identifier, rule.type); + fieldErrors.push(module.get.prompt(rule, field)); fieldValid = false; } }); } if(fieldValid) { - module.remove.prompt(field, fieldErrors); - $.proxy(settings.onValid, $field)(); + module.remove.prompt(identifier, fieldErrors); + settings.onValid.call($field); } else { formErrors = formErrors.concat(fieldErrors); - module.add.prompt(field.identifier, fieldErrors); - $.proxy(settings.onInvalid, $field)(fieldErrors); + module.add.prompt(identifier, fieldErrors); + settings.onInvalid.call($field, fieldErrors); return false; } return true; }, // takes validation rule and returns whether field passes rule - rule: function(field, validation) { + rule: function(field, rule) { var - $field = module.get.field(field.identifier), - type = validation.type, - value = $.trim($field.val() + ''), - - bracketRegExp = /\[(.*)\]/i, - bracket = bracketRegExp.exec(type), - isValid = true, - ancillary, - functionType - ; - // if bracket notation is used, pass in extra parameters - if(bracket !== undefined && bracket !== null) { - ancillary = '' + bracket[1]; - functionType = type.replace(bracket[0], ''); - isValid = $.proxy(settings.rules[functionType], $module)(value, ancillary); - } - // normal notation - else { - isValid = $.proxy(settings.rules[type], $field)(value); + $field = module.get.field(field.identifier), + type = rule.type, + value = $field.val(), + isValid = true, + ancillary = module.get.ancillaryValue(rule), + ruleName = module.get.ruleName(rule), + ruleFunction = settings.rules[ruleName] + ; + if( !$.isFunction(ruleFunction) ) { + module.error(error.noRule, ruleName); + return; } - return isValid; + // cast to string avoiding encoding special values + value = (value === undefined || value === '' || value === null) + ? '' + : $.trim(value + '') + ; + return ruleFunction.call($field, value, ancillary); } }, @@ -1016,7 +1417,7 @@ $.fn.form = function(fields, parameters) { }); } clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 100); + module.performance.timer = setTimeout(module.performance.display, 500); }, display: function() { var @@ -1032,8 +1433,8 @@ $.fn.form = function(fields, parameters) { if(moduleSelector) { title += ' \'' + moduleSelector + '\''; } - if($allModules.size() |