PageSourceSearch

https://www.tuli.sk/includes/js/system/FormValidator.js?094864

js tuli.sk collected 2026-09-24 13:07:35 UTC 18,479 bytes, 741 lines download raw bytes

1/**
2 * Validator na formy pisane cez divField v material designe
3 * - required inputy su validovane automaticky
4 * - pre custom validaciu a pridanie pravidiel je potrebne pouzit addRule
5 *
6 * @param formContainer jQuery element, v ktorom sa nachadza cely form
7 * @returns {FormValidator}
8 * @constructor
9 *
10 * @author Jakub Sakac <[email protected]>
11 */
12var FormValidator = function (formContainer) {
13	this.form = jQuery(formContainer);
14	this.inputs = this.form.find('input, select, textarea');
15	this.rules = [];
16
17	return this;
18};
19
20/**
21 * Ziskanie hodnot vsetkych inputov, okrem tych disabled
22 *
23 * @param sanitizeInputs {boolean} ak je true, tak vrati osetrene hodnoty
24 */
25FormValidator.prototype.getFormValues = function(sanitizeInputs) {
26	var formValues = {};
27
28	if ( sanitizeInputs ) {
29		this.sanitize();
30	}
31
32	this.inputs.not(':disabled').each(function(key, elm) {
33		elm = jQuery(elm);
34
35		// ak je input radio button alebo checkbox a nie je zaskrtnuty, tak ho nepridavajme
36		if ( (elm.is(':radio') || elm.is(':checkbox')) && !elm.prop('checked') ) {
37			return;
38		}
39
40		var elmVal = elm.val();
41		var elmName = elm.attr('name');
42
43		formValues[elmName] = elmVal;
44	});
45
46	return formValues;
47};
48
49/**
50 * Nabindovanie validacie na vsetky inputy po definovani vsetkych nastaveni a pridani pravidiel
51 */
52FormValidator.prototype.bindValidation = function() {
53	this.inputs.not(':checkbox').on('blur change', jQuery.proxy(function(e) {
54		this.validateInput(jQuery(e.target));
55	}, this));
56};
57
58/**
59 * Manualna validacia formulara
60 * je potrebne volat pri submite
61 *
62 * Prechadza vsetky inputy najdene v poli inputov (vytvori sa v constructe)
63 *
64 * @returns {boolean} vrati ci je formular validny podla definovanych pravidiel
65 */
66FormValidator.prototype.validate = function() {
67	var valid = true;
68
69	this.inputs.not(':disabled').each(jQuery.proxy(function(key, elm) {
70		if (!this.validateInput(elm)) valid = false;
71	}, this));
72
73	return valid;
74};
75
76/**
77 * Funkcia na zvalidovanie konkretneho inputu/selectu
78 * Interna funkcia, nie je potrebne volat vonku
79 *
80 * V pripade, ze pravidlo nie je pre input definovane, vrati true a input je validny
81 *
82 * @param elm konkretny input element
83 * @returns {boolean} vrati ci je input validny
84 */
85FormValidator.prototype.validateInput = function(elm) {
86	elm = jQuery(elm);
87	var elmVal = elm.val();
88	var elmName = elm.attr('name');
89	var elmRules = this.rules[elmName];
90	var elmIsRequired = elm.hasClass('required');
91
92	elm.toggleClass('filled', this.isDefined(elmVal) && elmVal != '');
93
94	this.removeError(elm);
95
96	// required field
97	if (elmIsRequired && ( !this.isDefined(elmVal) || elmVal == '' || (config('js_Config_custom_contact_form_selects') && elm.is('select') && elm.val() === '0')) ) {
98		if ( typeof js_Config_forgotten_password_new !== 'undefined' && js_Config_forgotten_password_new ) {
99
100			var labelText = elm.closest('.field').find('label').text();
101			labelText = labelText.trim().replace(':', '');
102
103			if (labelText !== '') {
104				this.addError(elm, js_lang_new_form_item + ' "' +labelText+ '" ' + js_lang_new_form_nesessery);
105			} else {
106				this.addError(elm, js_lang_registration_reset_password_field_required );
107			}
108		} else {
109			this.addError(elm, 'Položka je povinná');
110		}
111
112
113		return false;
114	}
115
116	// rules nastavene cez addRule
117	if (this.isDefined(elmRules)) {
118		for (var ruleName in elmRules) {
119			if (!elmRules.hasOwnProperty(ruleName)) {
120				continue;
121			}
122
123			var rule = elmRules[ruleName];
124
125			if (this.isSanitizationRule(rule)) {
126				continue;
127			}
128
129			if (this.isDefined(rule.conditions) && !this.checkConditions(rule.conditions)) {
130				elm.addClass('valid');
131				return true;
132			}
133
134			if (typeof this[ruleName] === 'function') {
135				// zavolanie custom funkcie na overenie
136				if ( !this[ruleName](elm, rule) ) {
137					return false;
138				}
139			}
140		}
141	}
142
143	if (elmIsRequired || this.isDefined(elmRules)) {
144		elm.addClass('valid');
145	}
146
147	return true;
148};
149
150/**
151 * Satinizacia/osetrenie hodnot formulara
152 * bud sa musi zavolat manualne alebo pri ziskani vsektych hodnot v getFormValues
153 *
154 * Prechadza vsetky inputy najdene v poli inputov (vytvori sa v constructe)
155 */
156FormValidator.prototype.sanitize = function() {
157	this.inputs.not(':disabled').each(jQuery.proxy(function(key, elm) {
158		this.sanitizeInput(elm);
159	}, this));
160};
161
162/**
163 * Funkcia na sanitizaciu/osetrenie konkretneho inputu
164 *
165 * V pripade, ze custom pravidlo nie je pre input definovane, vrati trimnutu hodnotu
166 *
167 * @param elm
168 * @returns {string}
169 */
170FormValidator.prototype.sanitizeInput = function(elm) {
171	elm = jQuery(elm);
172	var elmVal = elm.val();
173	var elmName = elm.attr('name');
174	var elmRules = this.rules[elmName];
175
176	var trimmedVal = elmVal.trim();
177
178	// rules nastavene cez addRule
179	if (this.isDefined(elmRules)) {
180		trimmedVal = Object.keys(elmRules).reduce(jQuery.proxy(function(inputVal, ruleName) {
181			var rule = elmRules[ruleName];
182
183			if (!this.isSanitizationRule(rule)) {
184				return inputVal;
185			}
186
187			return this[ruleName](elm, rule, inputVal);
188		}, this), trimmedVal);
189	}
190
191	elm.val(trimmedVal);
192	return trimmedVal;
193};
194
195/**
196 * Sluzi na overenie podmienok, ktore urcuju, ci sa ma validacia inputu vykonat - vo validateInput
197 *
198 * V pripade, ak niektory z inputov nema platnu value (podla pola),
199 * podmienka nepresla a pravidlo na ktore je naviazana sa nebude overovat (input bude validny)
200 *
201 * @param {Object.<string, Array>} conditions objekt, v ktorom su ako kluce nazvy inputov (atribut name) a ako value pole hodnot moznych pre tento input
202 * @returns {boolean}
203 */
204FormValidator.prototype.checkConditions = function(conditions) {
205	var valid = true;
206
207	for (var elmName in conditions) {
208		if (!conditions.hasOwnProperty(elmName)) {
209			continue;
210		}
211
212		var elm = this.inputs.filter('[name="' + elmName + '"]');
213
214		if (elm.length) {
215			var elmVal = elm.val();
216
217			if (typeof conditions[elmName] == 'object' && conditions[elmName].indexOf(elmVal) == -1) {
218				valid = false;
219			}
220		}
221	}
222
223	return valid;
224};
225
226/**
227 * Pridanie pravidla validacie do zoznamu pravidiel
228 *
229 *
230 * @param inputName nazov inputu vo forme
231 * @param rule custom metoda overovania - metody su definovane dole v classe
232 * @param value kontrolovana hodnota
233 * @param message chybova hlaska v pripade, ze input neprejde validaciou
234 * @param conditions podmienka, ak jej vysledok je true, input sa zvaliduje, inac nie
235 * @param sanitizationRule {boolean} kontrola, ci sa jedna o validacne alebo sanitizacne pravidlo
236 * @returns {FormValidator}
237 */
238FormValidator.prototype.addRule = function(inputName, rule, value, message, conditions, sanitizationRule) {
239	if (!this.isDefined(this.rules[inputName])) {
240		this.rules[inputName] = [];
241	}
242
243	this.rules[inputName][rule] = [];
244	this.rules[inputName][rule].value = value;
245
246	if (this.isDefined(sanitizationRule)) {
247		this.rules[inputName][rule].sanitizationRule = sanitizationRule;
248	}
249
250	if (this.isDefined(message)) {
251		this.rules[inputName][rule].message = message;
252	}
253
254	if (this.isDefined(conditions)) {
255		this.rules[inputName][rule].conditions = conditions;
256	}
257
258	return this;
259};
260
261/**
262 * Vykreslenie chyby v pripade nevalidneho inputu
263 *
264 * @param elm
265 * @param message
266 */
267FormValidator.prototype.addError = function(elm, message) {
268	var $wrapper = elm.closest('.field');
269
270	this.removeError(elm);
271
272	$wrapper.append('<div class="error_box">' + message + "</div>");
273	elm.addClass('error');
274	elm.removeClass('valid');
275};
276
277/**
278 * Odstranenie chyby v pripade, ze input je validny
279 *
280 * @param elm
281 */
282FormValidator.prototype.removeError = function(elm) {
283	var $wrapper = elm.closest('.field');
284
285	$wrapper.find('.error_box').remove();
286	elm.removeClass('error');
287};
288
289/**
290 * @param variable kontrolovana premenna
291 * @returns {boolean} premenna existuje
292 */
293FormValidator.prototype.isDefined = function(variable) {
294	return typeof variable !== 'undefined';
295};
296
297/**
298 *
299 * @param rule kontrolovane pravidlo
300 * @returns {boolean} nie je validacne pravidlo, ale sanitizacne
301 */
302FormValidator.prototype.isSanitizationRule = function(rule) {
303	return typeof rule.sanitizationRule !== 'undefined' && rule.sanitizationRule ;
304};
305
306/*********************************
307 ** CUSTOM VALIDACNE PRAVIDLA PRE addRule **
308 ********************************/
309
310/**
311 * Regex validacia
312 *
313 * @param elm
314 * @param rule
315 * @returns {boolean}
316 */
317FormValidator.prototype.regexMatch = function(elm, rule) {
318	if (!this.isDefined(rule.value)) {
319		return false;
320	}
321
322	var valid = elm.val().match(rule.value) != null;
323	var message = this.isDefined(rule.message) ? rule.message : 'Hodnota nie je v správnom formáte';
324
325	if (!valid) {
326		this.addError(elm, message);
327		return false;
328	}
329
330	return true;
331};
332
333FormValidator.prototype.allowedChars = function(elm, rule) {
334	if (!this.isDefined(rule.value)) {
335		return false;
336	}
337
338	var valid = elm.val().match(rule.value) != null;
339	var message = this.isDefined(rule.message) ? rule.message : 'Obsahuje nepovolené znaky';
340
341	if (!valid) {
342		this.addError(elm, message);
343		return false;
344	}
345
346	return true;
347};
348
349FormValidator.prototype.minLength = function(elm, rule) {
350	if (!this.isDefined(rule.value)) {
351		return false;
352	}
353
354	var valid = elm.val().length >= rule.value;
355	var message = this.isDefined(rule.message) ? rule.message : 'Min. počet znakov: ' + rule.value;
356
357	if (!valid) {
358		this.addError(elm, message);
359		return false;
360	}
361
362	return true;
363};
364
365FormValidator.prototype.maxLength = function(elm, rule) {
366	if (!this.isDefined(rule.value)) {
367		return false;
368	}
369
370	var valid = elm.val().length <= rule.value;
371	var message = this.isDefined(rule.message) ? rule.message : 'Max. počet znakov: ' + rule.value;
372
373	if (!valid) {
374		this.addError(elm, message);
375		return false;
376	}
377
378	return true;
379};
380
381FormValidator.prototype.min = function(elm, rule) {
382	if (!this.isDefined(rule.value)) {
383		return false;
384	}
385
386	if (isNaN(elm.val()) || isNaN(rule.value)) {
387		this.addError(elm, 'Hodnota musí byť číslo');
388		return false;
389	}
390
391	var valid = elm.val() >= rule.value;
392	var message = this.isDefined(rule.message) ? rule.message : 'Min. hodnota: ' + rule.value;
393
394	if (!valid) {
395		this.addError(elm, message);
396		return false;
397	}
398
399	return true;
400};
401
402FormValidator.prototype.max = function(elm, rule) {
403	if (!this.isDefined(rule.value)) {
404		return false;
405	}
406
407	if (isNaN(elm.val()) || isNaN(rule.value)) {
408		this.addError(elm, 'Hodnota musí byť číslo');
409		return false;
410	}
411
412	var valid = elm.val() <= rule.value;
413	var message = this.isDefined(rule.message) ? rule.message : 'Max. hodnota: ' + rule.value;
414
415	if (!valid) {
416		this.addError(elm, message);
417		return false;
418	}
419
420	return true;
421};
422
423FormValidator.prototype.enum = function(elm, rule) {
424	if (!this.isDefined(rule.value) || !(rule.value instanceof Array)) {
425		return false;
426	}
427
428	var valid = rule.value.indexOf(elm.val()) !== -1;
429	var message = this.isDefined(rule.message) ? rule.message : 'Hodnota nie je v správnom formáte';
430
431	if (!valid) {
432		this.addError(elm, message);
433		return false;
434	}
435
436	return true;
437};
438
439FormValidator.prototype.isEmail = function(elm, rule) {
440	if (!this.isDefined(rule.value)) {
441		return false;
442	}
443
444	var emailAddress = elm.val();
445
446	var valid = emailAddress.match(/[\w.\-]+@\w+[\w.\-]*?\.\w{1,4}/) != null;
447	var message = this.isDefined(rule.message) ? rule.message : 'Nesprávny tvar e-mailovej adresy: "' + emailAddress + '"';
448
449	if (!valid) {
450		this.addError(elm, message);
451		return false;
452	}
453
454	return true;
455};
456
457FormValidator.prototype.isNumber = function(elm, rule) {
458	if (!this.isDefined(rule.value)) {
459		return false;
460	}
461
462	var valid = !isNaN(elm.val());
463	var message = this.isDefined(rule.message) ? rule.message : 'Hodnota musí byť číslo';
464
465	if (!valid) {
466		this.addError(elm, message);
467		return false;
468	}
469
470	return true;
471};
472
473FormValidator.prototype.isEqualTo = function(elm, rule) {
474	if (!this.isDefined(rule.value)) {
475		return false;
476	}
477
478	var checkAgainstInput = this.form.find('[name="' + rule.value + '"]');
479
480	var valid = elm.val() === checkAgainstInput.val();
481	var message = this.isDefined(rule.message) ? rule.message : 'Hodnoty sa nezhodujú';
482
483	if (!valid) {
484		this.addError(elm, message);
485		return false;
486	}
487
488	return true;
489};
490
491FormValidator.prototype.isChecked = function(elm, rule) {
492	if (!elm.prop('checked')) {
493		var message = this.isDefined(rule.message) ? rule.message : 'Položka je povinná';
494		this.addError(elm, message);
495		return false;
496	}
497
498	return true;
499};
500
501FormValidator.prototype.isBarcode = function(elm, rule) {
502	var barcode = elm.val();
503	var message = this.isDefined(rule.message) ? rule.message : 'Kód klubovej karty nie je platný';
504
505	// check length
506	if (barcode.length < 8 || barcode.length > 18 ||
507		(barcode.length != 8 && barcode.length != 12 &&
508			barcode.length != 13 && barcode.length != 14 &&
509			barcode.length != 18)) {
510		this.addError(elm, message);
511		return false;
512	}
513
514	var lastDigit = Number(barcode.substring(barcode.length - 1));
515	var checkSum = 0;
516	if (isNaN(lastDigit)) {
517		this.addError(elm, message);
518		return false;
519	} // not a valid upc/ean
520
521	var arr = barcode.substring(0,barcode.length - 1).split("").reverse();
522	var oddTotal = 0, evenTotal = 0;
523
524	for (var i=0; i<arr.length; i++) {
525		if (isNaN(arr[i])) {
526			this.addError(elm, message);
527			return false;
528		} // can't be a valid upc/ean we're checking for
529
530		if (i % 2 == 0) { oddTotal += Number(arr[i]) * 3; }
531		else { evenTotal += Number(arr[i]); }
532	}
533	checkSum = (10 - ((evenTotal + oddTotal) % 10)) % 10;
534
535	// true if they are equal
536	if (checkSum != lastDigit) {
537		this.addError(elm, message);
538		return false;
539	}
540
541	return true;
542};
543
544FormValidator.prototype.isZipCode = function(elm, rule) {
545	// TODO
546};
547
548/**
549 *  DEPRECATED ↓
550 */
551
552/**
553 * Validacia checkboxu
554 *
555 * @param elm
556 * @param rule
557 * @returns {boolean}
558 */
559FormValidator.prototype.validateCheckbox = function(elm, rule) {
560	if (!elm.prop('checked')) {
561		var message = this.isDefined(rule.message) ? rule.message : 'Položka je povinná';
562		this.addError(elm, message);
563		return false;
564	}
565
566	return true;
567};
568
569/**
570 * Validacia dlzky hodnoty
571 *
572 * @param elm
573 * @param rule
574 * @returns {boolean}
575 */
576FormValidator.prototype.validateLength = function(elm, rule) {
577	if (!this.isDefined(rule.value)) {
578		return false;
579	}
580
581	var requiredLength = rule.value;
582
583	if ( elm.val().trim().length < requiredLength ) {
584		var message = this.isDefined(rule.message) ? rule.message : 'Minimálne ' + requiredLength + ' znakov';
585		this.addError(elm, message);
586		return false;
587	}
588
589	return true;
590};
591
592/**
593 * Porovnanie hodnot dvoch inputov
594 *
595 * rule.value musi byt jQuery Object
596 *
597 * @param elm
598 * @param rule
599 * @returns {boolean}
600 */
601FormValidator.prototype.compareInputValues = function(elm, rule) {
602	if (!this.isDefined(rule.value) || !rule.value.length) {
603		return false;
604	}
605
606	var firstValue = elm.val().trim();
607	var secondValue = rule.value.val().trim();
608
609	if ( firstValue !== secondValue ) {
610		var message = this.isDefined(rule.message) ? rule.message : 'Hodnoty sa nezhodujú';
611		this.addError(elm, message);
612		return false;
613	}
614
615	return true;
616};
617
618/**
619 * @param elm
620 * @param {string} value
621 * @param {object} rule
622 * @returns {boolean}
623 */
624FormValidator.prototype.validateDate = function(elm, rule) {
625	if (!this.isDefined(rule) || Object.keys(rule).length === 0) {
626		return false;
627	}
628
629	let message = this.isDefined(rule.message) ? rule.message : 'Neplatný formát dátumu';
630	let date;
631
632	try {
633		 date = jQuery.datepicker.parseDate(rule.format, elm.val().trim());
634	} catch (e) {
635		return false;
636	}
637
638	if (!date) {
639		return false;
640	}
641
642	if (!rule.days?.includes(date.getDay())) {
643		this.addError(elm, message);
644		return false;
645	}
646
647	if (rule.minDate && typeof rule.minDate === 'number') {
648		const today = new Date();
649		today.setHours(0, 0, 0, 0);
650		today.setDate(today.getDate() + rule.minDate);
651
652		if (date < today) {
653			this.addError(elm, message);
654			return false;
655		}
656	}
657
658	return true;
659};
660
661/**
662 * Validacia klubovej karty
663 *
664 * @param elm
665 * @param rule
666 * @returns {boolean}
667 */
668FormValidator.prototype.validateBarcode = function(elm, rule) {
669	var barcode = elm.val();
670	var message = this.isDefined(rule.message) ? rule.message : 'Kód klubovej karty nie je platný';
671
672	// check length
673	if (barcode.length < 8 || barcode.length > 18 ||
674		(barcode.length != 8 && barcode.length != 12 &&
675			barcode.length != 13 && barcode.length != 14 &&
676			barcode.length != 18)) {
677		this.addError(elm, message);
678		return false;
679	}
680
681	var lastDigit = Number(barcode.substring(barcode.length - 1));
682	var checkSum = 0;
683	if (isNaN(lastDigit)) {
684		this.addError(elm, message);
685		return false;
686	} // not a valid upc/ean
687
688	var arr = barcode.substring(0,barcode.length - 1).split("").reverse();
689	var oddTotal = 0, evenTotal = 0;
690
691	for (var i=0; i<arr.length; i++) {
692		if (isNaN(arr[i])) {
693			this.addError(elm, message);
694			return false;
695		} // can't be a valid upc/ean we're checking for
696
697		if (i % 2 == 0) { oddTotal += Number(arr[i]) * 3; }
698		else { evenTotal += Number(arr[i]); }
699	}
700	checkSum = (10 - ((evenTotal + oddTotal) % 10)) % 10;
701
702	// true if they are equal
703	if (checkSum != lastDigit) {
704		this.addError(elm, message);
705		return false;
706	}
707
708	return true;
709};
710
711/*********************************
712 ** CUSTOM SANITIZACNE PRAVIDLA PRE addRule **
713 ********************************/
714
715/**
716 * Regex sanitizacia
717 * rule.value musi byt object vo formate { regex: Regex, replacement: String }
718 *
719 * @param elm
720 * @param rule
721 * @param elemVal {string}
722 * @returns {string}
723 */
724FormValidator.prototype.regexReplace = function(elm, rule, elemVal) {
725	if (!this.isSanitizationRule(rule)) {
726		return elemVal;
727	}
728
729	if (
730		!this.isDefined(rule.value)
731		|| !this.isDefined(rule.value.pattern)
732		|| !this.isDefined(rule.value.replacement)
733		) {
734		return elemVal;
735	}
736
737	var pattern = new RegExp(rule.value.pattern, 'gi');
738	var replacement = rule.value.replacement;
739
740	return elemVal.replace(pattern, replacement);
741};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.