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.