From c8a689cf60eae19b75424520f62276ddba903e41 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Mon, 29 Aug 2016 09:43:53 +0200 Subject: [PATCH 01/72] remove padding --- styles/bootstrap/datepicker/css/datepicker.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/bootstrap/datepicker/css/datepicker.css b/styles/bootstrap/datepicker/css/datepicker.css index 410e13e93..4e1a785e8 100644 --- a/styles/bootstrap/datepicker/css/datepicker.css +++ b/styles/bootstrap/datepicker/css/datepicker.css @@ -8,7 +8,7 @@ * */ .datepicker { - padding: 4px; + _padding: 4px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; From 96a4db05bf980148fd6c2d96f61695bcc6be16e0 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Mon, 29 Aug 2016 09:44:49 +0200 Subject: [PATCH 02/72] add more field validation --- views/bootstrap/class.AddDocument.php | 35 +++++++++++++++++++++++- views/bootstrap/class.AddSubFolder.php | 24 ++++++++++++++-- views/bootstrap/class.Bootstrap.php | 11 ++++---- views/bootstrap/class.EditDocument.php | 24 ++++++++++++++-- views/bootstrap/class.EditFolder.php | 23 ++++++++++++++-- views/bootstrap/class.UpdateDocument.php | 20 +++++++++++++- 6 files changed, 123 insertions(+), 14 deletions(-) diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index 8204f120c..5a2dbe877 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -74,6 +74,37 @@ $(document).ready(function() { $('#new-file').click(function(event) { $("#upload-file").clone().appendTo("#upload-files").removeAttr("id").children('div').children('input').val(''); }); + + var validator = $("#form1").bind("invalid-form.validate", function() { + noty({ + text: (validator.numberOfInvalids() == 1) ? "".replace('#', validator.numberOfInvalids()) : "".replace('#', validator.numberOfInvalids()), + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + }).validate({ + rules: { + "_userfile[]": { + required: true + } + }, + messages: { + "_userfile[]": "", + name: "", + comment: "", + keywords: "" + }, + errorPlacement: function( error, element ) { + if ( element.is( ":file" ) ) { + error.appendTo( element.parent().parent().parent()); +console.log(element); + } else { + error.appendTo( element.parent()); + } + } + }); }); printKeywordChooserJs("form1"); @@ -98,6 +129,8 @@ $(document).ready(function() { $orderby = $this->params['orderby']; $folderid = $folder->getId(); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName())))); $this->globalNavigation($folder); $this->contentStart(); @@ -131,7 +164,7 @@ $(document).ready(function() { : - + : diff --git a/views/bootstrap/class.AddSubFolder.php b/views/bootstrap/class.AddSubFolder.php index 0e9f53aa1..23fa1ef8a 100644 --- a/views/bootstrap/class.AddSubFolder.php +++ b/views/bootstrap/class.AddSubFolder.php @@ -61,10 +61,26 @@ function checkForm() return true; } $(document).ready( function() { - $('body').on('submit', '#form1', function(ev){ +/* $('body').on('submit', '#form1', function(ev){ if(checkForm()) return; ev.preventDefault(); }); +*/ + var validator = $("#form1").bind("invalid-form.validate", function() { + noty({ + text: (validator.numberOfInvalids() == 1) ? "".replace('#', validator.numberOfInvalids()) : "".replace('#', validator.numberOfInvalids()), + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + }).validate({ + messages: { + name: "", + comment: "" + }, + }); }); params['strictformcheck']; $orderby = $this->params['orderby']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName())))); $this->globalNavigation($folder); $this->contentStart(); @@ -91,11 +109,11 @@ $(document).ready( function() { - + - + diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index e2a4d74a5..6502410f2 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -1021,9 +1021,10 @@ function folderSelected(id, name) { } /* }}} */ function printKeywordChooserHtml($formName, $keywords='', $fieldname='keywords') { /* {{{ */ + $strictformcheck = $this->params['strictformcheck']; ?>
- + />
:
:
:
- + - + diff --git a/views/bootstrap/class.EditFolder.php b/views/bootstrap/class.EditFolder.php index 9e9c1c929..f8032b893 100644 --- a/views/bootstrap/class.EditFolder.php +++ b/views/bootstrap/class.EditFolder.php @@ -61,10 +61,27 @@ function checkForm() return true; } $(document).ready(function() { +/* $('body').on('submit', '#form1', function(ev){ if(checkForm()) return; ev.preventDefault(); }); +*/ + var validator = $("#form1").bind("invalid-form.validate", function() { + noty({ + text: (validator.numberOfInvalids() == 1) ? "".replace('#', validator.numberOfInvalids()) : "".replace('#', validator.numberOfInvalids()), + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + }).validate({ + messages: { + name: "", + comment: "" + }, + }); }); params['strictformcheck']; $orderby = $this->params['orderby']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName())))); $this->globalNavigation($folder); $this->contentStart(); @@ -91,11 +110,11 @@ $(document).ready(function() {
:
:
:
- + - +getID() == $rootfolderid) ? false : $folder->getParent(); diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index bb76e5725..48554688a 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -70,10 +70,26 @@ function checkForm() } $(document).ready( function() { +/* $('body').on('submit', '#form1', function(ev){ if(checkForm()) return; ev.preventDefault(); }); +*/ + var validator = $("#form1").bind("invalid-form.validate", function() { + noty({ + text: (validator.numberOfInvalids() == 1) ? "".replace('#', validator.numberOfInvalids()) : "".replace('#', validator.numberOfInvalids()), + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + }).validate({ + messages: { + comment: "", + } + }); }); params['presetexpiration']; $documentid = $document->getId(); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("document_title", array("documentname" => htmlspecialchars($document->getName())))); $this->globalNavigation($folder); $this->contentStart(); @@ -163,7 +181,7 @@ $(document).ready( function() { Date: Tue, 30 Aug 2016 07:56:50 +0200 Subject: [PATCH 03/72] remove guest user check --- inc/inc.ClassDbAuthentication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/inc.ClassDbAuthentication.php b/inc/inc.ClassDbAuthentication.php index 1750a6acc..18838ee3e 100644 --- a/inc/inc.ClassDbAuthentication.php +++ b/inc/inc.ClassDbAuthentication.php @@ -58,7 +58,7 @@ class SeedDMS_DbAuthentication extends SeedDMS_Authentication { // Check if password matches (if not a guest user) // Assume that the password has been sent via HTTP POST. It would be careless // (and dangerous) for passwords to be sent via GET. - if (($userid != $settings->_guestID) && (md5($password) != $user->getPwd()) || ($userid == $settings->_guestID) && $user->getPwd() && (md5($password) != $user->getPwd())) { + if (md5($password) != $user->getPwd()) { /* if counting of login failures is turned on, then increment its value */ if($settings->_loginFailure) { $failures = $user->addLoginFailure(); From 1e691c245173bce1516959598d40ae1e9f63ec4c Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Tue, 30 Aug 2016 07:57:06 +0200 Subject: [PATCH 04/72] check early for guest login even before any other authenitcation methods --- op/op.Login.php | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/op/op.Login.php b/op/op.Login.php index f684f9254..c6d4e3708 100644 --- a/op/op.Login.php +++ b/op/op.Login.php @@ -57,21 +57,28 @@ if(isset($_POST['pwd'])) { } } -/* The password may only be empty if the guest user tries to log in */ -if($settings->_enableGuestLogin && (int) $settings->_guestID) { - $guestUser = $dms->getUser((int) $settings->_guestID); - if ((!isset($pwd) || strlen($pwd)==0) && ($login != $guestUser->getLogin())) { - _printMessage(getMLText("login_error_title"), getMLText("login_error_text")."\n"); - exit; - } -} - /* Initialy set $user to false. It will contain a valid user record - * if authentication against ldap succeeds. - * _ldapHost will only have a value if the ldap connector has been enabled + * if the user is a guest user or authentication will succeed. */ $user = false; +/* The password may only be empty if the guest user tries to log in. + * There is just one guest account with id $settings->_guestID which + * is allowed to log in without a password. All other guest accounts + * are treated like regular logins + */ +if($settings->_enableGuestLogin && (int) $settings->_guestID) { + $guestUser = $dms->getUser((int) $settings->_guestID); + if(($login != $guestUser->getLogin())) { + if ((!isset($pwd) || strlen($pwd)==0)) { + _printMessage(getMLText("login_error_title"), getMLText("login_error_text")."\n"); + exit; + } + } else { + $user = $guestUser; + } +} + /* Authenticate against LDAP server {{{ */ if (!$user && isset($settings->_ldapHost) && strlen($settings->_ldapHost)>0) { require_once("../inc/inc.ClassLdapAuthentication.php"); @@ -80,7 +87,7 @@ if (!$user && isset($settings->_ldapHost) && strlen($settings->_ldapHost)>0) { } /* }}} */ /* Authenticate against SeedDMS database {{{ */ -else { +if(!$user) { require_once("../inc/inc.ClassDbAuthentication.php"); $authobj = new SeedDMS_DbAuthentication($dms, $settings); $user = $authobj->authenticate($login, $pwd); From e67ef718cceda7a8c67755d7bc237d499cfaf947 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Tue, 30 Aug 2016 07:59:03 +0200 Subject: [PATCH 05/72] add jquery validation --- .../bootstrap/validate/additional-methods.js | 1069 +++++++++++ .../validate/additional-methods.min.js | 4 + styles/bootstrap/validate/jquery.validate.js | 1574 +++++++++++++++++ .../bootstrap/validate/jquery.validate.min.js | 4 + .../validate/localization/messages_ar.js | 35 + .../validate/localization/messages_ar.min.js | 4 + .../validate/localization/messages_bg.js | 35 + .../validate/localization/messages_bg.min.js | 4 + .../validate/localization/messages_bn_BD.js | 35 + .../localization/messages_bn_BD.min.js | 4 + .../validate/localization/messages_ca.js | 35 + .../validate/localization/messages_ca.min.js | 4 + .../validate/localization/messages_cs.js | 35 + .../validate/localization/messages_cs.min.js | 4 + .../validate/localization/messages_da.js | 32 + .../validate/localization/messages_da.min.js | 4 + .../validate/localization/messages_de.js | 32 + .../validate/localization/messages_de.min.js | 4 + .../validate/localization/messages_el.js | 35 + .../validate/localization/messages_el.min.js | 4 + .../validate/localization/messages_es.js | 38 + .../validate/localization/messages_es.min.js | 4 + .../validate/localization/messages_es_AR.js | 39 + .../localization/messages_es_AR.min.js | 4 + .../validate/localization/messages_es_PE.js | 39 + .../localization/messages_es_PE.min.js | 4 + .../validate/localization/messages_et.js | 33 + .../validate/localization/messages_et.min.js | 4 + .../validate/localization/messages_eu.js | 35 + .../validate/localization/messages_eu.min.js | 4 + .../validate/localization/messages_fa.js | 38 + .../validate/localization/messages_fa.min.js | 4 + .../validate/localization/messages_fi.js | 33 + .../validate/localization/messages_fi.min.js | 4 + .../validate/localization/messages_fr.js | 61 + .../validate/localization/messages_fr.min.js | 4 + .../validate/localization/messages_ge.js | 35 + .../validate/localization/messages_ge.min.js | 4 + .../validate/localization/messages_gl.js | 40 + .../validate/localization/messages_gl.min.js | 4 + .../validate/localization/messages_he.js | 35 + .../validate/localization/messages_he.min.js | 4 + .../validate/localization/messages_hr.js | 35 + .../validate/localization/messages_hr.min.js | 4 + .../validate/localization/messages_hu.js | 34 + .../validate/localization/messages_hu.min.js | 4 + .../validate/localization/messages_hy_AM.js | 35 + .../localization/messages_hy_AM.min.js | 4 + .../validate/localization/messages_id.js | 34 + .../validate/localization/messages_id.min.js | 4 + .../validate/localization/messages_is.js | 33 + .../validate/localization/messages_is.min.js | 4 + .../validate/localization/messages_it.js | 39 + .../validate/localization/messages_it.min.js | 4 + .../validate/localization/messages_ja.js | 35 + .../validate/localization/messages_ja.min.js | 4 + .../validate/localization/messages_ka.js | 35 + .../validate/localization/messages_ka.min.js | 4 + .../validate/localization/messages_kk.js | 35 + .../validate/localization/messages_kk.min.js | 4 + .../validate/localization/messages_ko.js | 35 + .../validate/localization/messages_ko.min.js | 4 + .../validate/localization/messages_lt.js | 35 + .../validate/localization/messages_lt.min.js | 4 + .../validate/localization/messages_lv.js | 35 + .../validate/localization/messages_lv.min.js | 4 + .../validate/localization/messages_mk.js | 35 + .../validate/localization/messages_mk.min.js | 4 + .../validate/localization/messages_my.js | 35 + .../validate/localization/messages_my.min.js | 4 + .../validate/localization/messages_nl.js | 45 + .../validate/localization/messages_nl.min.js | 4 + .../validate/localization/messages_no.js | 35 + .../validate/localization/messages_no.min.js | 4 + .../validate/localization/messages_pl.js | 36 + .../validate/localization/messages_pl.min.js | 4 + .../validate/localization/messages_pt_BR.js | 87 + .../localization/messages_pt_BR.min.js | 4 + .../validate/localization/messages_pt_PT.js | 39 + .../localization/messages_pt_PT.min.js | 4 + .../validate/localization/messages_ro.js | 35 + .../validate/localization/messages_ro.min.js | 4 + .../validate/localization/messages_ru.js | 35 + .../validate/localization/messages_ru.min.js | 4 + .../validate/localization/messages_si.js | 35 + .../validate/localization/messages_si.min.js | 4 + .../validate/localization/messages_sk.js | 32 + .../validate/localization/messages_sk.min.js | 4 + .../validate/localization/messages_sl.js | 35 + .../validate/localization/messages_sl.min.js | 4 + .../validate/localization/messages_sr.js | 35 + .../validate/localization/messages_sr.min.js | 4 + .../validate/localization/messages_sr_lat.js | 35 + .../localization/messages_sr_lat.min.js | 4 + .../validate/localization/messages_sv.js | 33 + .../validate/localization/messages_sv.min.js | 4 + .../validate/localization/messages_th.js | 35 + .../validate/localization/messages_th.min.js | 4 + .../validate/localization/messages_tj.js | 35 + .../validate/localization/messages_tj.min.js | 4 + .../validate/localization/messages_tr.js | 36 + .../validate/localization/messages_tr.min.js | 4 + .../validate/localization/messages_uk.js | 35 + .../validate/localization/messages_uk.min.js | 4 + .../validate/localization/messages_vi.js | 35 + .../validate/localization/messages_vi.min.js | 4 + .../validate/localization/messages_zh.js | 35 + .../validate/localization/messages_zh.min.js | 4 + .../validate/localization/messages_zh_TW.js | 36 + .../localization/messages_zh_TW.min.js | 4 + .../validate/localization/methods_de.js | 24 + .../validate/localization/methods_de.min.js | 4 + .../validate/localization/methods_es_CL.js | 24 + .../localization/methods_es_CL.min.js | 4 + .../validate/localization/methods_fi.js | 24 + .../validate/localization/methods_fi.min.js | 4 + .../validate/localization/methods_nl.js | 21 + .../validate/localization/methods_nl.min.js | 4 + .../validate/localization/methods_pt.js | 21 + .../validate/localization/methods_pt.min.js | 4 + views/bootstrap/class.AddDocument.php | 13 +- views/bootstrap/class.EditFolder.php | 21 +- views/bootstrap/class.EditUserData.php | 36 + views/bootstrap/class.Login.php | 24 +- views/bootstrap/class.UpdateDocument.php | 21 + 125 files changed, 5051 insertions(+), 15 deletions(-) create mode 100644 styles/bootstrap/validate/additional-methods.js create mode 100644 styles/bootstrap/validate/additional-methods.min.js create mode 100644 styles/bootstrap/validate/jquery.validate.js create mode 100644 styles/bootstrap/validate/jquery.validate.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ar.js create mode 100644 styles/bootstrap/validate/localization/messages_ar.min.js create mode 100644 styles/bootstrap/validate/localization/messages_bg.js create mode 100644 styles/bootstrap/validate/localization/messages_bg.min.js create mode 100644 styles/bootstrap/validate/localization/messages_bn_BD.js create mode 100644 styles/bootstrap/validate/localization/messages_bn_BD.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ca.js create mode 100644 styles/bootstrap/validate/localization/messages_ca.min.js create mode 100644 styles/bootstrap/validate/localization/messages_cs.js create mode 100644 styles/bootstrap/validate/localization/messages_cs.min.js create mode 100644 styles/bootstrap/validate/localization/messages_da.js create mode 100644 styles/bootstrap/validate/localization/messages_da.min.js create mode 100644 styles/bootstrap/validate/localization/messages_de.js create mode 100644 styles/bootstrap/validate/localization/messages_de.min.js create mode 100644 styles/bootstrap/validate/localization/messages_el.js create mode 100644 styles/bootstrap/validate/localization/messages_el.min.js create mode 100644 styles/bootstrap/validate/localization/messages_es.js create mode 100644 styles/bootstrap/validate/localization/messages_es.min.js create mode 100644 styles/bootstrap/validate/localization/messages_es_AR.js create mode 100644 styles/bootstrap/validate/localization/messages_es_AR.min.js create mode 100644 styles/bootstrap/validate/localization/messages_es_PE.js create mode 100644 styles/bootstrap/validate/localization/messages_es_PE.min.js create mode 100644 styles/bootstrap/validate/localization/messages_et.js create mode 100644 styles/bootstrap/validate/localization/messages_et.min.js create mode 100644 styles/bootstrap/validate/localization/messages_eu.js create mode 100644 styles/bootstrap/validate/localization/messages_eu.min.js create mode 100644 styles/bootstrap/validate/localization/messages_fa.js create mode 100644 styles/bootstrap/validate/localization/messages_fa.min.js create mode 100644 styles/bootstrap/validate/localization/messages_fi.js create mode 100644 styles/bootstrap/validate/localization/messages_fi.min.js create mode 100644 styles/bootstrap/validate/localization/messages_fr.js create mode 100644 styles/bootstrap/validate/localization/messages_fr.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ge.js create mode 100644 styles/bootstrap/validate/localization/messages_ge.min.js create mode 100644 styles/bootstrap/validate/localization/messages_gl.js create mode 100644 styles/bootstrap/validate/localization/messages_gl.min.js create mode 100644 styles/bootstrap/validate/localization/messages_he.js create mode 100644 styles/bootstrap/validate/localization/messages_he.min.js create mode 100644 styles/bootstrap/validate/localization/messages_hr.js create mode 100644 styles/bootstrap/validate/localization/messages_hr.min.js create mode 100644 styles/bootstrap/validate/localization/messages_hu.js create mode 100644 styles/bootstrap/validate/localization/messages_hu.min.js create mode 100644 styles/bootstrap/validate/localization/messages_hy_AM.js create mode 100644 styles/bootstrap/validate/localization/messages_hy_AM.min.js create mode 100644 styles/bootstrap/validate/localization/messages_id.js create mode 100644 styles/bootstrap/validate/localization/messages_id.min.js create mode 100644 styles/bootstrap/validate/localization/messages_is.js create mode 100644 styles/bootstrap/validate/localization/messages_is.min.js create mode 100644 styles/bootstrap/validate/localization/messages_it.js create mode 100644 styles/bootstrap/validate/localization/messages_it.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ja.js create mode 100644 styles/bootstrap/validate/localization/messages_ja.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ka.js create mode 100644 styles/bootstrap/validate/localization/messages_ka.min.js create mode 100644 styles/bootstrap/validate/localization/messages_kk.js create mode 100644 styles/bootstrap/validate/localization/messages_kk.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ko.js create mode 100644 styles/bootstrap/validate/localization/messages_ko.min.js create mode 100644 styles/bootstrap/validate/localization/messages_lt.js create mode 100644 styles/bootstrap/validate/localization/messages_lt.min.js create mode 100644 styles/bootstrap/validate/localization/messages_lv.js create mode 100644 styles/bootstrap/validate/localization/messages_lv.min.js create mode 100644 styles/bootstrap/validate/localization/messages_mk.js create mode 100644 styles/bootstrap/validate/localization/messages_mk.min.js create mode 100644 styles/bootstrap/validate/localization/messages_my.js create mode 100644 styles/bootstrap/validate/localization/messages_my.min.js create mode 100644 styles/bootstrap/validate/localization/messages_nl.js create mode 100644 styles/bootstrap/validate/localization/messages_nl.min.js create mode 100644 styles/bootstrap/validate/localization/messages_no.js create mode 100644 styles/bootstrap/validate/localization/messages_no.min.js create mode 100644 styles/bootstrap/validate/localization/messages_pl.js create mode 100644 styles/bootstrap/validate/localization/messages_pl.min.js create mode 100644 styles/bootstrap/validate/localization/messages_pt_BR.js create mode 100644 styles/bootstrap/validate/localization/messages_pt_BR.min.js create mode 100644 styles/bootstrap/validate/localization/messages_pt_PT.js create mode 100644 styles/bootstrap/validate/localization/messages_pt_PT.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ro.js create mode 100644 styles/bootstrap/validate/localization/messages_ro.min.js create mode 100644 styles/bootstrap/validate/localization/messages_ru.js create mode 100644 styles/bootstrap/validate/localization/messages_ru.min.js create mode 100644 styles/bootstrap/validate/localization/messages_si.js create mode 100644 styles/bootstrap/validate/localization/messages_si.min.js create mode 100644 styles/bootstrap/validate/localization/messages_sk.js create mode 100644 styles/bootstrap/validate/localization/messages_sk.min.js create mode 100644 styles/bootstrap/validate/localization/messages_sl.js create mode 100644 styles/bootstrap/validate/localization/messages_sl.min.js create mode 100644 styles/bootstrap/validate/localization/messages_sr.js create mode 100644 styles/bootstrap/validate/localization/messages_sr.min.js create mode 100644 styles/bootstrap/validate/localization/messages_sr_lat.js create mode 100644 styles/bootstrap/validate/localization/messages_sr_lat.min.js create mode 100644 styles/bootstrap/validate/localization/messages_sv.js create mode 100644 styles/bootstrap/validate/localization/messages_sv.min.js create mode 100644 styles/bootstrap/validate/localization/messages_th.js create mode 100644 styles/bootstrap/validate/localization/messages_th.min.js create mode 100644 styles/bootstrap/validate/localization/messages_tj.js create mode 100644 styles/bootstrap/validate/localization/messages_tj.min.js create mode 100644 styles/bootstrap/validate/localization/messages_tr.js create mode 100644 styles/bootstrap/validate/localization/messages_tr.min.js create mode 100644 styles/bootstrap/validate/localization/messages_uk.js create mode 100644 styles/bootstrap/validate/localization/messages_uk.min.js create mode 100644 styles/bootstrap/validate/localization/messages_vi.js create mode 100644 styles/bootstrap/validate/localization/messages_vi.min.js create mode 100644 styles/bootstrap/validate/localization/messages_zh.js create mode 100644 styles/bootstrap/validate/localization/messages_zh.min.js create mode 100644 styles/bootstrap/validate/localization/messages_zh_TW.js create mode 100644 styles/bootstrap/validate/localization/messages_zh_TW.min.js create mode 100644 styles/bootstrap/validate/localization/methods_de.js create mode 100644 styles/bootstrap/validate/localization/methods_de.min.js create mode 100644 styles/bootstrap/validate/localization/methods_es_CL.js create mode 100644 styles/bootstrap/validate/localization/methods_es_CL.min.js create mode 100644 styles/bootstrap/validate/localization/methods_fi.js create mode 100644 styles/bootstrap/validate/localization/methods_fi.min.js create mode 100644 styles/bootstrap/validate/localization/methods_nl.js create mode 100644 styles/bootstrap/validate/localization/methods_nl.min.js create mode 100644 styles/bootstrap/validate/localization/methods_pt.js create mode 100644 styles/bootstrap/validate/localization/methods_pt.min.js diff --git a/styles/bootstrap/validate/additional-methods.js b/styles/bootstrap/validate/additional-methods.js new file mode 100644 index 000000000..7342e9753 --- /dev/null +++ b/styles/bootstrap/validate/additional-methods.js @@ -0,0 +1,1069 @@ +/*! + * jQuery Validation Plugin v1.15.1 + * + * http://jqueryvalidation.org/ + * + * Copyright (c) 2016 Jörn Zaefferer + * Released under the MIT license + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "./jquery.validate"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +( function() { + + function stripHtml( value ) { + + // Remove html tags and space chars + return value.replace( /<.[^<>]*?>/g, " " ).replace( / | /gi, " " ) + + // Remove punctuation + .replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" ); + } + + $.validator.addMethod( "maxWords", function( value, element, params ) { + return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params; + }, $.validator.format( "Please enter {0} words or less." ) ); + + $.validator.addMethod( "minWords", function( value, element, params ) { + return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params; + }, $.validator.format( "Please enter at least {0} words." ) ); + + $.validator.addMethod( "rangeWords", function( value, element, params ) { + var valueStripped = stripHtml( value ), + regex = /\b\w+\b/g; + return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ]; + }, $.validator.format( "Please enter between {0} and {1} words." ) ); + +}() ); + +// Accept a value from a file input based on a required mimetype +$.validator.addMethod( "accept", function( value, element, param ) { + + // Split mime on commas in case we have multiple types we can accept + var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*", + optionalValue = this.optional( element ), + i, file, regex; + + // Element is optional + if ( optionalValue ) { + return optionalValue; + } + + if ( $( element ).attr( "type" ) === "file" ) { + + // Escape string to be used in the regex + // see: http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex + // Escape also "/*" as "/.*" as a wildcard + typeParam = typeParam + .replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" ) + .replace( /,/g, "|" ) + .replace( /\/\*/g, "/.*" ); + + // Check if the element has a FileList before checking each file + if ( element.files && element.files.length ) { + regex = new RegExp( ".?(" + typeParam + ")$", "i" ); + for ( i = 0; i < element.files.length; i++ ) { + file = element.files[ i ]; + + // Grab the mimetype from the loaded file, verify it matches + if ( !file.type.match( regex ) ) { + return false; + } + } + } + } + + // Either return true because we've validated each file, or because the + // browser does not support element.files and the FileList feature + return true; +}, $.validator.format( "Please enter a value with a valid mimetype." ) ); + +$.validator.addMethod( "alphanumeric", function( value, element ) { + return this.optional( element ) || /^\w+$/i.test( value ); +}, "Letters, numbers, and underscores only please" ); + +/* + * Dutch bank account numbers (not 'giro' numbers) have 9 digits + * and pass the '11 check'. + * We accept the notation with spaces, as that is common. + * acceptable: 123456789 or 12 34 56 789 + */ +$.validator.addMethod( "bankaccountNL", function( value, element ) { + if ( this.optional( element ) ) { + return true; + } + if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) { + return false; + } + + // Now '11 check' + var account = value.replace( / /g, "" ), // Remove spaces + sum = 0, + len = account.length, + pos, factor, digit; + for ( pos = 0; pos < len; pos++ ) { + factor = len - pos; + digit = account.substring( pos, pos + 1 ); + sum = sum + factor * digit; + } + return sum % 11 === 0; +}, "Please specify a valid bank account number" ); + +$.validator.addMethod( "bankorgiroaccountNL", function( value, element ) { + return this.optional( element ) || + ( $.validator.methods.bankaccountNL.call( this, value, element ) ) || + ( $.validator.methods.giroaccountNL.call( this, value, element ) ); +}, "Please specify a valid bank or giro account number" ); + +/** + * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity. + * + * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional) + * + * Validation is case-insensitive. Please make sure to normalize input yourself. + * + * BIC definition in detail: + * - First 4 characters - bank code (only letters) + * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters) + * - Next 2 characters - location code (letters and digits) + * a. shall not start with '0' or '1' + * b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing) + * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits) + */ +$.validator.addMethod( "bic", function( value, element ) { + return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() ); +}, "Please specify a valid BIC code" ); + +/* + * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities + * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal + */ +$.validator.addMethod( "cifES", function( value ) { + "use strict"; + + var num = [], + controlDigit, sum, i, count, tmp, secondDigit; + + value = value.toUpperCase(); + + // Quick format test + if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) { + return false; + } + + for ( i = 0; i < 9; i++ ) { + num[ i ] = parseInt( value.charAt( i ), 10 ); + } + + // Algorithm for checking CIF codes + sum = num[ 2 ] + num[ 4 ] + num[ 6 ]; + for ( count = 1; count < 8; count += 2 ) { + tmp = ( 2 * num[ count ] ).toString(); + secondDigit = tmp.charAt( 1 ); + + sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) ); + } + + /* The first (position 1) is a letter following the following criteria: + * A. Corporations + * B. LLCs + * C. General partnerships + * D. Companies limited partnerships + * E. Communities of goods + * F. Cooperative Societies + * G. Associations + * H. Communities of homeowners in horizontal property regime + * J. Civil Societies + * K. Old format + * L. Old format + * M. Old format + * N. Nonresident entities + * P. Local authorities + * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions + * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008) + * S. Organs of State Administration and regions + * V. Agrarian Transformation + * W. Permanent establishments of non-resident in Spain + */ + if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) { + sum += ""; + controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 ); + value += controlDigit; + return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) ); + } + + return false; + +}, "Please specify a valid CIF number." ); + +/* + * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number. + * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation. + */ +$.validator.addMethod( "cpfBR", function( value ) { + + // Removing special characters from value + value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); + + // Checking value to have 11 digits only + if ( value.length !== 11 ) { + return false; + } + + var sum = 0, + firstCN, secondCN, checkResult, i; + + firstCN = parseInt( value.substring( 9, 10 ), 10 ); + secondCN = parseInt( value.substring( 10, 11 ), 10 ); + + checkResult = function( sum, cn ) { + var result = ( sum * 10 ) % 11; + if ( ( result === 10 ) || ( result === 11 ) ) { + result = 0; + } + return ( result === cn ); + }; + + // Checking for dump data + if ( value === "" || + value === "00000000000" || + value === "11111111111" || + value === "22222222222" || + value === "33333333333" || + value === "44444444444" || + value === "55555555555" || + value === "66666666666" || + value === "77777777777" || + value === "88888888888" || + value === "99999999999" + ) { + return false; + } + + // Step 1 - using first Check Number: + for ( i = 1; i <= 9; i++ ) { + sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i ); + } + + // If first Check Number (CN) is valid, move to Step 2 - using second Check Number: + if ( checkResult( sum, firstCN ) ) { + sum = 0; + for ( i = 1; i <= 10; i++ ) { + sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i ); + } + return checkResult( sum, secondCN ); + } + return false; + +}, "Please specify a valid CPF number" ); + +// http://jqueryvalidation.org/creditcard-method/ +// based on http://en.wikipedia.org/wiki/Luhn_algorithm +$.validator.addMethod( "creditcard", function( value, element ) { + if ( this.optional( element ) ) { + return "dependency-mismatch"; + } + + // Accept only spaces, digits and dashes + if ( /[^0-9 \-]+/.test( value ) ) { + return false; + } + + var nCheck = 0, + nDigit = 0, + bEven = false, + n, cDigit; + + value = value.replace( /\D/g, "" ); + + // Basing min and max length on + // http://developer.ean.com/general_info/Valid_Credit_Card_Types + if ( value.length < 13 || value.length > 19 ) { + return false; + } + + for ( n = value.length - 1; n >= 0; n-- ) { + cDigit = value.charAt( n ); + nDigit = parseInt( cDigit, 10 ); + if ( bEven ) { + if ( ( nDigit *= 2 ) > 9 ) { + nDigit -= 9; + } + } + + nCheck += nDigit; + bEven = !bEven; + } + + return ( nCheck % 10 ) === 0; +}, "Please enter a valid credit card number." ); + +/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator + * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 + * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) + */ +$.validator.addMethod( "creditcardtypes", function( value, element, param ) { + if ( /[^0-9\-]+/.test( value ) ) { + return false; + } + + value = value.replace( /\D/g, "" ); + + var validTypes = 0x0000; + + if ( param.mastercard ) { + validTypes |= 0x0001; + } + if ( param.visa ) { + validTypes |= 0x0002; + } + if ( param.amex ) { + validTypes |= 0x0004; + } + if ( param.dinersclub ) { + validTypes |= 0x0008; + } + if ( param.enroute ) { + validTypes |= 0x0010; + } + if ( param.discover ) { + validTypes |= 0x0020; + } + if ( param.jcb ) { + validTypes |= 0x0040; + } + if ( param.unknown ) { + validTypes |= 0x0080; + } + if ( param.all ) { + validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; + } + if ( validTypes & 0x0001 && /^(5[12345])/.test( value ) ) { // Mastercard + return value.length === 16; + } + if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa + return value.length === 16; + } + if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex + return value.length === 15; + } + if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub + return value.length === 14; + } + if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute + return value.length === 15; + } + if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover + return value.length === 16; + } + if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb + return value.length === 16; + } + if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb + return value.length === 15; + } + if ( validTypes & 0x0080 ) { // Unknown + return true; + } + return false; +}, "Please enter a valid credit card number." ); + +/** + * Validates currencies with any given symbols by @jameslouiz + * Symbols can be optional or required. Symbols required by default + * + * Usage examples: + * currency: ["£", false] - Use false for soft currency validation + * currency: ["$", false] + * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc + * + * + * + * Soft symbol checking + * currencyInput: { + * currency: ["$", false] + * } + * + * Strict symbol checking (default) + * currencyInput: { + * currency: "$" + * //OR + * currency: ["$", true] + * } + * + * Multiple Symbols + * currencyInput: { + * currency: "$,£,¢" + * } + */ +$.validator.addMethod( "currency", function( value, element, param ) { + var isParamString = typeof param === "string", + symbol = isParamString ? param : param[ 0 ], + soft = isParamString ? true : param[ 1 ], + regex; + + symbol = symbol.replace( /,/g, "" ); + symbol = soft ? symbol + "]" : symbol + "]?"; + regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$"; + regex = new RegExp( regex ); + return this.optional( element ) || regex.test( value ); + +}, "Please specify a valid currency" ); + +$.validator.addMethod( "dateFA", function( value, element ) { + return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value ); +}, $.validator.messages.date ); + +/** + * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. + * + * @example $.validator.methods.date("01/01/1900") + * @result true + * + * @example $.validator.methods.date("01/13/1990") + * @result false + * + * @example $.validator.methods.date("01.01.1900") + * @result false + * + * @example + * @desc Declares an optional input element whose value must be a valid date. + * + * @name $.validator.methods.dateITA + * @type Boolean + * @cat Plugins/Validate/Methods + */ +$.validator.addMethod( "dateITA", function( value, element ) { + var check = false, + re = /^\d{1,2}\/\d{1,2}\/\d{4}$/, + adata, gg, mm, aaaa, xdata; + if ( re.test( value ) ) { + adata = value.split( "/" ); + gg = parseInt( adata[ 0 ], 10 ); + mm = parseInt( adata[ 1 ], 10 ); + aaaa = parseInt( adata[ 2 ], 10 ); + xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) ); + if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) { + check = true; + } else { + check = false; + } + } else { + check = false; + } + return this.optional( element ) || check; +}, $.validator.messages.date ); + +$.validator.addMethod( "dateNL", function( value, element ) { + return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value ); +}, $.validator.messages.date ); + +// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept +$.validator.addMethod( "extension", function( value, element, param ) { + param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif"; + return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) ); +}, $.validator.format( "Please enter a value with a valid extension." ) ); + +/** + * Dutch giro account numbers (not bank numbers) have max 7 digits + */ +$.validator.addMethod( "giroaccountNL", function( value, element ) { + return this.optional( element ) || /^[0-9]{1,7}$/.test( value ); +}, "Please specify a valid giro account number" ); + +/** + * IBAN is the international bank account number. + * It has a country - specific format, that is checked here too + * + * Validation is case-insensitive. Please make sure to normalize input yourself. + */ +$.validator.addMethod( "iban", function( value, element ) { + + // Some quick simple tests to prevent needless work + if ( this.optional( element ) ) { + return true; + } + + // Remove spaces and to upper case + var iban = value.replace( / /g, "" ).toUpperCase(), + ibancheckdigits = "", + leadingZeroes = true, + cRest = "", + cOperator = "", + countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p; + + // Check for IBAN code length. + // It contains: + // country code ISO 3166-1 - two letters, + // two check digits, + // Basic Bank Account Number (BBAN) - up to 30 chars + var minimalIBANlength = 5; + if ( iban.length < minimalIBANlength ) { + return false; + } + + // Check the country code and find the country specific format + countrycode = iban.substring( 0, 2 ); + bbancountrypatterns = { + "AL": "\\d{8}[\\dA-Z]{16}", + "AD": "\\d{8}[\\dA-Z]{12}", + "AT": "\\d{16}", + "AZ": "[\\dA-Z]{4}\\d{20}", + "BE": "\\d{12}", + "BH": "[A-Z]{4}[\\dA-Z]{14}", + "BA": "\\d{16}", + "BR": "\\d{23}[A-Z][\\dA-Z]", + "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}", + "CR": "\\d{17}", + "HR": "\\d{17}", + "CY": "\\d{8}[\\dA-Z]{16}", + "CZ": "\\d{20}", + "DK": "\\d{14}", + "DO": "[A-Z]{4}\\d{20}", + "EE": "\\d{16}", + "FO": "\\d{14}", + "FI": "\\d{14}", + "FR": "\\d{10}[\\dA-Z]{11}\\d{2}", + "GE": "[\\dA-Z]{2}\\d{16}", + "DE": "\\d{18}", + "GI": "[A-Z]{4}[\\dA-Z]{15}", + "GR": "\\d{7}[\\dA-Z]{16}", + "GL": "\\d{14}", + "GT": "[\\dA-Z]{4}[\\dA-Z]{20}", + "HU": "\\d{24}", + "IS": "\\d{22}", + "IE": "[\\dA-Z]{4}\\d{14}", + "IL": "\\d{19}", + "IT": "[A-Z]\\d{10}[\\dA-Z]{12}", + "KZ": "\\d{3}[\\dA-Z]{13}", + "KW": "[A-Z]{4}[\\dA-Z]{22}", + "LV": "[A-Z]{4}[\\dA-Z]{13}", + "LB": "\\d{4}[\\dA-Z]{20}", + "LI": "\\d{5}[\\dA-Z]{12}", + "LT": "\\d{16}", + "LU": "\\d{3}[\\dA-Z]{13}", + "MK": "\\d{3}[\\dA-Z]{10}\\d{2}", + "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}", + "MR": "\\d{23}", + "MU": "[A-Z]{4}\\d{19}[A-Z]{3}", + "MC": "\\d{10}[\\dA-Z]{11}\\d{2}", + "MD": "[\\dA-Z]{2}\\d{18}", + "ME": "\\d{18}", + "NL": "[A-Z]{4}\\d{10}", + "NO": "\\d{11}", + "PK": "[\\dA-Z]{4}\\d{16}", + "PS": "[\\dA-Z]{4}\\d{21}", + "PL": "\\d{24}", + "PT": "\\d{21}", + "RO": "[A-Z]{4}[\\dA-Z]{16}", + "SM": "[A-Z]\\d{10}[\\dA-Z]{12}", + "SA": "\\d{2}[\\dA-Z]{18}", + "RS": "\\d{18}", + "SK": "\\d{20}", + "SI": "\\d{15}", + "ES": "\\d{20}", + "SE": "\\d{20}", + "CH": "\\d{5}[\\dA-Z]{12}", + "TN": "\\d{20}", + "TR": "\\d{5}[\\dA-Z]{17}", + "AE": "\\d{3}\\d{16}", + "GB": "[A-Z]{4}\\d{14}", + "VG": "[\\dA-Z]{4}\\d{16}" + }; + + bbanpattern = bbancountrypatterns[ countrycode ]; + + // As new countries will start using IBAN in the + // future, we only check if the countrycode is known. + // This prevents false negatives, while almost all + // false positives introduced by this, will be caught + // by the checksum validation below anyway. + // Strict checking should return FALSE for unknown + // countries. + if ( typeof bbanpattern !== "undefined" ) { + ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" ); + if ( !( ibanregexp.test( iban ) ) ) { + return false; // Invalid country specific format + } + } + + // Now check the checksum, first convert to digits + ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 ); + for ( i = 0; i < ibancheck.length; i++ ) { + charAt = ibancheck.charAt( i ); + if ( charAt !== "0" ) { + leadingZeroes = false; + } + if ( !leadingZeroes ) { + ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt ); + } + } + + // Calculate the result of: ibancheckdigits % 97 + for ( p = 0; p < ibancheckdigits.length; p++ ) { + cChar = ibancheckdigits.charAt( p ); + cOperator = "" + cRest + "" + cChar; + cRest = cOperator % 97; + } + return cRest === 1; +}, "Please specify a valid IBAN" ); + +$.validator.addMethod( "integer", function( value, element ) { + return this.optional( element ) || /^-?\d+$/.test( value ); +}, "A positive or negative non-decimal number please" ); + +$.validator.addMethod( "ipv4", function( value, element ) { + return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value ); +}, "Please enter a valid IP v4 address." ); + +$.validator.addMethod( "ipv6", function( value, element ) { + return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value ); +}, "Please enter a valid IP v6 address." ); + +$.validator.addMethod( "lettersonly", function( value, element ) { + return this.optional( element ) || /^[a-z]+$/i.test( value ); +}, "Letters only please" ); + +$.validator.addMethod( "letterswithbasicpunc", function( value, element ) { + return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value ); +}, "Letters or punctuation only please" ); + +$.validator.addMethod( "mobileNL", function( value, element ) { + return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); +}, "Please specify a valid mobile number" ); + +/* For UK phone functions, do the following server side processing: + * Compare original input with this RegEx pattern: + * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ + * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0' + * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. + * A number of very detailed GB telephone number RegEx patterns can also be found at: + * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers + */ +$.validator.addMethod( "mobileUK", function( phone_number, element ) { + phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); + return this.optional( element ) || phone_number.length > 9 && + phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ ); +}, "Please specify a valid mobile number" ); + +/* + * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain + */ +$.validator.addMethod( "nieES", function( value ) { + "use strict"; + + value = value.toUpperCase(); + + // Basic format test + if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) { + return false; + } + + // Test NIE + //T + if ( /^[T]{1}/.test( value ) ) { + return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) ); + } + + //XYZ + if ( /^[XYZ]{1}/.test( value ) ) { + return ( + value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( + value.replace( "X", "0" ) + .replace( "Y", "1" ) + .replace( "Z", "2" ) + .substring( 0, 8 ) % 23 + ) + ); + } + + return false; + +}, "Please specify a valid NIE number." ); + +/* + * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals + */ +$.validator.addMethod( "nifES", function( value ) { + "use strict"; + + value = value.toUpperCase(); + + // Basic format test + if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) { + return false; + } + + // Test NIF + if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) { + return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) ); + } + + // Test specials NIF (starts with K, L or M) + if ( /^[KLM]{1}/.test( value ) ) { + return ( value[ 8 ] === String.fromCharCode( 64 ) ); + } + + return false; + +}, "Please specify a valid NIF number." ); + +$.validator.addMethod( "notEqualTo", function( value, element, param ) { + return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param ); +}, "Please enter a different value, values must not be the same." ); + +$.validator.addMethod( "nowhitespace", function( value, element ) { + return this.optional( element ) || /^\S+$/i.test( value ); +}, "No white space please" ); + +/** +* Return true if the field value matches the given format RegExp +* +* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/) +* @result true +* +* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/) +* @result false +* +* @name $.validator.methods.pattern +* @type Boolean +* @cat Plugins/Validate/Methods +*/ +$.validator.addMethod( "pattern", function( value, element, param ) { + if ( this.optional( element ) ) { + return true; + } + if ( typeof param === "string" ) { + param = new RegExp( "^(?:" + param + ")$" ); + } + return param.test( value ); +}, "Invalid format." ); + +/** + * Dutch phone numbers have 10 digits (or 11 and start with +31). + */ +$.validator.addMethod( "phoneNL", function( value, element ) { + return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); +}, "Please specify a valid phone number." ); + +/* For UK phone functions, do the following server side processing: + * Compare original input with this RegEx pattern: + * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ + * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0' + * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. + * A number of very detailed GB telephone number RegEx patterns can also be found at: + * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers + */ +$.validator.addMethod( "phoneUK", function( phone_number, element ) { + phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); + return this.optional( element ) || phone_number.length > 9 && + phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ ); +}, "Please specify a valid phone number" ); + +/** + * Matches US phone number format + * + * where the area code may not start with 1 and the prefix may not start with 1 + * allows '-' or ' ' as a separator and allows parens around area code + * some people may want to put a '1' in front of their number + * + * 1(212)-999-2345 or + * 212 999 2344 or + * 212-999-0983 + * + * but not + * 111-123-5434 + * and not + * 212 123 4567 + */ +$.validator.addMethod( "phoneUS", function( phone_number, element ) { + phone_number = phone_number.replace( /\s+/g, "" ); + return this.optional( element ) || phone_number.length > 9 && + phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/ ); +}, "Please specify a valid phone number" ); + +/* For UK phone functions, do the following server side processing: + * Compare original input with this RegEx pattern: + * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ + * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0' + * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. + * A number of very detailed GB telephone number RegEx patterns can also be found at: + * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers + */ + +// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers +$.validator.addMethod( "phonesUK", function( phone_number, element ) { + phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); + return this.optional( element ) || phone_number.length > 9 && + phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ ); +}, "Please specify a valid uk phone number" ); + +/** + * Matches a valid Canadian Postal Code + * + * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element ) + * @result true + * + * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element ) + * @result false + * + * @name jQuery.validator.methods.postalCodeCA + * @type Boolean + * @cat Plugins/Validate/Methods + */ +$.validator.addMethod( "postalCodeCA", function( value, element ) { + return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value ); +}, "Please specify a valid postal code" ); + +/* +* Valida CEPs do brasileiros: +* +* Formatos aceitos: +* 99999-999 +* 99.999-999 +* 99999999 +*/ +$.validator.addMethod( "postalcodeBR", function( cep_value, element ) { + return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value ); +}, "Informe um CEP válido." ); + +/* Matches Italian postcode (CAP) */ +$.validator.addMethod( "postalcodeIT", function( value, element ) { + return this.optional( element ) || /^\d{5}$/.test( value ); +}, "Please specify a valid postal code" ); + +$.validator.addMethod( "postalcodeNL", function( value, element ) { + return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value ); +}, "Please specify a valid postal code" ); + +// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK) +$.validator.addMethod( "postcodeUK", function( value, element ) { + return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value ); +}, "Please specify a valid UK postcode" ); + +/* + * Lets you say "at least X inputs that match selector Y must be filled." + * + * The end result is that neither of these inputs: + * + * + * + * + * ...will validate unless at least one of them is filled. + * + * partnumber: {require_from_group: [1,".productinfo"]}, + * description: {require_from_group: [1,".productinfo"]} + * + * options[0]: number of fields that must be filled in the group + * options[1]: CSS selector that defines the group of conditionally required fields + */ +$.validator.addMethod( "require_from_group", function( value, element, options ) { + var $fields = $( options[ 1 ], element.form ), + $fieldsFirst = $fields.eq( 0 ), + validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ), + isValid = $fields.filter( function() { + return validator.elementValue( this ); + } ).length >= options[ 0 ]; + + // Store the cloned validator for future validation + $fieldsFirst.data( "valid_req_grp", validator ); + + // If element isn't being validated, run each require_from_group field's validation rules + if ( !$( element ).data( "being_validated" ) ) { + $fields.data( "being_validated", true ); + $fields.each( function() { + validator.element( this ); + } ); + $fields.data( "being_validated", false ); + } + return isValid; +}, $.validator.format( "Please fill at least {0} of these fields." ) ); + +/* + * Lets you say "either at least X inputs that match selector Y must be filled, + * OR they must all be skipped (left blank)." + * + * The end result, is that none of these inputs: + * + * + * + * + * + * ...will validate unless either at least two of them are filled, + * OR none of them are. + * + * partnumber: {skip_or_fill_minimum: [2,".productinfo"]}, + * description: {skip_or_fill_minimum: [2,".productinfo"]}, + * color: {skip_or_fill_minimum: [2,".productinfo"]} + * + * options[0]: number of fields that must be filled in the group + * options[1]: CSS selector that defines the group of conditionally required fields + * + */ +$.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) { + var $fields = $( options[ 1 ], element.form ), + $fieldsFirst = $fields.eq( 0 ), + validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ), + numberFilled = $fields.filter( function() { + return validator.elementValue( this ); + } ).length, + isValid = numberFilled === 0 || numberFilled >= options[ 0 ]; + + // Store the cloned validator for future validation + $fieldsFirst.data( "valid_skip", validator ); + + // If element isn't being validated, run each skip_or_fill_minimum field's validation rules + if ( !$( element ).data( "being_validated" ) ) { + $fields.data( "being_validated", true ); + $fields.each( function() { + validator.element( this ); + } ); + $fields.data( "being_validated", false ); + } + return isValid; +}, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) ); + +/* Validates US States and/or Territories by @jdforsythe + * Can be case insensitive or require capitalization - default is case insensitive + * Can include US Territories or not - default does not + * Can include US Military postal abbreviations (AA, AE, AP) - default does not + * + * Note: "States" always includes DC (District of Colombia) + * + * Usage examples: + * + * This is the default - case insensitive, no territories, no military zones + * stateInput: { + * caseSensitive: false, + * includeTerritories: false, + * includeMilitary: false + * } + * + * Only allow capital letters, no territories, no military zones + * stateInput: { + * caseSensitive: false + * } + * + * Case insensitive, include territories but not military zones + * stateInput: { + * includeTerritories: true + * } + * + * Only allow capital letters, include territories and military zones + * stateInput: { + * caseSensitive: true, + * includeTerritories: true, + * includeMilitary: true + * } + * + */ +$.validator.addMethod( "stateUS", function( value, element, options ) { + var isDefault = typeof options === "undefined", + caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive, + includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories, + includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary, + regex; + + if ( !includeTerritories && !includeMilitary ) { + regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; + } else if ( includeTerritories && includeMilitary ) { + regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; + } else if ( includeTerritories ) { + regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; + } else { + regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; + } + + regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" ); + return this.optional( element ) || regex.test( value ); +}, "Please specify a valid state" ); + +// TODO check if value starts with <, otherwise don't try stripping anything +$.validator.addMethod( "strippedminlength", function( value, element, param ) { + return $( value ).text().length >= param; +}, $.validator.format( "Please enter at least {0} characters" ) ); + +$.validator.addMethod( "time", function( value, element ) { + return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value ); +}, "Please enter a valid time, between 00:00 and 23:59" ); + +$.validator.addMethod( "time12h", function( value, element ) { + return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value ); +}, "Please enter a valid time in 12-hour am/pm format" ); + +// Same as url, but TLD is optional +$.validator.addMethod( "url2", function( value, element ) { + return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value ); +}, $.validator.messages.url ); + +/** + * Return true, if the value is a valid vehicle identification number (VIN). + * + * Works with all kind of text inputs. + * + * @example + * @desc Declares a required input element whose value must be a valid vehicle identification number. + * + * @name $.validator.methods.vinUS + * @type Boolean + * @cat Plugins/Validate/Methods + */ +$.validator.addMethod( "vinUS", function( v ) { + if ( v.length !== 17 ) { + return false; + } + + var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ], + VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ], + FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ], + rs = 0, + i, n, d, f, cd, cdv; + + for ( i = 0; i < 17; i++ ) { + f = FL[ i ]; + d = v.slice( i, i + 1 ); + if ( i === 8 ) { + cdv = d; + } + if ( !isNaN( d ) ) { + d *= f; + } else { + for ( n = 0; n < LL.length; n++ ) { + if ( d.toUpperCase() === LL[ n ] ) { + d = VL[ n ]; + d *= f; + if ( isNaN( cdv ) && n === 8 ) { + cdv = LL[ n ]; + } + break; + } + } + } + rs += d; + } + cd = rs % 11; + if ( cd === 10 ) { + cd = "X"; + } + if ( cd === cdv ) { + return true; + } + return false; +}, "The specified vehicle identification number (VIN) is invalid." ); + +$.validator.addMethod( "zipcodeUS", function( value, element ) { + return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value ); +}, "The specified US ZIP Code is invalid" ); + +$.validator.addMethod( "ziprange", function( value, element ) { + return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value ); +}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" ); + +})); \ No newline at end of file diff --git a/styles/bootstrap/validate/additional-methods.min.js b/styles/bootstrap/validate/additional-methods.min.js new file mode 100644 index 000000000..b06943e6f --- /dev/null +++ b/styles/bootstrap/validate/additional-methods.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.15.1 - 7/22/2016 + * http://jqueryvalidation.org/ + * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;e<=9;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;e<=10;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.length9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):!!/^[XYZ]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23))},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]===String.fromCharCode(64))},"Please specify a valid NIF number."),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c
:
:
: - +