fomantic-ui
Version:
Fomantic empowers designers and developers by creating a shared vocabulary for UI.
1,176 lines (1,069 loc) • 1.39 MB
JavaScript
/*
* # Fomantic UI - 2.9.4
* https://github.com/fomantic/Fomantic-UI
* https://fomantic-ui.com/
*
* Copyright 2025 Contributors
* Released under the MIT license
* https://opensource.org/licenses/MIT
*
*/
/*!
* # Fomantic-UI 2.9.4 - Site
* https://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* https://opensource.org/licenses/MIT
*
*/
(function ($, window, document) {
'use strict';
function isFunction(obj) {
return typeof obj === 'function' && typeof obj.nodeType !== 'number';
}
window = window !== undefined && window.Math === Math
? window
: globalThis;
$.fn.site = function (parameters) {
var
time = Date.now(),
performance = [],
query = arguments[0],
methodInvoked = typeof query === 'string',
queryArguments = [].slice.call(arguments, 1),
settings = $.isPlainObject(parameters)
? $.extend(true, {}, $.site.settings, parameters)
: $.extend({}, $.site.settings),
namespace = settings.namespace,
error = settings.error,
moduleNamespace = 'module-' + namespace,
$document = $(document),
$module = $document,
element = this,
instance = $module.data(moduleNamespace),
module,
returnedValue
;
module = {
initialize: function () {
module.instantiate();
},
instantiate: function () {
module.verbose('Storing instance of site', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
normalize: function () {
// keep the function for backward compatibility
// eslint-disable-next-line no-useless-return
return;
},
fix: {
consoleClear: function () {
module.debug('Disabling programmatic console clearing');
window.console.clear = function () {};
},
},
moduleExists: function (name) {
return $.fn[name] !== undefined && $.fn[name].settings !== undefined;
},
enabled: {
modules: function (modules) {
var
enabledModules = []
;
modules = modules || settings.modules;
$.each(modules, function (index, name) {
if (module.moduleExists(name)) {
enabledModules.push(name);
}
});
return enabledModules;
},
},
disabled: {
modules: function (modules) {
var
disabledModules = []
;
modules = modules || settings.modules;
$.each(modules, function (index, name) {
if (!module.moduleExists(name)) {
disabledModules.push(name);
}
});
return disabledModules;
},
},
change: {
setting: function (setting, value, modules, modifyExisting) {
modules = typeof modules === 'string'
? (modules === 'all'
? settings.modules
: [modules])
: modules || settings.modules;
modifyExisting = modifyExisting !== undefined
? modifyExisting
: true;
$.each(modules, function (index, name) {
var
namespace = module.moduleExists(name)
? $.fn[name].settings.namespace || false
: true,
$existingModules
;
if (module.moduleExists(name)) {
module.verbose('Changing default setting', setting, value, name);
$.fn[name].settings[setting] = value;
if (modifyExisting && namespace) {
$existingModules = $(':data(module-' + namespace + ')');
if ($existingModules.length > 0) {
module.verbose('Modifying existing settings', $existingModules);
$existingModules[name]('setting', setting, value);
}
}
}
});
},
settings: function (newSettings, modules, modifyExisting) {
modules = typeof modules === 'string'
? [modules]
: modules || settings.modules;
modifyExisting = modifyExisting !== undefined
? modifyExisting
: true;
$.each(modules, function (index, name) {
var
$existingModules
;
if (module.moduleExists(name)) {
module.verbose('Changing default setting', newSettings, name);
$.extend(true, $.fn[name].settings, newSettings);
if (modifyExisting && namespace) {
$existingModules = $(':data(module-' + namespace + ')');
if ($existingModules.length > 0) {
module.verbose('Modifying existing settings', $existingModules);
$existingModules[name]('setting', newSettings);
}
}
}
});
},
},
enable: {
console: function () {
module.console(true);
},
debug: function (modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Enabling debug for modules', modules);
module.change.setting('debug', true, modules, modifyExisting);
},
verbose: function (modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Enabling verbose debug for modules', modules);
module.change.setting('verbose', true, modules, modifyExisting);
},
},
disable: {
console: function () {
module.console(false);
},
debug: function (modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Disabling debug for modules', modules);
module.change.setting('debug', false, modules, modifyExisting);
},
verbose: function (modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Disabling verbose debug for modules', modules);
module.change.setting('verbose', false, modules, modifyExisting);
},
},
console: function (enable) {
if (enable) {
if (instance.cache.console === undefined) {
module.error(error.console);
return;
}
module.debug('Restoring console function');
window.console = instance.cache.console;
} else {
module.debug('Disabling console function');
instance.cache.console = window.console;
window.console = {
clear: function () {},
error: function () {},
group: function () {},
groupCollapsed: function () {},
groupEnd: function () {},
info: function () {},
log: function () {},
table: function () {},
warn: function () {},
};
}
},
destroy: function () {
module.verbose('Destroying previous site for', $module);
$module
.removeData(moduleNamespace)
;
},
cache: {},
setting: function (name, value) {
if ($.isPlainObject(name)) {
$.extend(true, settings, name);
} else if (value !== undefined) {
settings[name] = value;
} else {
return settings[name];
}
},
internal: function (name, value) {
if ($.isPlainObject(name)) {
$.extend(true, module, name);
} else if (value !== undefined) {
module[name] = value;
} else {
return module[name];
}
},
debug: function () {
if (settings.debug) {
if (settings.performance) {
module.performance.log(arguments);
} else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function () {
if (settings.verbose && settings.debug) {
if (settings.performance) {
module.performance.log(arguments);
} else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function () {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function (message) {
var
currentTime,
executionTime,
previousTime
;
if (settings.performance) {
currentTime = Date.now();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
Element: element,
Name: message[0],
Arguments: [].slice.call(message, 1) || '',
'Execution Time': executionTime,
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(function () {
module.performance.display();
}, 500);
},
display: function () {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function (index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if (performance.length > 0) {
console.groupCollapsed(title);
if (console.table) {
console.table(performance);
} else {
$.each(performance, function (index, data) {
console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
});
}
console.groupEnd();
}
performance = [];
},
},
invoke: function (query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = context || element;
if (typeof query === 'string' && object !== undefined) {
query = query.split(/[ .]/);
maxDepth = query.length - 1;
$.each(query, function (depth, value) {
var camelCaseValue = depth !== maxDepth
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
object = object[camelCaseValue];
} else if (object[camelCaseValue] !== undefined) {
found = object[camelCaseValue];
return false;
} else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
object = object[value];
} else if (object[value] !== undefined) {
found = object[value];
return false;
} else {
module.error(error.method, query);
return false;
}
});
}
if (isFunction(found)) {
response = found.apply(context, passedArguments);
} else if (found !== undefined) {
response = found;
}
if (Array.isArray(returnedValue)) {
returnedValue.push(response);
} else if (returnedValue !== undefined) {
returnedValue = [returnedValue, response];
} else if (response !== undefined) {
returnedValue = response;
}
return found;
},
};
if (methodInvoked) {
if (instance === undefined) {
module.initialize();
}
module.invoke(query);
} else {
if (instance !== undefined) {
module.destroy();
}
module.initialize();
}
return returnedValue !== undefined
? returnedValue
: this;
};
$.site = $.fn.site;
$.site.settings = {
name: 'Site',
namespace: 'site',
error: {
console: 'Console cannot be restored, most likely it was overwritten outside of module',
method: 'The method you called is not defined.',
},
debug: false,
verbose: false,
performance: true,
modules: [
'accordion',
'api',
'calendar',
'checkbox',
'dimmer',
'dropdown',
'embed',
'flyout',
'form',
'modal',
'nag',
'popup',
'progress',
'rating',
'search',
'shape',
'sidebar',
'slider',
'state',
'sticky',
'tab',
'toast',
'transition',
'visibility',
],
siteNamespace: 'site',
namespaceStub: {
cache: {},
config: {},
sections: {},
section: {},
utilities: {},
},
};
// allows for selection of elements with data attributes
$.extend($.expr.pseudos, {
data: $.expr.createPseudo(function (dataName) {
return function (elem) {
return !!$.data(elem, dataName);
};
}),
});
})(jQuery, window, document);
/*!
* # Fomantic-UI 2.9.4 - Form Validation
* https://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* https://opensource.org/licenses/MIT
*
*/
(function ($, window, document) {
'use strict';
function isFunction(obj) {
return typeof obj === 'function' && typeof obj.nodeType !== 'number';
}
window = window !== undefined && window.Math === Math
? window
: globalThis;
$.fn.form = function (parameters) {
var
$allModules = $(this),
$window = $(window),
time = Date.now(),
performance = [],
query = arguments[0],
methodInvoked = typeof query === 'string',
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules.each(function () {
var
$module = $(this),
element = this,
formErrors = [],
formErrorsTracker = {},
keyHeldDown = false,
// set at run-time
$field,
$group,
$message,
$prompt,
$submit,
$clear,
$reset,
settings,
validation,
metadata,
selector,
className,
regExp,
error,
namespace,
moduleNamespace,
eventNamespace,
attachEventsSelector,
attachEventsAction,
submitting = false,
dirty = false,
history = ['clean', 'clean'],
instance,
module
;
module = {
initialize: function () {
// settings grabbed at run time
module.get.settings();
$module.addClass(className.initial);
if (methodInvoked) {
if (instance === undefined) {
module.instantiate();
}
module.invoke(query);
} else {
if (instance !== undefined) {
instance.invoke('destroy');
module.refresh();
}
module.verbose('Initializing form validation', $module, settings);
module.bindEvents();
module.set.defaults();
if (settings.autoCheckRequired) {
module.set.autoCheck();
}
module.instantiate();
}
},
instantiate: function () {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function () {
module.verbose('Destroying previous module', instance);
module.removeEvents();
$module
.removeData(moduleNamespace)
;
},
refresh: function () {
module.verbose('Refreshing selector cache');
$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);
},
refreshEvents: function () {
module.removeEvents();
module.bindEvents();
},
submit: function (event) {
module.verbose('Submitting form', $module);
submitting = true;
$module.trigger('submit');
if (event) {
event.preventDefault();
}
},
attachEvents: function (selector, action) {
if (!action) {
action = 'submit';
}
$(selector).on('click' + eventNamespace, function (event) {
module[action]();
event.preventDefault();
});
attachEventsSelector = selector;
attachEventsAction = action;
},
bindEvents: function () {
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('invalid' + eventNamespace, module.event.field.invalid);
if (settings.keyboardShortcuts) {
$module.on('keydown' + eventNamespace, selector.field, module.event.field.keydown);
}
$field.each(function (index, el) {
var
$input = $(el),
type = $input.prop('type'),
inputEvent = module.get.changeEvent(type, $input)
;
$input.on(inputEvent + eventNamespace, module.event.field.change);
});
// Dirty events
if (settings.preventLeaving) {
$window.on('beforeunload' + eventNamespace, module.event.beforeUnload);
}
$field.on('change' + eventNamespace
+ ' click' + eventNamespace
+ ' keyup' + eventNamespace
+ ' keydown' + eventNamespace
+ ' blur' + eventNamespace, function (e) {
module.determine.isDirty();
});
$module.on('dirty' + eventNamespace, function (e) {
settings.onDirty.call();
});
$module.on('clean' + eventNamespace, function (e) {
settings.onClean.call();
});
if (attachEventsSelector) {
module.attachEvents(attachEventsSelector, attachEventsAction);
}
},
clear: function () {
$field.each(function (index, el) {
var
$field = $(el),
$element = $field.parent(),
$fieldGroup = $field.closest($group),
$prompt = $fieldGroup.find(selector.prompt),
$calendar = $field.closest(selector.uiCalendar),
defaultValue = $field.data(metadata.defaultValue) || '',
isCheckbox = $field.is(selector.checkbox),
isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
isCalendar = $calendar.length > 0 && module.can.useElement('calendar'),
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', true);
} else if (isCheckbox) {
$field.prop('checked', false);
} else if (isCalendar) {
$calendar.calendar('clear');
} else {
module.verbose('Resetting field value', $field, defaultValue);
$field.val('');
}
});
module.remove.states();
},
reset: function () {
$field.each(function (index, el) {
var
$field = $(el),
$element = $field.parent(),
$fieldGroup = $field.closest($group),
$calendar = $field.closest(selector.uiCalendar),
$prompt = $fieldGroup.find(selector.prompt),
defaultValue = $field.data(metadata.defaultValue),
isCheckbox = $field.is(selector.checkbox),
isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
isCalendar = $calendar.length > 0 && module.can.useElement('calendar'),
isFile = $field.is(selector.file),
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', true);
} else if (isCheckbox) {
module.verbose('Resetting checkbox value', $field, defaultValue);
$field.prop('checked', defaultValue);
} else if (isCalendar) {
$calendar.calendar('set date', defaultValue);
} else {
module.verbose('Resetting field value', $field, defaultValue);
$field.val(isFile ? '' : defaultValue);
}
});
module.remove.states();
},
determine: {
isValid: function () {
var
allValid = true
;
$field.each(function (index, el) {
var $el = $(el),
validation = module.get.validation($el) || {},
identifier = module.get.identifier(validation, $el)
;
if (!module.validate.field(validation, identifier, true)) {
allValid = false;
}
});
return allValid;
},
isDirty: function (e) {
var formIsDirty = false;
$field.each(function (index, el) {
var
$el = $(el),
isCheckbox = $el.filter(selector.checkbox).length > 0,
isDirty
;
isDirty = isCheckbox
? module.is.checkboxDirty($el)
: module.is.fieldDirty($el);
$el.data(settings.metadata.isDirty, isDirty);
formIsDirty = formIsDirty || isDirty;
});
if (formIsDirty) {
module.set.dirty();
} else {
module.set.clean();
}
},
},
is: {
bracketedRule: function (rule) {
return rule.type && rule.type.match(settings.regExp.bracket);
},
// duck type rule test
shorthandRules: function (rules) {
return typeof rules === 'string' || Array.isArray(rules);
},
empty: function ($field) {
if (!$field || $field.length === 0) {
return true;
}
if ($field.is(selector.checkbox)) {
return !$field.is(':checked');
}
return module.is.blank($field);
},
blank: function ($field) {
return String($field.val()).trim() === '';
},
valid: function (field, showErrors) {
var
allValid = true
;
if (field) {
module.verbose('Checking if field is valid', field);
return module.validate.field(validation[field], field, !!showErrors);
}
module.verbose('Checking if form is valid');
$.each(validation, function (fieldName, field) {
if (!module.is.valid(fieldName, showErrors)) {
allValid = false;
}
});
return allValid;
},
dirty: function () {
return dirty;
},
clean: function () {
return !dirty;
},
fieldDirty: function ($el) {
var initialValue = $el.data(metadata.defaultValue);
// Explicitly check for undefined/null here as value may be `false`, so ($el.data(dataInitialValue) || '') would not work
if (initialValue === undefined || initialValue === null) {
initialValue = '';
} else if (Array.isArray(initialValue)) {
initialValue = initialValue.toString();
}
var currentValue = $el.val();
if (currentValue === undefined || currentValue === null) {
currentValue = '';
} else if (Array.isArray(currentValue)) {
// multiple select values are returned as arrays which are never equal, so do string conversion first
currentValue = currentValue.toString();
}
// Boolean values can be encoded as "true/false" or "True/False" depending on underlying frameworks so we need a case insensitive comparison
var boolRegex = /^(true|false)$/i;
var isBoolValue = boolRegex.test(initialValue) && boolRegex.test(currentValue);
if (isBoolValue) {
var regex = new RegExp('^' + initialValue + '$', 'i');
return !regex.test(currentValue);
}
return currentValue !== initialValue;
},
checkboxDirty: function ($el) {
var initialValue = $el.data(metadata.defaultValue);
var currentValue = $el.is(':checked');
return initialValue !== currentValue;
},
justDirty: function () {
return history[0] === 'dirty';
},
justClean: function () {
return history[0] === 'clean';
},
},
removeEvents: function () {
$module.off(eventNamespace);
$field.off(eventNamespace);
$submit.off(eventNamespace);
if (settings.preventLeaving) {
$window.off(eventNamespace);
}
if (attachEventsSelector) {
$(attachEventsSelector).off(eventNamespace);
attachEventsSelector = undefined;
}
},
event: {
field: {
keydown: function (event) {
var
$field = $(this),
key = event.which,
isInput = $field.is(selector.input),
isCheckbox = $field.is(selector.checkbox),
isInDropdown = $field.closest(selector.uiDropdown).length > 0,
keyCode = {
enter: 13,
escape: 27,
}
;
if (key === keyCode.escape) {
module.verbose('Escape key pressed blurring field');
$field[0]
.blur()
;
}
if (!event.ctrlKey && key === keyCode.enter && isInput && !isInDropdown && !isCheckbox) {
if (!keyHeldDown) {
$field.one('keyup' + eventNamespace, module.event.field.keyup);
module.submit(event);
module.debug('Enter pressed on input submitting form');
}
keyHeldDown = true;
}
},
keyup: function () {
keyHeldDown = false;
},
invalid: function (event) {
event.preventDefault();
},
blur: function (event) {
var
$field = $(this),
validationRules = module.get.validation($field) || {},
identifier = module.get.identifier(validationRules, $field)
;
if (settings.on === 'blur' || (!$module.hasClass(className.initial) && settings.revalidate)) {
module.debug('Revalidating field', $field, validationRules);
module.validate.field(validationRules, identifier);
if (!settings.inline) {
module.validate.form(false, true);
}
}
},
change: function (event) {
var
$field = $(this),
validationRules = module.get.validation($field) || {},
identifier = module.get.identifier(validationRules, $field)
;
if (settings.on === 'change' || (!$module.hasClass(className.initial) && settings.revalidate)) {
clearTimeout(module.timer);
module.timer = setTimeout(function () {
module.debug('Revalidating field', $field, validationRules);
module.validate.field(validationRules, identifier);
if (!settings.inline) {
module.validate.form(false, true);
}
}, settings.delay);
}
},
},
beforeUnload: function (event) {
if (module.is.dirty() && !submitting) {
event = event || window.event;
// For modern browsers
if (event) {
event.returnValue = settings.text.leavingMessage;
}
// For olders...
return settings.text.leavingMessage;
}
},
},
get: {
ancillaryValue: function (rule) {
if (!rule.type || (!rule.value && !module.is.bracketedRule(rule))) {
return false;
}
return rule.value !== undefined
? rule.value
: 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) {
return ['file', 'checkbox', 'radio', 'hidden'].indexOf(type) >= 0 || $input.is('select') ? 'change' : 'input';
},
fieldsFromShorthand: function (fields) {
var
fullFields = {}
;
$.each(fields, function (name, rules) {
if (!Array.isArray(rules) && typeof rules === 'object') {
fullFields[name] = rules;
} else {
if (typeof rules === 'string') {
rules = [rules];
}
fullFields[name] = {
rules: [],
};
$.each(rules, function (index, rule) {
fullFields[name].rules.push({ type: rule });
});
}
$.each(fullFields[name].rules, function (index, rule) {
var ruleName = module.get.ruleName(rule);
if (ruleName === 'empty') {
module.warn('*** DEPRECATED *** : Rule "empty" for field "' + name + '" will be removed in a future version. -> Use "notEmpty" rule instead.');
}
});
});
return fullFields;
},
identifier: function (validation, $el) {
return validation.identifier || $el.attr('id') || $el.attr('name') || $el.data(metadata.validate);
},
prompt: function (rule, field) {
var
ruleName = module.get.ruleName(rule),
ancillary = module.get.ancillaryValue(rule),
$field = module.get.field(field.identifier),
value = $field.val(),
promptCheck = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
prompt = String(isFunction(promptCheck)
? promptCheck.call($field[0], value)
: promptCheck),
requiresValue = prompt.search('{value}') !== -1,
requiresName = prompt.search('{name}') !== -1,
parts,
suffixPrompt
;
if (ancillary && ['integer', 'decimal', 'number', 'size'].indexOf(ruleName) >= 0 && ancillary.indexOf('..') >= 0) {
parts = ancillary.split('..', 2);
if (!rule.prompt && ruleName !== 'size') {
suffixPrompt = parts[0] === ''
? settings.prompt.maxValue.replace(/{ruleValue}/g, '{max}')
: (parts[1] === ''
? settings.prompt.minValue.replace(/{ruleValue}/g, '{min}')
: settings.prompt.range);
prompt += suffixPrompt.replace(/{name}/g, ' ' + settings.text.and);
}
prompt = prompt.replace(/{min}/g, parts[0]);
prompt = prompt.replace(/{max}/g, parts[1]);
}
if (ancillary && ['match', 'different'].indexOf(ruleName) >= 0) {
prompt = prompt.replace(/{ruleValue}/g, module.get.fieldLabel(ancillary, true));
}
if (requiresValue) {
prompt = prompt.replace(/{value}/g, $field.val());
}
if (requiresName) {
prompt = prompt.replace(/{name}/g, module.get.fieldLabel($field));
}
prompt = prompt.replace(/{identifier}/g, field.identifier);
prompt = prompt.replace(/{ruleValue}/g, ancillary);
if (!rule.prompt) {
module.verbose('Using default validation prompt for type', prompt, ruleName);
}
return prompt;
},
settings: function () {
if ($.isPlainObject(parameters)) {
settings = $.extend(true, {}, $.fn.form.settings, parameters);
if (settings.fields) {
settings.fields = module.get.fieldsFromShorthand(settings.fields);
}
validation = $.extend(true, {}, $.fn.form.settings.defaults, settings.fields);
module.verbose('Extending settings', validation, settings);
} else {
settings = $.extend(true, {}, $.fn.form.settings);
validation = $.extend(true, {}, $.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;
regExp = settings.regExp;
error = settings.error;
moduleNamespace = 'module-' + namespace;
eventNamespace = '.' + namespace;
// grab instance
instance = $module.data(moduleNamespace);
// refresh selector cache
(instance || module).refresh();
},
field: function (identifier, strict, ignoreMissing) {
module.verbose('Finding field with identifier', identifier);
identifier = module.escape.string(identifier);
var t;
t = $field.filter('#' + identifier);
if (t.length > 0) {
return t;
}
t = $field.filter('[name="' + identifier + '"]');
if (t.length > 0) {
return t;
}
t = $field.filter('[name="' + identifier + '[]"]');
if (t.length > 0) {
return t;
}
t = $field.filter('[data-' + metadata.validate + '="' + identifier + '"]');
if (t.length > 0) {
return t;
}
if (!ignoreMissing) {
module.error(error.noField.replace('{identifier}', identifier));
}
return strict ? $() : $('<input/>');
},
fields: function (fields, strict) {
var
$fields = $()
;
$.each(fields, function (index, name) {
$fields = $fields.add(module.get.field(name, strict));
});
return $fields;
},
fieldLabel: function (identifier, useIdAsFallback) {
var $field = typeof identifier === 'string'
? module.get.field(identifier)
: identifier,
$label = $field.closest(selector.group).find('label:not(:empty)').eq(0)
;
return $label.length === 1
? $label.text()
: $field.prop('placeholder') || (useIdAsFallback ? identifier : settings.text.unspecifiedField);
},
validation: function ($field) {
var
fieldValidation,
identifier
;
if (!validation) {
return false;
}
$.each(validation, function (fieldName, field) {
identifier = field.identifier || fieldName;
$.each(module.get.field(identifier), function (index, groupField) {
if (groupField == $field[0]) {
field.identifier = identifier;
fieldValidation = field;
return false;
}
});
});
return fieldValidation || false;
},
value: function (field, strict) {
var
fields = [],
results,
resultKeys
;
fields.push(field);
results = module.get.values.call(element, fields, strict);
resultKeys = Object.keys(results);
return resultKeys.length > 0 ? results[resultKey