nette-forms
Advanced tools
Comparing version 3.3.6 to 3.4.0
{ | ||
"name": "nette-forms", | ||
"version": "3.3.6", | ||
"description": "Client side script for Nette Forms Component", | ||
"keywords": [ | ||
"nette", | ||
"validation", | ||
"forms" | ||
], | ||
"homepage": "https://nette.org", | ||
"author": "David Grudl (https://davidgrudl.com)", | ||
"license": "BSD-3-Clause", | ||
"main": "src/assets/netteForms.js", | ||
"files": [ | ||
"src/assets" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/nette/forms.git" | ||
} | ||
"name": "nette-forms", | ||
"version": "3.4.0", | ||
"description": "Client side script for Nette Forms Component", | ||
"keywords": [ | ||
"nette", | ||
"validation", | ||
"forms" | ||
], | ||
"homepage": "https://nette.org", | ||
"author": "David Grudl (https://davidgrudl.com)", | ||
"license": "BSD-3-Clause", | ||
"main": "src/assets/netteForms.js", | ||
"files": [ | ||
"src/assets" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/nette/forms.git" | ||
}, | ||
"devDependencies": { | ||
"@eslint/js": "^9.1.1", | ||
"eslint": "^9.1.1", | ||
"globals": "^15.1.0" | ||
} | ||
} |
@@ -8,3 +8,8 @@ /**! | ||
(function(global, factory) { | ||
/** | ||
* @typedef {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement|HTMLButtonElement} FormElement | ||
* @typedef {{op: string, neg: boolean, msg: string, arg: *, rules: ?Array<Rule>, control: string, toggle: ?Array<string>}} Rule | ||
*/ | ||
(function (global, factory) { | ||
if (!global.JSON) { | ||
@@ -15,9 +20,7 @@ return; | ||
if (typeof define === 'function' && define.amd) { | ||
define(function() { | ||
return factory(global); | ||
}); | ||
define(() => factory(global)); | ||
} else if (typeof module === 'object' && typeof module.exports === 'object') { | ||
module.exports = factory(global); | ||
} else { | ||
var init = !global.Nette || !global.Nette.noInit; | ||
let init = !global.Nette?.noInit; | ||
global.Nette = factory(global); | ||
@@ -29,21 +32,40 @@ if (init) { | ||
}(typeof window !== 'undefined' ? window : this, function(window) { | ||
}(typeof window !== 'undefined' ? window : this, (window) => { | ||
'use strict'; | ||
var Nette = {}; | ||
var preventFiltering = {}; | ||
var formToggles = {}; | ||
var toggleListeners = new window.WeakMap(); | ||
const Nette = {}; | ||
let preventFiltering = {}; | ||
let formToggles = {}; | ||
let toggleListeners = new window.WeakMap(); | ||
Nette.formErrors = []; | ||
Nette.version = '3.3.0'; | ||
Nette.invalidNumberMessage = 'Please enter a valid value.'; | ||
/** | ||
* @param {HTMLFormElement} form | ||
* @param {string} name | ||
* @return {?FormElement} | ||
*/ | ||
function getFormElement(form, name) { | ||
let res = form.elements.namedItem(name); | ||
return res instanceof RadioNodeList ? res[0] : res; | ||
} | ||
/** | ||
* @param {FormElement} elem | ||
* @return {Array<FormElement>} | ||
*/ | ||
function expandRadioElement(elem) { | ||
let res = elem.form.elements.namedItem(elem.name); | ||
return res instanceof RadioNodeList ? Array.from(res) : [res]; | ||
} | ||
/** | ||
* Function to execute when the DOM is fully loaded. | ||
* @private | ||
*/ | ||
Nette.onDocumentReady = function(callback) { | ||
Nette.onDocumentReady = function (callback) { | ||
if (document.readyState !== 'loading') { | ||
@@ -59,58 +81,39 @@ callback.call(this); | ||
* Returns the value of form element. | ||
* @param {FormElement|RadioNodeList} elem | ||
* @return {*} | ||
*/ | ||
Nette.getValue = function(elem) { | ||
var i; | ||
if (!elem) { | ||
return null; | ||
Nette.getValue = function (elem) { | ||
if (elem instanceof HTMLInputElement) { | ||
if (elem.type === 'radio') { | ||
return expandRadioElement(elem) | ||
.find((input) => input.checked) | ||
?.value ?? null; | ||
} else if (!elem.tagName) { // RadioNodeList, HTMLCollection, array | ||
return elem[0] ? Nette.getValue(elem[0]) : null; | ||
} else if (elem.type === 'file') { | ||
return elem.files; | ||
} else if (elem.type === 'radio') { | ||
var elements = elem.form.elements; // prevents problem with name 'item' or 'namedItem' | ||
for (i = 0; i < elements.length; i++) { | ||
if (elements[i].name === elem.name && elements[i].checked) { | ||
return elements[i].value; | ||
} | ||
} | ||
return null; | ||
} else if (elem.type === 'checkbox') { | ||
return elem.name.endsWith('[]') // checkbox list | ||
? expandRadioElement(elem) | ||
.filter((input) => input.checked) | ||
.map((input) => input.value) | ||
: elem.checked; | ||
} else if (elem.type === 'file') { | ||
return elem.files || elem.value; | ||
} else if (elem.tagName.toLowerCase() === 'select') { | ||
var index = elem.selectedIndex, | ||
options = elem.options, | ||
values = []; | ||
if (elem.type === 'select-one') { | ||
return index < 0 ? null : options[index].value; | ||
} else { | ||
return elem.value.trim(); | ||
} | ||
for (i = 0; i < options.length; i++) { | ||
if (options[i].selected) { | ||
values.push(options[i].value); | ||
} | ||
} | ||
return values; | ||
} else if (elem instanceof HTMLSelectElement) { | ||
return elem.multiple | ||
? Array.from(elem.selectedOptions, (option) => option.value) | ||
: elem.selectedOptions[0]?.value ?? null; | ||
} else if (elem.name && elem.name.substr(-2) === '[]') { // multiple elements [] | ||
elements = elem.form.elements[elem.name].tagName ? [elem] : elem.form.elements[elem.name]; | ||
values = []; | ||
} else if (elem instanceof HTMLTextAreaElement) { | ||
return elem.value; | ||
for (i = 0; i < elements.length; i++) { | ||
if (elements[i].type !== 'checkbox' || elements[i].checked) { | ||
values.push(elements[i].value); | ||
} | ||
} | ||
return values; | ||
} else if (elem instanceof RadioNodeList) { | ||
return Nette.getValue(elem[0]); | ||
} else if (elem.type === 'checkbox') { | ||
return elem.checked; | ||
} else if (elem.tagName.toLowerCase() === 'textarea') { | ||
return elem.value.replace('\r', ''); | ||
} else { | ||
return elem.value.replace('\r', '').replace(/^\s+|\s+$/g, ''); | ||
return null; | ||
} | ||
@@ -122,13 +125,14 @@ }; | ||
* Returns the effective value of form element. | ||
* @param {FormElement} elem | ||
* @param {boolean} filter | ||
* @return {*} | ||
*/ | ||
Nette.getEffectiveValue = function(elem, filter) { | ||
var val = Nette.getValue(elem); | ||
if (elem.getAttribute) { | ||
if (val === elem.getAttribute('data-nette-empty-value')) { | ||
val = ''; | ||
} | ||
Nette.getEffectiveValue = function (elem, filter = false) { | ||
let val = Nette.getValue(elem); | ||
if (val === elem.getAttribute('data-nette-empty-value')) { | ||
val = ''; | ||
} | ||
if (filter && preventFiltering[elem.name] === undefined) { | ||
preventFiltering[elem.name] = true; | ||
var ref = {value: val}; | ||
let ref = {value: val}; | ||
Nette.validateControl(elem, null, true, ref); | ||
@@ -144,13 +148,17 @@ val = ref.value; | ||
* Validates form element against given rules. | ||
* @param {FormElement} elem | ||
* @param {?Array<Rule>} rules | ||
* @param {boolean} onlyCheck | ||
* @param {?{value: *}} value | ||
* @param {?boolean} emptyOptional | ||
* @return {boolean} | ||
*/ | ||
Nette.validateControl = function(elem, rules, onlyCheck, value, emptyOptional) { | ||
elem = elem.tagName ? elem : elem[0]; // RadioNodeList | ||
rules = rules || JSON.parse(elem.getAttribute('data-nette-rules') || '[]'); | ||
value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value; | ||
emptyOptional = emptyOptional === undefined ? !Nette.validateRule(elem, ':filled', null, value) : emptyOptional; | ||
Nette.validateControl = function (elem, rules, onlyCheck = false, value = null, emptyOptional = null) { | ||
rules ??= JSON.parse(elem.getAttribute('data-nette-rules') ?? '[]'); | ||
value ??= {value: Nette.getEffectiveValue(elem)}; | ||
emptyOptional ??= !Nette.validateRule(elem, ':filled', null, value); | ||
for (var id = 0, len = rules.length; id < len; id++) { | ||
var rule = rules[id], | ||
op = rule.op.match(/(~)?([^?]+)/), | ||
curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem; | ||
for (let rule of rules) { | ||
let op = rule.op.match(/(~)?([^?]+)/), | ||
curElem = rule.control ? getFormElement(elem.form, rule.control) : elem; | ||
@@ -167,5 +175,3 @@ rule.neg = op[1]; | ||
curElem = curElem.tagName ? curElem : curElem[0]; // RadioNodeList | ||
var success = Nette.validateRule(curElem, rule.op, rule.arg, elem === curElem ? value : undefined); | ||
let success = Nette.validateRule(curElem, rule.op, rule.arg, elem === curElem ? value : undefined); | ||
if (success === null) { | ||
@@ -186,6 +192,7 @@ continue; | ||
if (!onlyCheck) { | ||
var arr = Array.isArray(rule.arg) ? rule.arg : [rule.arg], | ||
message = rule.msg.replace(/%(value|\d+)/g, function(foo, m) { | ||
return Nette.getValue(m === 'value' ? curElem : elem.form.elements.namedItem(arr[m].control)); | ||
}); | ||
let arr = Array.isArray(rule.arg) ? rule.arg : [rule.arg], | ||
message = rule.msg.replace( | ||
/%(value|\d+)/g, | ||
(foo, m) => Nette.getValue(m === 'value' ? curElem : elem.form.elements.namedItem(arr[m].control)) | ||
); | ||
Nette.addError(curElem, message); | ||
@@ -203,6 +210,9 @@ } | ||
* Validates whole form. | ||
* @param {HTMLFormElement} sender | ||
* @param {boolean} onlyCheck | ||
* @return {boolean} | ||
*/ | ||
Nette.validateForm = function(sender, onlyCheck) { | ||
var form = sender.form || sender, | ||
scope = false; | ||
Nette.validateForm = function (sender, onlyCheck = false) { | ||
let form = sender.form ?? sender, | ||
scope; | ||
@@ -212,3 +222,3 @@ Nette.formErrors = []; | ||
if (form['nette-submittedBy'] && form['nette-submittedBy'].getAttribute('formnovalidate') !== null) { | ||
var scopeArr = JSON.parse(form['nette-submittedBy'].getAttribute('data-nette-validation-scope') || '[]'); | ||
let scopeArr = JSON.parse(form['nette-submittedBy'].getAttribute('data-nette-validation-scope') ?? '[]'); | ||
if (scopeArr.length) { | ||
@@ -222,29 +232,16 @@ scope = new RegExp('^(' + scopeArr.join('-|') + '-)'); | ||
var radios = {}, i, elem; | ||
for (i = 0; i < form.elements.length; i++) { | ||
elem = form.elements[i]; | ||
if (elem.tagName && !(elem.tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1})) { | ||
continue; | ||
} else if (elem.type === 'radio') { | ||
if (radios[elem.name]) { | ||
continue; | ||
} | ||
radios[elem.name] = true; | ||
} else if (elem.type === 'number' && elem.validity.badInput && !Nette.isDisabled(elem)) { | ||
if (onlyCheck) { | ||
return false; | ||
} | ||
Nette.addError(elem, Nette.invalidNumberMessage); | ||
continue; | ||
for (let elem of form.elements) { | ||
if (elem.willValidate && elem.validity.badInput) { | ||
elem.reportValidity(); | ||
return false; | ||
} | ||
} | ||
if ((scope && !elem.name.replace(/]\[|\[|]|$/g, '-').match(scope)) || Nette.isDisabled(elem)) { | ||
continue; | ||
} | ||
if (!Nette.validateControl(elem, null, onlyCheck) && !Nette.formErrors.length) { | ||
for (let elem of Array.from(form.elements)) { | ||
if (elem.getAttribute('data-nette-rules') | ||
&& (!scope || elem.name.replace(/]\[|\[|]|$/g, '-').match(scope)) | ||
&& !Nette.isDisabled(elem) | ||
&& !Nette.validateControl(elem, null, onlyCheck) | ||
&& !Nette.formErrors.length | ||
) { | ||
return false; | ||
@@ -254,3 +251,3 @@ } | ||
var success = !Nette.formErrors.length; | ||
let success = !Nette.formErrors.length; | ||
Nette.showFormErrors(form, Nette.formErrors); | ||
@@ -263,11 +260,9 @@ return success; | ||
* Check if input is disabled. | ||
* @param {FormElement} elem | ||
* @return {boolean} | ||
*/ | ||
Nette.isDisabled = function(elem) { | ||
Nette.isDisabled = function (elem) { | ||
if (elem.type === 'radio') { | ||
for (var i = 0, elements = elem.form.elements; i < elements.length; i++) { | ||
if (elements[i].name === elem.name && !elements[i].disabled) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return expandRadioElement(elem) | ||
.every((input) => input.disabled); | ||
} | ||
@@ -280,4 +275,6 @@ return elem.disabled; | ||
* Adds error message to the queue. | ||
* @param {FormElement} elem | ||
* @param {string} message | ||
*/ | ||
Nette.addError = function(elem, message) { | ||
Nette.addError = function (elem, message) { | ||
Nette.formErrors.push({ | ||
@@ -292,16 +289,15 @@ element: elem, | ||
* Display error messages. | ||
* @param {HTMLFormElement} form | ||
* @param {Array<{element: FormElement, message: string}>} errors | ||
*/ | ||
Nette.showFormErrors = function(form, errors) { | ||
var messages = [], | ||
Nette.showFormErrors = function (form, errors) { | ||
let messages = [], | ||
focusElem; | ||
for (var i = 0; i < errors.length; i++) { | ||
var elem = errors[i].element, | ||
message = errors[i].message; | ||
for (let error of errors) { | ||
if (messages.indexOf(error.message) < 0) { | ||
messages.push(error.message); | ||
if (messages.indexOf(message) < 0) { | ||
messages.push(message); | ||
if (!focusElem && elem.focus) { | ||
focusElem = elem; | ||
if (!focusElem && error.element.focus) { | ||
focusElem = error.element; | ||
} | ||
@@ -312,3 +308,3 @@ } | ||
if (messages.length) { | ||
Nette.showModal(messages.join('\n'), function () { | ||
Nette.showModal(messages.join('\n'), () => { | ||
if (focusElem) { | ||
@@ -324,5 +320,7 @@ focusElem.focus(); | ||
* Display modal window. | ||
* @param {string} message | ||
* @param {function} onclose | ||
*/ | ||
Nette.showModal = function(message, onclose) { | ||
var dialog = document.createElement('dialog'); | ||
Nette.showModal = function (message, onclose) { | ||
let dialog = document.createElement('dialog'); | ||
@@ -335,8 +333,8 @@ if (!dialog.showModal) { | ||
var style = document.createElement('style'); | ||
let style = document.createElement('style'); | ||
style.innerText = '.netteFormsModal { text-align: center; margin: auto; border: 2px solid black; padding: 1rem } .netteFormsModal button { padding: .1em 2em }'; | ||
var button = document.createElement('button'); | ||
let button = document.createElement('button'); | ||
button.innerText = 'OK'; | ||
button.onclick = function () { | ||
button.onclick = () => { | ||
dialog.remove(); | ||
@@ -356,26 +354,28 @@ onclose(); | ||
* Validates single rule. | ||
* @param {FormElement} elem | ||
* @param {string} op | ||
* @param {*} arg | ||
* @param {?{value: *}} value | ||
*/ | ||
Nette.validateRule = function(elem, op, arg, value) { | ||
if (elem.type === 'number' && elem.validity.badInput) { | ||
return op === 'filled'; | ||
Nette.validateRule = function (elem, op, arg, value) { | ||
if (elem.validity.badInput) { | ||
return op === ':filled'; | ||
} | ||
value = value === undefined ? {value: Nette.getEffectiveValue(elem, true)} : value; | ||
value ??= {value: Nette.getEffectiveValue(elem, true)}; | ||
if (op.charAt(0) === ':') { | ||
op = op.substr(1); | ||
} | ||
op = op.replace('::', '_'); | ||
op = op.replace(/\\/g, ''); | ||
let method = op.charAt(0) === ':' ? op.substring(1) : op; | ||
method = method.replace('::', '_').replaceAll('\\', ''); | ||
var arr = Array.isArray(arg) ? arg.slice(0) : [arg]; | ||
for (var i = 0, len = arr.length; i < len; i++) { | ||
if (arr[i] && arr[i].control) { | ||
var control = elem.form.elements.namedItem(arr[i].control); | ||
arr[i] = control === elem ? value.value : Nette.getEffectiveValue(control, true); | ||
let args = Array.isArray(arg) ? arg : [arg]; | ||
args = args.map((arg) => { | ||
if (arg?.control) { | ||
let control = getFormElement(elem.form, arg.control); | ||
return control === elem ? value.value : Nette.getEffectiveValue(control, true); | ||
} | ||
} | ||
return arg; | ||
}); | ||
return Nette.validators[op] | ||
? Nette.validators[op](elem, Array.isArray(arg) ? arr : arr[0], value.value, value) | ||
return Nette.validators[method] | ||
? Nette.validators[method](elem, Array.isArray(arg) ? args : args[0], value.value, value) | ||
: null; | ||
@@ -386,3 +386,3 @@ }; | ||
Nette.validators = { | ||
filled: function(elem, arg, val) { | ||
filled: function (elem, arg, val) { | ||
return val !== '' && val !== false && val !== null | ||
@@ -393,11 +393,11 @@ && (!Array.isArray(val) || !!val.length) | ||
blank: function(elem, arg, val) { | ||
blank: function (elem, arg, val) { | ||
return !Nette.validators.filled(elem, arg, val); | ||
}, | ||
valid: function(elem) { | ||
valid: function (elem) { | ||
return Nette.validateControl(elem, null, true); | ||
}, | ||
equal: function(elem, arg, val) { | ||
equal: function (elem, arg, val) { | ||
if (arg === undefined) { | ||
@@ -407,3 +407,3 @@ return null; | ||
var toString = function(val) { | ||
let toString = (val) => { | ||
if (typeof val === 'number' || typeof val === 'string') { | ||
@@ -419,5 +419,5 @@ return '' + val; | ||
loop: | ||
for (var i1 = 0, len1 = val.length; i1 < len1; i1++) { | ||
for (var i2 = 0, len2 = arg.length; i2 < len2; i2++) { | ||
if (toString(val[i1]) === toString(arg[i2])) { | ||
for (let a of val) { | ||
for (let b of arg) { | ||
if (toString(a) === toString(b)) { | ||
continue loop; | ||
@@ -431,15 +431,18 @@ } | ||
notEqual: function(elem, arg, val) { | ||
notEqual: function (elem, arg, val) { | ||
return arg === undefined ? null : !Nette.validators.equal(elem, arg, val); | ||
}, | ||
minLength: function(elem, arg, val) { | ||
minLength: function (elem, arg, val) { | ||
val = typeof val === 'number' ? val.toString() : val; | ||
return val.length >= arg; | ||
}, | ||
maxLength: function(elem, arg, val) { | ||
maxLength: function (elem, arg, val) { | ||
val = typeof val === 'number' ? val.toString() : val; | ||
return val.length <= arg; | ||
}, | ||
length: function(elem, arg, val) { | ||
length: function (elem, arg, val) { | ||
val = typeof val === 'number' ? val.toString() : val; | ||
arg = Array.isArray(arg) ? arg : [arg, arg]; | ||
@@ -449,7 +452,7 @@ return (arg[0] === null || val.length >= arg[0]) && (arg[1] === null || val.length <= arg[1]); | ||
email: function(elem, arg, val) { | ||
email: function (elem, arg, val) { | ||
return (/^("([ !#-[\]-~]|\\[ -~])+"|[-a-z0-9!#$%&'*+/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*)@([0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)+[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?$/i).test(val); | ||
}, | ||
url: function(elem, arg, val, value) { | ||
url: function (elem, arg, val, newValue) { | ||
if (!(/^[a-z\d+.-]+:/).test(val)) { | ||
@@ -459,3 +462,3 @@ val = 'https://' + val; | ||
if ((/^https?:\/\/((([-_0-9a-z\u00C0-\u02FF\u0370-\u1EFF]+\.)*[0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)?[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-f:]{3,39}\])(:\d{1,5})?(\/\S*)?$/i).test(val)) { | ||
value.value = val; | ||
newValue.value = val; | ||
return true; | ||
@@ -466,10 +469,10 @@ } | ||
regexp: function(elem, arg, val) { | ||
var parts = typeof arg === 'string' ? arg.match(/^\/(.*)\/([imu]*)$/) : false; | ||
regexp: function (elem, arg, val) { | ||
let parts = typeof arg === 'string' ? arg.match(/^\/(.*)\/([imu]*)$/) : false; | ||
try { | ||
return parts && (new RegExp(parts[1], parts[2].replace('u', ''))).test(val); | ||
} catch (e) {} // eslint-disable-line no-empty | ||
} catch {} // eslint-disable-line no-empty | ||
}, | ||
pattern: function(elem, arg, val, value, caseInsensitive) { | ||
pattern: function (elem, arg, val, newValue, caseInsensitive) { | ||
if (typeof arg !== 'string') { | ||
@@ -480,33 +483,26 @@ return null; | ||
try { | ||
let regExp; | ||
try { | ||
var regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'ui' : 'u'); | ||
} catch (e) { | ||
regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'ui' : 'u'); | ||
} catch { | ||
regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'i' : ''); | ||
} | ||
if (val instanceof FileList) { | ||
for (var i = 0; i < val.length; i++) { | ||
if (!regExp.test(val[i].name)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return regExp.test(val); | ||
} catch (e) {} // eslint-disable-line no-empty | ||
return val instanceof FileList | ||
? Array.from(val).every((file) => regExp.test(file.name)) | ||
: regExp.test(val); | ||
} catch {} // eslint-disable-line no-empty | ||
}, | ||
patternCaseInsensitive: function(elem, arg, val) { | ||
patternCaseInsensitive: function (elem, arg, val) { | ||
return Nette.validators.pattern(elem, arg, val, null, true); | ||
}, | ||
numeric: function(elem, arg, val) { | ||
numeric: function (elem, arg, val) { | ||
return (/^[0-9]+$/).test(val); | ||
}, | ||
integer: function(elem, arg, val, value) { | ||
integer: function (elem, arg, val, newValue) { | ||
if ((/^-?[0-9]+$/).test(val)) { | ||
value.value = parseFloat(val); | ||
newValue.value = parseFloat(val); | ||
return true; | ||
@@ -517,6 +513,6 @@ } | ||
'float': function(elem, arg, val, value) { | ||
'float': function (elem, arg, val, newValue) { | ||
val = val.replace(/ +/g, '').replace(/,/g, '.'); | ||
if ((/^-?[0-9]*\.?[0-9]+$/).test(val)) { | ||
value.value = parseFloat(val); | ||
newValue.value = parseFloat(val); | ||
return true; | ||
@@ -527,3 +523,3 @@ } | ||
min: function(elem, arg, val) { | ||
min: function (elem, arg, val) { | ||
if (Number.isFinite(arg)) { | ||
@@ -535,3 +531,3 @@ val = parseFloat(val); | ||
max: function(elem, arg, val) { | ||
max: function (elem, arg, val) { | ||
if (Number.isFinite(arg)) { | ||
@@ -543,3 +539,3 @@ val = parseFloat(val); | ||
range: function(elem, arg, val) { | ||
range: function (elem, arg, val) { | ||
if (!Array.isArray(arg)) { | ||
@@ -554,36 +550,20 @@ return null; | ||
submitted: function(elem) { | ||
submitted: function (elem) { | ||
return elem.form['nette-submittedBy'] === elem; | ||
}, | ||
fileSize: function(elem, arg, val) { | ||
for (var i = 0; i < val.length; i++) { | ||
if (val[i].size > arg) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
fileSize: function (elem, arg, val) { | ||
return Array.from(val).every((file) => file.size <= arg); | ||
}, | ||
mimeType: function (elem, arg, val) { | ||
arg = Array.isArray(arg) ? arg : [arg]; | ||
for (var i = 0, len = arg.length, re = []; i < len; i++) { | ||
re.push('^' + arg[i].replace(/([^\w])/g, '\\$1').replace('\\*', '.*') + '$'); | ||
} | ||
mimeType: function (elem, args, val) { | ||
let re = []; | ||
args = Array.isArray(args) ? args : [args]; | ||
args.forEach((arg) => re.push('^' + arg.replace(/([^\w])/g, '\\$1').replace('\\*', '.*') + '$')); | ||
re = new RegExp(re.join('|')); | ||
if (val instanceof FileList) { | ||
for (i = 0; i < val.length; i++) { | ||
if (val[i].type && !re.test(val[i].type)) { | ||
return false; | ||
} else if (elem.validity.badInput) { | ||
return null; | ||
} | ||
} | ||
} | ||
return true; | ||
return Array.from(val).every((file) => !file.type || re.test(file.type)); | ||
}, | ||
image: function (elem, arg, val) { | ||
return Nette.validators.mimeType(elem, arg || ['image/gif', 'image/png', 'image/jpeg', 'image/webp'], val); | ||
return Nette.validators.mimeType(elem, arg ?? ['image/gif', 'image/png', 'image/jpeg', 'image/webp'], val); | ||
}, | ||
@@ -599,13 +579,14 @@ | ||
* Process all toggles in form. | ||
* @param {HTMLFormElement} form | ||
* @param {?Event} event | ||
*/ | ||
Nette.toggleForm = function(form, event) { | ||
var i; | ||
Nette.toggleForm = function (form, event = null) { | ||
formToggles = {}; | ||
for (i = 0; i < form.elements.length; i++) { | ||
if (form.elements[i].tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1}) { | ||
Nette.toggleControl(form.elements[i], null, null, !event); | ||
for (let elem of Array.from(form.elements)) { | ||
if (elem.getAttribute('data-nette-rules')) { | ||
Nette.toggleControl(elem, null, null, !event); | ||
} | ||
} | ||
for (i in formToggles) { | ||
for (let i in formToggles) { | ||
Nette.toggle(i, formToggles[i].state, formToggles[i].elem, event); | ||
@@ -618,18 +599,21 @@ } | ||
* Process toggles on form element. | ||
* @param {FormElement} elem | ||
* @param {?Array<Rule>} rules | ||
* @param {?boolean} success | ||
* @param {boolean} firsttime | ||
* @param {?{value: *}} value | ||
* @param {?boolean} emptyOptional | ||
* @return {boolean} | ||
*/ | ||
Nette.toggleControl = function(elem, rules, success, firsttime, value, emptyOptional) { | ||
rules = rules || JSON.parse(elem.getAttribute('data-nette-rules') || '[]'); | ||
value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value; | ||
emptyOptional = emptyOptional === undefined ? !Nette.validateRule(elem, ':filled', null, value) : emptyOptional; | ||
Nette.toggleControl = function (elem, rules, success, firsttime, value = null, emptyOptional = null) { | ||
rules ??= JSON.parse(elem.getAttribute('data-nette-rules') ?? '[]'); | ||
value ??= {value: Nette.getEffectiveValue(elem)}; | ||
emptyOptional ??= !Nette.validateRule(elem, ':filled', null, value); | ||
var has = false, | ||
handler = function (e) { | ||
Nette.toggleForm(elem.form, e); | ||
}, | ||
let has = false, | ||
curSuccess; | ||
for (var id = 0, len = rules.length; id < len; id++) { | ||
var rule = rules[id], | ||
op = rule.op.match(/(~)?([^?]+)/), | ||
curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem; | ||
for (let rule of rules) { | ||
let op = rule.op.match(/(~)?([^?]+)/), | ||
curElem = rule.control ? getFormElement(elem.form, rule.control) : elem; | ||
@@ -663,15 +647,11 @@ rule.neg = op[1]; | ||
if (firsttime) { | ||
var name = curElem.tagName ? curElem.name : curElem[0].name, | ||
els = curElem.tagName ? curElem.form.elements : curElem; | ||
for (var i = 0; i < els.length; i++) { | ||
if (els[i].name === name && !toggleListeners.has(els[i])) { | ||
els[i].addEventListener('change', handler); | ||
toggleListeners.set(els[i], null); | ||
} | ||
} | ||
expandRadioElement(curElem) | ||
.filter((el) => !toggleListeners.has(el)) | ||
.forEach((el) => { | ||
el.addEventListener('change', (e) => Nette.toggleForm(elem.form, e)); | ||
toggleListeners.set(el, null); | ||
}); | ||
} | ||
for (var toggleId in rule.toggle || []) { | ||
formToggles[toggleId] = formToggles[toggleId] || {elem: elem}; | ||
formToggles[toggleId].state = formToggles[toggleId].state || (rule.toggle[toggleId] ? curSuccess : !curSuccess); | ||
for (let id in rule.toggle ?? []) { | ||
formToggles[id] ??= {elem: elem, state: rule.toggle[id] ? curSuccess : !curSuccess}; | ||
} | ||
@@ -686,11 +666,13 @@ } | ||
* Displays or hides HTML element. | ||
* @param {string} selector | ||
* @param {boolean} visible | ||
* @param {FormElement} srcElement | ||
* @param {Event} event | ||
*/ | ||
Nette.toggle = function(selector, visible, srcElement, event) { // eslint-disable-line no-unused-vars | ||
Nette.toggle = function (selector, visible, srcElement, event) { // eslint-disable-line no-unused-vars | ||
if (/^\w[\w.:-]*$/.test(selector)) { // id | ||
selector = '#' + selector; | ||
} | ||
var elems = document.querySelectorAll(selector); | ||
for (var i = 0; i < elems.length; i++) { | ||
elems[i].hidden = !visible; | ||
} | ||
Array.from(document.querySelectorAll(selector)) | ||
.forEach((elem) => elem.hidden = !visible); | ||
}; | ||
@@ -701,38 +683,18 @@ | ||
* Compact checkboxes | ||
* @param {HTMLFormElement} form | ||
* @param {FormData} formData | ||
*/ | ||
Nette.compactCheckboxes = function(form) { | ||
var name, i, elem, values = {}; | ||
Nette.compactCheckboxes = function (form, formData) { | ||
let values = {}; | ||
for (i = 0; i < form.elements.length; i++) { | ||
elem = form.elements[i]; | ||
if (elem.tagName | ||
&& elem.tagName.toLowerCase() === 'input' | ||
&& elem.type === 'checkbox' | ||
) { | ||
if (elem.name | ||
&& elem.name.substr(-2) === '[]' | ||
) { | ||
name = elem.name.substr(0, elem.name.length - 2); | ||
elem.removeAttribute('name'); | ||
elem.setAttribute('data-nette-name', name); | ||
} | ||
if (name = elem.getAttribute('data-nette-name')) { // eslint-disable-line no-cond-assign | ||
values[name] = values[name] || []; | ||
if (elem.checked && !elem.disabled) { | ||
values[name].push(elem.value); | ||
} | ||
} | ||
for (let elem of form.elements) { | ||
if (elem instanceof HTMLInputElement && elem.type === 'checkbox' && elem.name.endsWith('[]') && elem.checked && !elem.disabled) { | ||
formData.delete(elem.name); | ||
values[elem.name] ??= []; | ||
values[elem.name].push(elem.value); | ||
} | ||
} | ||
for (name in values) { | ||
if (form.elements[name] === undefined) { | ||
elem = document.createElement('input'); | ||
elem.setAttribute('name', name); | ||
elem.setAttribute('type', 'hidden'); | ||
form.append(elem); | ||
} | ||
form.elements[name].value = values[name].join(','); | ||
form.elements[name].disabled = values[name].length === 0; | ||
for (let name in values) { | ||
formData.set(name.substring(0, name.length - 2), values[name].join(',')); | ||
} | ||
@@ -744,16 +706,10 @@ }; | ||
* Setup handlers. | ||
* @param {HTMLFormElement} form | ||
*/ | ||
Nette.initForm = function(form) { | ||
Nette.initForm = function (form) { | ||
if (form.method === 'get' && form.hasAttribute('data-nette-compact')) { | ||
form.addEventListener('submit', function() { | ||
Nette.compactCheckboxes(form); | ||
}); | ||
form.addEventListener('formdata', (e) => Nette.compactCheckboxes(form, e.formData)); | ||
} | ||
check: { | ||
for (var i = 0; i < form.elements.length; i++) { | ||
if (form.elements[i].getAttribute('data-nette-rules')) { | ||
break check; | ||
} | ||
} | ||
if (!Array.from(form.elements).some((elem) => elem.getAttribute('data-nette-rules'))) { | ||
return; | ||
@@ -769,3 +725,3 @@ } | ||
form.addEventListener('submit', function(e) { | ||
form.addEventListener('submit', (e) => { | ||
if (!Nette.validateForm(form)) { | ||
@@ -777,6 +733,4 @@ e.stopPropagation(); | ||
form.addEventListener('reset', function() { | ||
setTimeout(function() { | ||
Nette.toggleForm(form); | ||
}); | ||
form.addEventListener('reset', () => { | ||
setTimeout(() => Nette.toggleForm(form)); | ||
}); | ||
@@ -789,10 +743,9 @@ }; | ||
*/ | ||
Nette.initOnLoad = function() { | ||
Nette.onDocumentReady(function() { | ||
for (var i = 0; i < document.forms.length; i++) { | ||
Nette.initForm(document.forms[i]); | ||
} | ||
Nette.initOnLoad = function () { | ||
Nette.onDocumentReady(() => { | ||
Array.from(document.forms) | ||
.forEach((form) => Nette.initForm(form)); | ||
document.body.addEventListener('click', function(e) { | ||
var target = e.target; | ||
document.body.addEventListener('click', (e) => { | ||
let target = e.target; | ||
while (target) { | ||
@@ -812,7 +765,9 @@ if (target.form && target.type in {submit: 1, image: 1}) { | ||
* Converts string to web safe characters [a-z0-9-] text. | ||
* @param {string} s | ||
* @return {string} | ||
*/ | ||
Nette.webalize = function(s) { | ||
Nette.webalize = function (s) { | ||
s = s.toLowerCase(); | ||
var res = '', i, ch; | ||
for (i = 0; i < s.length; i++) { | ||
let res = '', ch; | ||
for (let i = 0; i < s.length; i++) { | ||
ch = Nette.webalizeTable[s.charAt(i)]; | ||
@@ -819,0 +774,0 @@ res += ch ? ch : s.charAt(i); |
@@ -1,22 +0,7 @@ | ||
(function(p,e){if(p.JSON)if("function"===typeof define&&define.amd)define(function(){return e(p)});else if("object"===typeof module&&"object"===typeof module.exports)module.exports=e(p);else{var u=!p.Nette||!p.Nette.noInit;p.Nette=e(p);u&&p.Nette.initOnLoad()}})("undefined"!==typeof window?window:this,function(p){var e={},u={},r={},x=new p.WeakMap;e.formErrors=[];e.version="3.3.0";e.invalidNumberMessage="Please enter a valid value.";e.onDocumentReady=function(a){"loading"!==document.readyState?a.call(this): | ||
document.addEventListener("DOMContentLoaded",a)};e.getValue=function(a){var b;if(a){if(a.tagName){if("radio"===a.type){var c=a.form.elements;for(b=0;b<c.length;b++)if(c[b].name===a.name&&c[b].checked)return c[b].value;return null}if("file"===a.type)return a.files||a.value;if("select"===a.tagName.toLowerCase()){b=a.selectedIndex;c=a.options;var d=[];if("select-one"===a.type)return 0>b?null:c[b].value;for(b=0;b<c.length;b++)c[b].selected&&d.push(c[b].value);return d}if(a.name&&"[]"===a.name.substr(-2)){c= | ||
a.form.elements[a.name].tagName?[a]:a.form.elements[a.name];d=[];for(b=0;b<c.length;b++)("checkbox"!==c[b].type||c[b].checked)&&d.push(c[b].value);return d}return"checkbox"===a.type?a.checked:"textarea"===a.tagName.toLowerCase()?a.value.replace("\r",""):a.value.replace("\r","").replace(/^\s+|\s+$/g,"")}return a[0]?e.getValue(a[0]):null}return null};e.getEffectiveValue=function(a,b){var c=e.getValue(a);a.getAttribute&&c===a.getAttribute("data-nette-empty-value")&&(c="");b&&void 0===u[a.name]&&(u[a.name]= | ||
!0,b={value:c},e.validateControl(a,null,!0,b),c=b.value,delete u[a.name]);return c};e.validateControl=function(a,b,c,d,f){a=a.tagName?a:a[0];b=b||JSON.parse(a.getAttribute("data-nette-rules")||"[]");d=void 0===d?{value:e.getEffectiveValue(a)}:d;f=void 0===f?!e.validateRule(a,":filled",null,d):f;for(var g=0,q=b.length;g<q;g++){var h=b[g],k=h.op.match(/(~)?([^?]+)/),n=h.control?a.form.elements.namedItem(h.control):a;h.neg=k[1];h.op=k[2];h.condition=!!h.rules;if(n&&(!f||h.condition||":filled"===h.op)&& | ||
(n=n.tagName?n:n[0],k=e.validateRule(n,h.op,h.arg,a===n?d:void 0),null!==k))if(h.neg&&(k=!k),h.condition&&k){if(!e.validateControl(a,h.rules,c,d,":blank"===h.op?!1:f))return!1}else if(!h.condition&&!k&&!e.isDisabled(n)){if(!c){var w=Array.isArray(h.arg)?h.arg:[h.arg];b=h.msg.replace(/%(value|\d+)/g,function(l,m){return e.getValue("value"===m?n:a.form.elements.namedItem(w[m].control))});e.addError(n,b)}return!1}}return!0};e.validateForm=function(a,b){a=a.form||a;var c=!1;e.formErrors=[];if(a["nette-submittedBy"]&& | ||
null!==a["nette-submittedBy"].getAttribute("formnovalidate"))if(c=JSON.parse(a["nette-submittedBy"].getAttribute("data-nette-validation-scope")||"[]"),c.length)c=new RegExp("^("+c.join("-|")+"-)");else return e.showFormErrors(a,[]),!0;var d={},f;for(f=0;f<a.elements.length;f++){var g=a.elements[f];if(!g.tagName||g.tagName.toLowerCase()in{input:1,select:1,textarea:1,button:1}){if("radio"===g.type){if(d[g.name])continue;d[g.name]=!0}else if("number"===g.type&&g.validity.badInput&&!e.isDisabled(g)){if(b)return!1; | ||
e.addError(g,e.invalidNumberMessage);continue}if(!(c&&!g.name.replace(/]\[|\[|]|$/g,"-").match(c)||e.isDisabled(g)||e.validateControl(g,null,b)||e.formErrors.length))return!1}}b=!e.formErrors.length;e.showFormErrors(a,e.formErrors);return b};e.isDisabled=function(a){if("radio"===a.type){for(var b=0,c=a.form.elements;b<c.length;b++)if(c[b].name===a.name&&!c[b].disabled)return!1;return!0}return a.disabled};e.addError=function(a,b){e.formErrors.push({element:a,message:b})};e.showFormErrors=function(a, | ||
b){a=[];for(var c,d=0;d<b.length;d++){var f=b[d].element,g=b[d].message;0>a.indexOf(g)&&(a.push(g),!c&&f.focus&&(c=f))}a.length&&e.showModal(a.join("\n"),function(){c&&c.focus()})};e.showModal=function(a,b){var c=document.createElement("dialog");if(c.showModal){var d=document.createElement("style");d.innerText=".netteFormsModal { text-align: center; margin: auto; border: 2px solid black; padding: 1rem } .netteFormsModal button { padding: .1em 2em }";var f=document.createElement("button");f.innerText= | ||
"OK";f.onclick=function(){c.remove();b()};c.setAttribute("class","netteFormsModal");c.innerText=a+"\n\n";c.append(d,f);document.body.append(c);c.showModal()}else alert(a),b()};e.validateRule=function(a,b,c,d){if("number"===a.type&&a.validity.badInput)return"filled"===b;d=void 0===d?{value:e.getEffectiveValue(a,!0)}:d;":"===b.charAt(0)&&(b=b.substr(1));b=b.replace("::","_");b=b.replace(/\\/g,"");for(var f=Array.isArray(c)?c.slice(0):[c],g=0,q=f.length;g<q;g++)if(f[g]&&f[g].control){var h=a.form.elements.namedItem(f[g].control); | ||
f[g]=h===a?d.value:e.getEffectiveValue(h,!0)}return e.validators[b]?e.validators[b](a,Array.isArray(c)?f:f[0],d.value,d):null};e.validators={filled:function(a,b,c){return""!==c&&!1!==c&&null!==c&&(!Array.isArray(c)||!!c.length)&&(!(c instanceof FileList)||c.length)},blank:function(a,b,c){return!e.validators.filled(a,b,c)},valid:function(a){return e.validateControl(a,null,!0)},equal:function(a,b,c){if(void 0===b)return null;a=function(h){return"number"===typeof h||"string"===typeof h?""+h:!0===h?"1": | ||
""};c=Array.isArray(c)?c:[c];b=Array.isArray(b)?b:[b];var d=0,f=c.length;a:for(;d<f;d++){for(var g=0,q=b.length;g<q;g++)if(a(c[d])===a(b[g]))continue a;return!1}return 0<c.length},notEqual:function(a,b,c){return void 0===b?null:!e.validators.equal(a,b,c)},minLength:function(a,b,c){return c.length>=b},maxLength:function(a,b,c){return c.length<=b},length:function(a,b,c){b=Array.isArray(b)?b:[b,b];return(null===b[0]||c.length>=b[0])&&(null===b[1]||c.length<=b[1])},email:function(a,b,c){return/^("([ !#-[\]-~]|\\[ -~])+"|[-a-z0-9!#$%&'*+/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*)@([0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)+[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?$/i.test(c)}, | ||
url:function(a,b,c,d){/^[a-z\d+.-]+:/.test(c)||(c="https://"+c);return/^https?:\/\/((([-_0-9a-z\u00C0-\u02FF\u0370-\u1EFF]+\.)*[0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)?[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-f:]{3,39}\])(:\d{1,5})?(\/\S*)?$/i.test(c)?(d.value=c,!0):!1},regexp:function(a,b,c){a="string"===typeof b?b.match(/^\/(.*)\/([imu]*)$/): | ||
!1;try{return a&&(new RegExp(a[1],a[2].replace("u",""))).test(c)}catch(d){}},pattern:function(a,b,c,d,f){if("string"!==typeof b)return null;try{try{var g=new RegExp("^(?:"+b+")$",f?"ui":"u")}catch(q){g=new RegExp("^(?:"+b+")$",f?"i":"")}if(c instanceof FileList){for(a=0;a<c.length;a++)if(!g.test(c[a].name))return!1;return!0}return g.test(c)}catch(q){}},patternCaseInsensitive:function(a,b,c){return e.validators.pattern(a,b,c,null,!0)},numeric:function(a,b,c){return/^[0-9]+$/.test(c)},integer:function(a, | ||
b,c,d){return/^-?[0-9]+$/.test(c)?(d.value=parseFloat(c),!0):!1},"float":function(a,b,c,d){c=c.replace(/ +/g,"").replace(/,/g,".");return/^-?[0-9]*\.?[0-9]+$/.test(c)?(d.value=parseFloat(c),!0):!1},min:function(a,b,c){Number.isFinite(b)&&(c=parseFloat(c));return c>=b},max:function(a,b,c){Number.isFinite(b)&&(c=parseFloat(c));return c<=b},range:function(a,b,c){return Array.isArray(b)?"time"===a.type&&b[0]>b[1]?c>=b[0]||c<=b[1]:(null===b[0]||e.validators.min(a,b[0],c))&&(null===b[1]||e.validators.max(a, | ||
b[1],c)):null},submitted:function(a){return a.form["nette-submittedBy"]===a},fileSize:function(a,b,c){for(a=0;a<c.length;a++)if(c[a].size>b)return!1;return!0},mimeType:function(a,b,c){b=Array.isArray(b)?b:[b];for(var d=0,f=b.length,g=[];d<f;d++)g.push("^"+b[d].replace(/([^\w])/g,"\\$1").replace("\\*",".*")+"$");g=new RegExp(g.join("|"));if(c instanceof FileList)for(d=0;d<c.length;d++){if(c[d].type&&!g.test(c[d].type))return!1;if(a.validity.badInput)return null}return!0},image:function(a,b,c){return e.validators.mimeType(a, | ||
b||["image/gif","image/png","image/jpeg","image/webp"],c)},"static":function(a,b){return b}};e.toggleForm=function(a,b){var c;r={};for(c=0;c<a.elements.length;c++)a.elements[c].tagName.toLowerCase()in{input:1,select:1,textarea:1,button:1}&&e.toggleControl(a.elements[c],null,null,!b);for(c in r)e.toggle(c,r[c].state,r[c].elem,b)};e.toggleControl=function(a,b,c,d,f,g){b=b||JSON.parse(a.getAttribute("data-nette-rules")||"[]");f=void 0===f?{value:e.getEffectiveValue(a)}:f;g=void 0===g?!e.validateRule(a, | ||
":filled",null,f):g;for(var q=!1,h=function(y){e.toggleForm(a.form,y)},k,n=0,w=b.length;n<w;n++){var l=b[n];k=l.op.match(/(~)?([^?]+)/);var m=l.control?a.form.elements.namedItem(l.control):a;l.neg=k[1];l.op=k[2];l.condition=!!l.rules;if(m&&(!g||l.condition||":filled"===l.op)){k=c;if(!1!==c){k=e.validateRule(m,l.op,l.arg,a===m?f:void 0);if(null===k)continue;else l.neg&&(k=!k);l.condition||(c=k)}if(l.condition&&e.toggleControl(a,l.rules,k,d,f,":blank"===l.op?!1:g)||l.toggle){q=!0;if(d){var z=m.tagName? | ||
m.name:m[0].name;m=m.tagName?m.form.elements:m;for(var t=0;t<m.length;t++)m[t].name!==z||x.has(m[t])||(m[t].addEventListener("change",h),x.set(m[t],null))}for(var v in l.toggle||[])r[v]=r[v]||{elem:a},r[v].state=r[v].state||(l.toggle[v]?k:!k)}}}return q};e.toggle=function(a,b,c,d){/^\w[\w.:-]*$/.test(a)&&(a="#"+a);a=document.querySelectorAll(a);for(c=0;c<a.length;c++)a[c].hidden=!b};e.compactCheckboxes=function(a){var b,c={};for(b=0;b<a.elements.length;b++){var d=a.elements[b];if(d.tagName&&"input"=== | ||
d.tagName.toLowerCase()&&"checkbox"===d.type){if(d.name&&"[]"===d.name.substr(-2)){var f=d.name.substr(0,d.name.length-2);d.removeAttribute("name");d.setAttribute("data-nette-name",f)}if(f=d.getAttribute("data-nette-name"))c[f]=c[f]||[],d.checked&&!d.disabled&&c[f].push(d.value)}}for(f in c)void 0===a.elements[f]&&(d=document.createElement("input"),d.setAttribute("name",f),d.setAttribute("type","hidden"),a.append(d)),a.elements[f].value=c[f].join(","),a.elements[f].disabled=0===c[f].length};e.initForm= | ||
function(a){"get"===a.method&&a.hasAttribute("data-nette-compact")&&a.addEventListener("submit",function(){e.compactCheckboxes(a)});a:{for(var b=0;b<a.elements.length;b++)if(a.elements[b].getAttribute("data-nette-rules"))break a;return}e.toggleForm(a);a.noValidate||(a.noValidate=!0,a.addEventListener("submit",function(c){e.validateForm(a)||(c.stopPropagation(),c.preventDefault())}),a.addEventListener("reset",function(){setTimeout(function(){e.toggleForm(a)})}))};e.initOnLoad=function(){e.onDocumentReady(function(){for(var a= | ||
0;a<document.forms.length;a++)e.initForm(document.forms[a]);document.body.addEventListener("click",function(b){for(b=b.target;b;){if(b.form&&b.type in{submit:1,image:1}){b.form["nette-submittedBy"]=b;break}b=b.parentNode}})})};e.webalize=function(a){a=a.toLowerCase();var b="",c;for(c=0;c<a.length;c++){var d=e.webalizeTable[a.charAt(c)];b+=d?d:a.charAt(c)}return b.replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")};e.webalizeTable={"\u00e1":"a","\u00e4":"a","\u010d":"c","\u010f":"d","\u00e9":"e","\u011b":"e", | ||
"\u00ed":"i","\u013e":"l","\u0148":"n","\u00f3":"o","\u00f4":"o","\u0159":"r","\u0161":"s","\u0165":"t","\u00fa":"u","\u016f":"u","\u00fd":"y","\u017e":"z"};return e}); | ||
"use strict"; | ||
/**! | ||
* NetteForms - simple form validation. | ||
* | ||
* This file is part of the Nette Framework (https://nette.org) | ||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com) | ||
*/!function(e,t){if(e.JSON)if("function"==typeof define&&define.amd)define((()=>t(e)));else if("object"==typeof module&&"object"==typeof module.exports)module.exports=t(e);else{var n;let r=!(null!==(n=e.Nette)&&void 0!==n&&n.noInit);e.Nette=t(e),r&&e.Nette.initOnLoad()}}("undefined"!=typeof window?window:void 0,(e=>{const t={};let n={},r={},o=new e.WeakMap;function l(e,t){let n=e.elements.namedItem(t);return n instanceof RadioNodeList?n[0]:n}function a(e){let t=e.form.elements.namedItem(e.name);return t instanceof RadioNodeList?Array.from(t):[t]}return t.formErrors=[],t.version="3.3.0",t.onDocumentReady=function(e){"loading"!==document.readyState?e.call(this):document.addEventListener("DOMContentLoaded",e)},t.getValue=function(e){var n,r;return e instanceof HTMLInputElement?"radio"===e.type?(null===(n=a(e).find((e=>e.checked)))||void 0===n?void 0:n.value)??null:"file"===e.type?e.files:"checkbox"===e.type?e.name.endsWith("[]")?a(e).filter((e=>e.checked)).map((e=>e.value)):e.checked:e.value.trim():e instanceof HTMLSelectElement?e.multiple?Array.from(e.selectedOptions,(e=>e.value)):(null===(r=e.selectedOptions[0])||void 0===r?void 0:r.value)??null:e instanceof HTMLTextAreaElement?e.value:e instanceof RadioNodeList?t.getValue(e[0]):null},t.getEffectiveValue=function(e,r=!1){let o=t.getValue(e);if(o===e.getAttribute("data-nette-empty-value")&&(o=""),r&&void 0===n[e.name]){n[e.name]=!0;let r={value:o};t.validateControl(e,null,!0,r),o=r.value,delete n[e.name]}return o},t.validateControl=function(e,n,r=!1,o=null,a=null){n??=JSON.parse(e.getAttribute("data-nette-rules")??"[]"),o??={value:t.getEffectiveValue(e)},a??=!t.validateRule(e,":filled",null,o);for(let i of n){let n=i.op.match(/(~)?([^?]+)/),u=i.control?l(e.form,i.control):e;if(i.neg=n[1],i.op=n[2],i.condition=!!i.rules,!u)continue;if(a&&!i.condition&&":filled"!==i.op)continue;let f=t.validateRule(u,i.op,i.arg,e===u?o:void 0);if(null!==f)if(i.neg&&(f=!f),i.condition&&f){if(!t.validateControl(e,i.rules,r,o,":blank"!==i.op&&a))return!1}else if(!i.condition&&!f){if(t.isDisabled(u))continue;if(!r){let n=Array.isArray(i.arg)?i.arg:[i.arg],r=i.msg.replace(/%(value|\d+)/g,((r,o)=>t.getValue("value"===o?u:e.form.elements.namedItem(n[o].control))));t.addError(u,r)}return!1}}return!0},t.validateForm=function(e,n=!1){let r,o=e.form??e;if(t.formErrors=[],o["nette-submittedBy"]&&null!==o["nette-submittedBy"].getAttribute("formnovalidate")){let e=JSON.parse(o["nette-submittedBy"].getAttribute("data-nette-validation-scope")??"[]");if(!e.length)return t.showFormErrors(o,[]),!0;r=new RegExp("^("+e.join("-|")+"-)")}for(let e of o.elements)if(e.willValidate&&e.validity.badInput)return e.reportValidity(),!1;for(let e of Array.from(o.elements))if(e.getAttribute("data-nette-rules")&&(!r||e.name.replace(/]\[|\[|]|$/g,"-").match(r))&&!t.isDisabled(e)&&!t.validateControl(e,null,n)&&!t.formErrors.length)return!1;let l=!t.formErrors.length;return t.showFormErrors(o,t.formErrors),l},t.isDisabled=function(e){return"radio"===e.type?a(e).every((e=>e.disabled)):e.disabled},t.addError=function(e,n){t.formErrors.push({element:e,message:n})},t.showFormErrors=function(e,n){let r,o=[];for(let e of n)o.indexOf(e.message)<0&&(o.push(e.message),!r&&e.element.focus&&(r=e.element));o.length&&t.showModal(o.join("\n"),(()=>{r&&r.focus()}))},t.showModal=function(e,t){let n=document.createElement("dialog");if(!n.showModal)return alert(e),void t();let r=document.createElement("style");r.innerText=".netteFormsModal { text-align: center; margin: auto; border: 2px solid black; padding: 1rem } .netteFormsModal button { padding: .1em 2em }";let o=document.createElement("button");o.innerText="OK",o.onclick=()=>{n.remove(),t()},n.setAttribute("class","netteFormsModal"),n.innerText=e+"\n\n",n.append(r,o),document.body.append(n),n.showModal()},t.validateRule=function(e,n,r,o){if(e.validity.badInput)return":filled"===n;o??={value:t.getEffectiveValue(e,!0)};let a=":"===n.charAt(0)?n.substring(1):n;a=a.replace("::","_").replaceAll("\\","");let i=Array.isArray(r)?r:[r];return i=i.map((n=>{if(null!=n&&n.control){let r=l(e.form,n.control);return r===e?o.value:t.getEffectiveValue(r,!0)}return n})),t.validators[a]?t.validators[a](e,Array.isArray(r)?i:i[0],o.value,o):null},t.validators={filled:function(e,t,n){return""!==n&&!1!==n&&null!==n&&(!Array.isArray(n)||!!n.length)&&(!(n instanceof FileList)||n.length)},blank:function(e,n,r){return!t.validators.filled(e,n,r)},valid:function(e){return t.validateControl(e,null,!0)},equal:function(e,t,n){if(void 0===t)return null;let r=e=>"number"==typeof e||"string"==typeof e?""+e:!0===e?"1":"";n=Array.isArray(n)?n:[n],t=Array.isArray(t)?t:[t];e:for(let e of n){for(let n of t)if(r(e)===r(n))continue e;return!1}return n.length>0},notEqual:function(e,n,r){return void 0===n?null:!t.validators.equal(e,n,r)},minLength:function(e,t,n){return(n="number"==typeof n?n.toString():n).length>=t},maxLength:function(e,t,n){return(n="number"==typeof n?n.toString():n).length<=t},length:function(e,t,n){return n="number"==typeof n?n.toString():n,(null===(t=Array.isArray(t)?t:[t,t])[0]||n.length>=t[0])&&(null===t[1]||n.length<=t[1])},email:function(e,t,n){return/^("([ !#-[\]-~]|\\[ -~])+"|[-a-z0-9!#$%&'*+/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*)@([0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)+[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?$/i.test(n)},url:function(e,t,n,r){return/^[a-z\d+.-]+:/.test(n)||(n="https://"+n),!!/^https?:\/\/((([-_0-9a-z\u00C0-\u02FF\u0370-\u1EFF]+\.)*[0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)?[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-f:]{3,39}\])(:\d{1,5})?(\/\S*)?$/i.test(n)&&(r.value=n,!0)},regexp:function(e,t,n){let r="string"==typeof t&&t.match(/^\/(.*)\/([imu]*)$/);try{return r&&new RegExp(r[1],r[2].replace("u","")).test(n)}catch{}},pattern:function(e,t,n,r,o){if("string"!=typeof t)return null;try{let e;try{e=new RegExp("^(?:"+t+")$",o?"ui":"u")}catch{e=new RegExp("^(?:"+t+")$",o?"i":"")}return n instanceof FileList?Array.from(n).every((t=>e.test(t.name))):e.test(n)}catch{}},patternCaseInsensitive:function(e,n,r){return t.validators.pattern(e,n,r,null,!0)},numeric:function(e,t,n){return/^[0-9]+$/.test(n)},integer:function(e,t,n,r){return!!/^-?[0-9]+$/.test(n)&&(r.value=parseFloat(n),!0)},float:function(e,t,n,r){return n=n.replace(/ +/g,"").replace(/,/g,"."),!!/^-?[0-9]*\.?[0-9]+$/.test(n)&&(r.value=parseFloat(n),!0)},min:function(e,t,n){return Number.isFinite(t)&&(n=parseFloat(n)),n>=t},max:function(e,t,n){return Number.isFinite(t)&&(n=parseFloat(n)),n<=t},range:function(e,n,r){return Array.isArray(n)?"time"===e.type&&n[0]>n[1]?r>=n[0]||r<=n[1]:(null===n[0]||t.validators.min(e,n[0],r))&&(null===n[1]||t.validators.max(e,n[1],r)):null},submitted:function(e){return e.form["nette-submittedBy"]===e},fileSize:function(e,t,n){return Array.from(n).every((e=>e.size<=t))},mimeType:function(e,t,n){let r=[];return(t=Array.isArray(t)?t:[t]).forEach((e=>r.push("^"+e.replace(/([^\w])/g,"\\$1").replace("\\*",".*")+"$"))),r=new RegExp(r.join("|")),Array.from(n).every((e=>!e.type||r.test(e.type)))},image:function(e,n,r){return t.validators.mimeType(e,n??["image/gif","image/png","image/jpeg","image/webp"],r)},static:function(e,t){return t}},t.toggleForm=function(e,n=null){r={};for(let r of Array.from(e.elements))r.getAttribute("data-nette-rules")&&t.toggleControl(r,null,null,!n);for(let e in r)t.toggle(e,r[e].state,r[e].elem,n)},t.toggleControl=function(e,n,i,u,f=null,d=null){n??=JSON.parse(e.getAttribute("data-nette-rules")??"[]"),f??={value:t.getEffectiveValue(e)},d??=!t.validateRule(e,":filled",null,f);let s,c=!1;for(let m of n){let n=m.op.match(/(~)?([^?]+)/),g=m.control?l(e.form,m.control):e;if(m.neg=n[1],m.op=n[2],m.condition=!!m.rules,g&&(!d||m.condition||":filled"===m.op)){if(s=i,!1!==i){if(s=t.validateRule(g,m.op,m.arg,e===g?f:void 0),null===s)continue;m.neg&&(s=!s),m.condition||(i=s)}if(m.condition&&t.toggleControl(e,m.rules,s,u,f,":blank"!==m.op&&d)||m.toggle){c=!0,u&&a(g).filter((e=>!o.has(e))).forEach((n=>{n.addEventListener("change",(n=>t.toggleForm(e.form,n))),o.set(n,null)}));for(let t in m.toggle??[])r[t]??={elem:e,state:m.toggle[t]?s:!s}}}}return c},t.toggle=function(e,t,n,r){/^\w[\w.:-]*$/.test(e)&&(e="#"+e),Array.from(document.querySelectorAll(e)).forEach((e=>e.hidden=!t))},t.compactCheckboxes=function(e,t){let n={};for(let r of e.elements)r instanceof HTMLInputElement&&"checkbox"===r.type&&r.name.endsWith("[]")&&r.checked&&!r.disabled&&(t.delete(r.name),n[r.name]??=[],n[r.name].push(r.value));for(let e in n)t.set(e.substring(0,e.length-2),n[e].join(","))},t.initForm=function(e){"get"===e.method&&e.hasAttribute("data-nette-compact")&&e.addEventListener("formdata",(n=>t.compactCheckboxes(e,n.formData))),Array.from(e.elements).some((e=>e.getAttribute("data-nette-rules")))&&(t.toggleForm(e),e.noValidate||(e.noValidate=!0,e.addEventListener("submit",(n=>{t.validateForm(e)||(n.stopPropagation(),n.preventDefault())})),e.addEventListener("reset",(()=>{setTimeout((()=>t.toggleForm(e)))}))))},t.initOnLoad=function(){t.onDocumentReady((()=>{Array.from(document.forms).forEach((e=>t.initForm(e))),document.body.addEventListener("click",(e=>{let t=e.target;for(;t;){if(t.form&&t.type in{submit:1,image:1}){t.form["nette-submittedBy"]=t;break}t=t.parentNode}}))}))},t.webalize=function(e){e=e.toLowerCase();let n,r="";for(let o=0;o<e.length;o++)n=t.webalizeTable[e.charAt(o)],r+=n||e.charAt(o);return r.replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")},t.webalizeTable={á:"a",ä:"a",č:"c",ď:"d",é:"e",ě:"e",í:"i",ľ:"l",ň:"n",ó:"o",ô:"o",ř:"r",š:"s",ť:"t",ú:"u",ů:"u",ý:"y",ž:"z"},t})); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
78542
7
1260
3
1