febc70dd by Jeff Balicki

Register

Signed-off-by: Jeff <jeff@gotenzing.com>
1 parent 179502c4
...@@ -1371,3 +1371,131 @@ ...@@ -1371,3 +1371,131 @@
1371 INFO [609b42a6] Finished in 0.254 seconds with exit status 0 (successful). 1371 INFO [609b42a6] Finished in 0.254 seconds with exit status 0 (successful).
1372 INFO [2f9fae7c] Running si crlg-staging as tenzing_www@web-1 1372 INFO [2f9fae7c] Running si crlg-staging as tenzing_www@web-1
1373 INFO [2f9fae7c] Finished in 2.035 seconds with exit status 0 (successful). 1373 INFO [2f9fae7c] Finished in 2.035 seconds with exit status 0 (successful).
1374 INFO ---------------------------------------------------------------------------
1375 INFO START 2023-02-09 11:08:07 -0500 cap staging deploy
1376 INFO ---------------------------------------------------------------------------
1377 INFO [c8b82cef] Running /usr/bin/env mkdir -p /tmp as tenzing_www@web-1
1378 INFO [c8b82cef] Finished in 1.213 seconds with exit status 0 (successful).
1379 INFO Uploading /tmp/git-ssh-crlg-staging-staging-jeffbalicki.sh 100.0%
1380 INFO [010d3b07] Running /usr/bin/env chmod 700 /tmp/git-ssh-crlg-staging-staging-jeffbalicki.sh as tenzing_www@web-1
1381 INFO [010d3b07] Finished in 0.218 seconds with exit status 0 (successful).
1382 INFO [4a61ffd7] Running /usr/bin/env git ls-remote git@git.gotenzing.com:jeffmbalicki/st_joseph.git HEAD as tenzing_www@web-1
1383 INFO [4a61ffd7] Finished in 0.984 seconds with exit status 0 (successful).
1384 INFO [c59fbc53] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared /var/www/html/production/crlg-staging/releases as tenzing_www@web-1
1385 INFO [c59fbc53] Finished in 0.218 seconds with exit status 0 (successful).
1386 INFO [ebd3994a] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared/wp-content/wflogs /var/www/html/production/crlg-staging/shared/wp-content/uploads /var/www/html/production/crlg-staging/shared/wp-content/storage /var/www/html/production/crlg-staging/shared/wp-content/languages /var/www/html/production/crlg-staging/shared/wp-content/cache /var/www/html/production/crlg-staging/shared/wp-content/wp-rocket-config as tenzing_www@web-1
1387 INFO [ebd3994a] Finished in 0.220 seconds with exit status 0 (successful).
1388 INFO [eeb7065d] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared as tenzing_www@web-1
1389 INFO [eeb7065d] Finished in 0.214 seconds with exit status 0 (successful).
1390 INFO The repository mirror is at /var/www/html/production/crlg-staging/repo
1391 INFO [236eeecc] Running /usr/bin/env git remote set-url origin git@git.gotenzing.com:jeffmbalicki/st_joseph.git as tenzing_www@web-1
1392 INFO [236eeecc] Finished in 0.216 seconds with exit status 0 (successful).
1393 INFO [3b07a640] Running /usr/bin/env git remote update --prune as tenzing_www@web-1
1394 INFO [3b07a640] Finished in 1.361 seconds with exit status 0 (successful).
1395 INFO [c1247579] Running /usr/bin/env git clone -b master --recursive . /var/www/html/production/crlg-staging/releases/20230209160812 as tenzing_www@web-1
1396 INFO [c1247579] Finished in 2.922 seconds with exit status 0 (successful).
1397 INFO [4aacc55f] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209160812 as tenzing_www@web-1
1398 INFO [4aacc55f] Finished in 0.213 seconds with exit status 0 (successful).
1399 INFO [c9f3a697] Running /usr/bin/env git archive master | /usr/bin/env tar -x -f - -C /var/www/html/production/crlg-staging/releases/20230209160812 as tenzing_www@web-1
1400 INFO [c9f3a697] Finished in 3.226 seconds with exit status 0 (successful).
1401 INFO [751cdea1] Running /usr/bin/env echo "473e875b039fbf87de18c031b6a73a8b36205077" >> REVISION as tenzing_www@web-1
1402 INFO [751cdea1] Finished in 0.204 seconds with exit status 0 (successful).
1403 INFO [48d1f6af] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209160812 as tenzing_www@web-1
1404 INFO [48d1f6af] Finished in 0.207 seconds with exit status 0 (successful).
1405 INFO [1ee45b5b] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/.env /var/www/html/production/crlg-staging/releases/20230209160812/.env as tenzing_www@web-1
1406 INFO [1ee45b5b] Finished in 0.210 seconds with exit status 0 (successful).
1407 INFO [207f6f9c] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209160812/wp-content as tenzing_www@web-1
1408 INFO [207f6f9c] Finished in 0.211 seconds with exit status 0 (successful).
1409 INFO [612f1cea] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/wflogs /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/wflogs as tenzing_www@web-1
1410 INFO [612f1cea] Finished in 0.209 seconds with exit status 0 (successful).
1411 INFO [cc5b8581] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/uploads /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/uploads as tenzing_www@web-1
1412 INFO [cc5b8581] Finished in 0.210 seconds with exit status 0 (successful).
1413 INFO [e101df07] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/storage /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/storage as tenzing_www@web-1
1414 INFO [e101df07] Finished in 0.208 seconds with exit status 0 (successful).
1415 INFO [1528b308] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/languages /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/languages as tenzing_www@web-1
1416 INFO [1528b308] Finished in 0.205 seconds with exit status 0 (successful).
1417 INFO [ab14785f] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/cache /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/cache as tenzing_www@web-1
1418 INFO [ab14785f] Finished in 0.217 seconds with exit status 0 (successful).
1419 INFO [e23d8c0b] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/wp-rocket-config /var/www/html/production/crlg-staging/releases/20230209160812/wp-content/wp-rocket-config as tenzing_www@web-1
1420 INFO [e23d8c0b] Finished in 0.209 seconds with exit status 0 (successful).
1421 INFO [9914b2e7] Running cd '/var/www/html/production/crlg-staging/releases/20230209160812'; /usr/bin/php73 /home/tenzing_www/composer.phar install --no-dev --prefer-dist --no-interaction --quiet --optimize-autoloader as tenzing_www@web-1
1422 INFO [9914b2e7] Finished in 1.096 seconds with exit status 0 (successful).
1423 INFO [d34e7615] Running si crlg-staging as tenzing_www@web-1
1424 INFO [d34e7615] Finished in 12.494 seconds with exit status 0 (successful).
1425 INFO [c2693765] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/releases/20230209160812 /var/www/html/production/crlg-staging/releases/current as tenzing_www@web-1
1426 INFO [c2693765] Finished in 0.335 seconds with exit status 0 (successful).
1427 INFO [d30f6e75] Running /usr/bin/env mv /var/www/html/production/crlg-staging/releases/current /var/www/html/production/crlg-staging as tenzing_www@web-1
1428 INFO [d30f6e75] Finished in 0.216 seconds with exit status 0 (successful).
1429 INFO Keeping 2 of 3 deployed releases on web-1
1430 INFO [02e53234] Running /usr/bin/env rm -rf /var/www/html/production/crlg-staging/releases/20230208203926 as tenzing_www@web-1
1431 INFO [02e53234] Finished in 0.957 seconds with exit status 0 (successful).
1432 INFO [5e2e8428] Running cd '/var/www/html/production/crlg-staging/releases/20230209160812/'; rm -Rf .git/ as tenzing_www@web-1
1433 INFO [5e2e8428] Finished in 0.244 seconds with exit status 0 (successful).
1434 INFO [3a50ae5c] Running /usr/bin/env echo "Branch master (at 473e875b039fbf87de18c031b6a73a8b36205077) deployed as release 20230209160812 by jeffbalicki" >> /var/www/html/production/crlg-staging/revisions.log as tenzing_www@web-1
1435 INFO [3a50ae5c] Finished in 0.212 seconds with exit status 0 (successful).
1436 INFO [7a4a2f05] Running si crlg-staging as tenzing_www@web-1
1437 INFO [7a4a2f05] Finished in 2.100 seconds with exit status 0 (successful).
1438 INFO ---------------------------------------------------------------------------
1439 INFO START 2023-02-09 11:45:41 -0500 cap staging deploy
1440 INFO ---------------------------------------------------------------------------
1441 INFO [d048b078] Running /usr/bin/env mkdir -p /tmp as tenzing_www@web-1
1442 INFO [d048b078] Finished in 1.357 seconds with exit status 0 (successful).
1443 INFO Uploading /tmp/git-ssh-crlg-staging-staging-jeffbalicki.sh 100.0%
1444 INFO [d3327483] Running /usr/bin/env chmod 700 /tmp/git-ssh-crlg-staging-staging-jeffbalicki.sh as tenzing_www@web-1
1445 INFO [d3327483] Finished in 0.240 seconds with exit status 0 (successful).
1446 INFO [969917a5] Running /usr/bin/env git ls-remote git@git.gotenzing.com:jeffmbalicki/st_joseph.git HEAD as tenzing_www@web-1
1447 INFO [969917a5] Finished in 1.093 seconds with exit status 0 (successful).
1448 INFO [0c18c23f] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared /var/www/html/production/crlg-staging/releases as tenzing_www@web-1
1449 INFO [0c18c23f] Finished in 0.260 seconds with exit status 0 (successful).
1450 INFO [3ad2c2d8] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared/wp-content/wflogs /var/www/html/production/crlg-staging/shared/wp-content/uploads /var/www/html/production/crlg-staging/shared/wp-content/storage /var/www/html/production/crlg-staging/shared/wp-content/languages /var/www/html/production/crlg-staging/shared/wp-content/cache /var/www/html/production/crlg-staging/shared/wp-content/wp-rocket-config as tenzing_www@web-1
1451 INFO [3ad2c2d8] Finished in 0.279 seconds with exit status 0 (successful).
1452 INFO [68e3e868] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/shared as tenzing_www@web-1
1453 INFO [68e3e868] Finished in 0.283 seconds with exit status 0 (successful).
1454 INFO The repository mirror is at /var/www/html/production/crlg-staging/repo
1455 INFO [1166b438] Running /usr/bin/env git remote set-url origin git@git.gotenzing.com:jeffmbalicki/st_joseph.git as tenzing_www@web-1
1456 INFO [1166b438] Finished in 0.278 seconds with exit status 0 (successful).
1457 INFO [71ebd24f] Running /usr/bin/env git remote update --prune as tenzing_www@web-1
1458 INFO [71ebd24f] Finished in 1.217 seconds with exit status 0 (successful).
1459 INFO [ab19b911] Running /usr/bin/env git clone -b master --recursive . /var/www/html/production/crlg-staging/releases/20230209164545 as tenzing_www@web-1
1460 INFO [ab19b911] Finished in 2.801 seconds with exit status 0 (successful).
1461 INFO [3df60a6c] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209164545 as tenzing_www@web-1
1462 INFO [3df60a6c] Finished in 0.256 seconds with exit status 0 (successful).
1463 INFO [b05114c3] Running /usr/bin/env git archive master | /usr/bin/env tar -x -f - -C /var/www/html/production/crlg-staging/releases/20230209164545 as tenzing_www@web-1
1464 INFO [b05114c3] Finished in 3.348 seconds with exit status 0 (successful).
1465 INFO [a6331c9f] Running /usr/bin/env echo "179502c4de81e1c0ac71d79a91a816fd4eb6fdfd" >> REVISION as tenzing_www@web-1
1466 INFO [a6331c9f] Finished in 0.255 seconds with exit status 0 (successful).
1467 INFO [9c945f01] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209164545 as tenzing_www@web-1
1468 INFO [9c945f01] Finished in 0.239 seconds with exit status 0 (successful).
1469 INFO [a2399eb4] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/.env /var/www/html/production/crlg-staging/releases/20230209164545/.env as tenzing_www@web-1
1470 INFO [a2399eb4] Finished in 0.266 seconds with exit status 0 (successful).
1471 INFO [46fced6a] Running /usr/bin/env mkdir -p /var/www/html/production/crlg-staging/releases/20230209164545/wp-content as tenzing_www@web-1
1472 INFO [46fced6a] Finished in 0.260 seconds with exit status 0 (successful).
1473 INFO [0342d87f] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/wflogs /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/wflogs as tenzing_www@web-1
1474 INFO [0342d87f] Finished in 0.279 seconds with exit status 0 (successful).
1475 INFO [eeb13e2b] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/uploads /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/uploads as tenzing_www@web-1
1476 INFO [eeb13e2b] Finished in 0.269 seconds with exit status 0 (successful).
1477 INFO [10e9bd39] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/storage /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/storage as tenzing_www@web-1
1478 INFO [10e9bd39] Finished in 0.256 seconds with exit status 0 (successful).
1479 INFO [2fe6115c] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/languages /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/languages as tenzing_www@web-1
1480 INFO [2fe6115c] Finished in 0.263 seconds with exit status 0 (successful).
1481 INFO [2276cb5b] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/cache /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/cache as tenzing_www@web-1
1482 INFO [2276cb5b] Finished in 0.254 seconds with exit status 0 (successful).
1483 INFO [5713a773] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/shared/wp-content/wp-rocket-config /var/www/html/production/crlg-staging/releases/20230209164545/wp-content/wp-rocket-config as tenzing_www@web-1
1484 INFO [5713a773] Finished in 0.250 seconds with exit status 0 (successful).
1485 INFO [84af6a6f] Running cd '/var/www/html/production/crlg-staging/releases/20230209164545'; /usr/bin/php73 /home/tenzing_www/composer.phar install --no-dev --prefer-dist --no-interaction --quiet --optimize-autoloader as tenzing_www@web-1
1486 INFO [84af6a6f] Finished in 1.094 seconds with exit status 0 (successful).
1487 INFO [1756b51a] Running si crlg-staging as tenzing_www@web-1
1488 INFO [1756b51a] Finished in 6.758 seconds with exit status 0 (successful).
1489 INFO [7b05e005] Running /usr/bin/env ln -s /var/www/html/production/crlg-staging/releases/20230209164545 /var/www/html/production/crlg-staging/releases/current as tenzing_www@web-1
1490 INFO [7b05e005] Finished in 0.451 seconds with exit status 0 (successful).
1491 INFO [52d5648c] Running /usr/bin/env mv /var/www/html/production/crlg-staging/releases/current /var/www/html/production/crlg-staging as tenzing_www@web-1
1492 INFO [52d5648c] Finished in 0.267 seconds with exit status 0 (successful).
1493 INFO Keeping 2 of 3 deployed releases on web-1
1494 INFO [2d7cfbbd] Running /usr/bin/env rm -rf /var/www/html/production/crlg-staging/releases/20230208204415 as tenzing_www@web-1
1495 INFO [2d7cfbbd] Finished in 1.270 seconds with exit status 0 (successful).
1496 INFO [53fada5c] Running cd '/var/www/html/production/crlg-staging/releases/20230209164545/'; rm -Rf .git/ as tenzing_www@web-1
1497 INFO [53fada5c] Finished in 0.276 seconds with exit status 0 (successful).
1498 INFO [bc1a2df3] Running /usr/bin/env echo "Branch master (at 179502c4de81e1c0ac71d79a91a816fd4eb6fdfd) deployed as release 20230209164545 by jeffbalicki" >> /var/www/html/production/crlg-staging/revisions.log as tenzing_www@web-1
1499 INFO [bc1a2df3] Finished in 0.252 seconds with exit status 0 (successful).
1500 INFO [7411291a] Running si crlg-staging as tenzing_www@web-1
1501 INFO [7411291a] Finished in 2.195 seconds with exit status 0 (successful).
......
...@@ -14654,6 +14654,10 @@ input[type=checkbox] { ...@@ -14654,6 +14654,10 @@ input[type=checkbox] {
14654 line-height: 34px !important; 14654 line-height: 34px !important;
14655 } 14655 }
14656 14656
14657 .woocommerce-form-register .error {
14658 color: red;
14659 }
14660
14657 .pre-header { 14661 .pre-header {
14658 background-color: #0484b8; 14662 background-color: #0484b8;
14659 color: #fff; 14663 color: #fff;
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
...@@ -134,11 +134,11 @@ function certs(){ ...@@ -134,11 +134,11 @@ function certs(){
134 function wooc_extra_register_fields() {?> 134 function wooc_extra_register_fields() {?>
135 <p class="form-row form-row-first"> 135 <p class="form-row form-row-first">
136 <label for="reg_billing_first_name"><?php _e( 'First name', 'woocommerce' ); ?><span class="required">*</span></label> 136 <label for="reg_billing_first_name"><?php _e( 'First name', 'woocommerce' ); ?><span class="required">*</span></label>
137 <input type="text" class="input-text" name="billing_first_name" id="reg_billing_first_name" value="<?php if ( ! empty( $_POST['billing_first_name'] ) ) esc_attr_e( $_POST['billing_first_name'] ); ?>" /> 137 <input type="text" class="woocommerce-Input woocommerce-Input--text input-text form-control" name="billing_first_name" id="reg_billing_first_name" value="<?php if ( ! empty( $_POST['billing_first_name'] ) ) esc_attr_e( $_POST['billing_first_name'] ); ?>" />
138 </p> 138 </p>
139 <p class="form-row form-row-last"> 139 <p class="form-row form-row-last">
140 <label for="reg_billing_last_name"><?php _e( 'Last name', 'woocommerce' ); ?><span class="required">*</span></label> 140 <label for="reg_billing_last_name"><?php _e( 'Last name', 'woocommerce' ); ?><span class="required">*</span></label>
141 <input type="text" class="input-text" name="billing_last_name" id="reg_billing_last_name" value="<?php if ( ! empty( $_POST['billing_last_name'] ) ) esc_attr_e( $_POST['billing_last_name'] ); ?>" /> 141 <input type="text" class="woocommerce-Input woocommerce-Input--text input-text form-control" name="billing_last_name" id="reg_billing_last_name" value="<?php if ( ! empty( $_POST['billing_last_name'] ) ) esc_attr_e( $_POST['billing_last_name'] ); ?>" />
142 </p> 142 </p>
143 <div class="clear"></div> 143 <div class="clear"></div>
144 <?php 144 <?php
...@@ -180,18 +180,22 @@ function wooc_save_extra_register_fields( $customer_id ) { ...@@ -180,18 +180,22 @@ function wooc_save_extra_register_fields( $customer_id ) {
180 } 180 }
181 add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' ); 181 add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' );
182 182
183 add_filter('woocommerce_registration_errors', 'registration_errors_validation', 10,3); 183
184
185
186
187 // ----- validate password match on the registration page
184 function registration_errors_validation($reg_errors, $sanitized_user_login, $user_email) { 188 function registration_errors_validation($reg_errors, $sanitized_user_login, $user_email) {
185 global $woocommerce; 189 global $woocommerce;
186 extract( $_POST ); 190 extract( $_POST );
187
188 if ( strcmp( $password, $password2 ) !== 0 ) { 191 if ( strcmp( $password, $password2 ) !== 0 ) {
189 return new WP_Error( 'registration-error', __( 'Passwords do not match.', 'woocommerce' ) ); 192 return new WP_Error( 'registration-error', __( 'Passwords do not match.', 'woocommerce' ) );
190 } 193 }
191 return $reg_errors; 194 return $reg_errors;
192 } 195 }
196 add_filter('woocommerce_registration_errors', 'registration_errors_validation', 10,3);
193 197
194 add_action( 'woocommerce_register_form', 'wc_register_form_password_repeat' ); 198 // ----- add a confirm password fields match on the registration page
195 function wc_register_form_password_repeat() { 199 function wc_register_form_password_repeat() {
196 ?> 200 ?>
197 <p class="form-row form-row-wide"> 201 <p class="form-row form-row-wide">
...@@ -200,4 +204,33 @@ function wc_register_form_password_repeat() { ...@@ -200,4 +204,33 @@ function wc_register_form_password_repeat() {
200 </p> 204 </p>
201 <?php 205 <?php
202 } 206 }
203 ?>
...\ No newline at end of file ...\ No newline at end of file
207 add_action( 'woocommerce_register_form', 'wc_register_form_password_repeat' );
208
209 // ----- Validate confirm password field match to the checkout page
210 function lit_woocommerce_confirm_password_validation( $posted ) {
211 $checkout = WC()->checkout;
212 if ( ! is_user_logged_in() && ( $checkout->must_create_account || ! empty( $posted['createaccount'] ) ) ) {
213 if ( strcmp( $posted['account_password'], $posted['account_confirm_password'] ) !== 0 ) {
214 wc_add_notice( __( 'Passwords do not match.', 'woocommerce' ), 'error' );
215 }
216 }
217 }
218 add_action( 'woocommerce_after_checkout_validation', 'lit_woocommerce_confirm_password_validation', 10, 2 );
219
220 // ----- Add a confirm password field to the checkout page
221 function lit_woocommerce_confirm_password_checkout( $checkout ) {
222 if ( get_option( 'woocommerce_registration_generate_password' ) == 'no' ) {
223
224 $fields = $checkout->get_checkout_fields();
225
226 $fields['account']['account_confirm_password'] = array(
227 'type' => 'password',
228 'label' => __( 'Confirm password', 'woocommerce' ),
229 'required' => true,
230 'placeholder' => _x( 'Confirm Password', 'placeholder', 'woocommerce' )
231 );
232
233 $checkout->__set( 'checkout_fields', $fields );
234 }
235 }
236 add_action( 'woocommerce_checkout_init', 'lit_woocommerce_confirm_password_checkout', 10, 1 );
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -26971,6 +26971,1671 @@ ...@@ -26971,6 +26971,1671 @@
26971 } 26971 }
26972 }; 26972 };
26973 26973
26974 var jquery_validate = {exports: {}};
26975
26976 /*!
26977 * jQuery Validation Plugin v1.19.5
26978 *
26979 * https://jqueryvalidation.org/
26980 *
26981 * Copyright (c) 2022 Jörn Zaefferer
26982 * Released under the MIT license
26983 */
26984
26985 (function (module) {
26986 (function( factory ) {
26987 if (module.exports) {
26988 module.exports = factory( $__default["default"] );
26989 } else {
26990 factory( jQuery );
26991 }
26992 }(function( $ ) {
26993
26994 $.extend( $.fn, {
26995
26996 // https://jqueryvalidation.org/validate/
26997 validate: function( options ) {
26998
26999 // If nothing is selected, return nothing; can't chain anyway
27000 if ( !this.length ) {
27001 if ( options && options.debug && window.console ) {
27002 console.warn( "Nothing selected, can't validate, returning nothing." );
27003 }
27004 return;
27005 }
27006
27007 // Check if a validator for this form was already created
27008 var validator = $.data( this[ 0 ], "validator" );
27009 if ( validator ) {
27010 return validator;
27011 }
27012
27013 // Add novalidate tag if HTML5.
27014 this.attr( "novalidate", "novalidate" );
27015
27016 validator = new $.validator( options, this[ 0 ] );
27017 $.data( this[ 0 ], "validator", validator );
27018
27019 if ( validator.settings.onsubmit ) {
27020
27021 this.on( "click.validate", ":submit", function( event ) {
27022
27023 // Track the used submit button to properly handle scripted
27024 // submits later.
27025 validator.submitButton = event.currentTarget;
27026
27027 // Allow suppressing validation by adding a cancel class to the submit button
27028 if ( $( this ).hasClass( "cancel" ) ) {
27029 validator.cancelSubmit = true;
27030 }
27031
27032 // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
27033 if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
27034 validator.cancelSubmit = true;
27035 }
27036 } );
27037
27038 // Validate the form on submit
27039 this.on( "submit.validate", function( event ) {
27040 if ( validator.settings.debug ) {
27041
27042 // Prevent form submit to be able to see console output
27043 event.preventDefault();
27044 }
27045
27046 function handle() {
27047 var hidden, result;
27048
27049 // Insert a hidden input as a replacement for the missing submit button
27050 // The hidden input is inserted in two cases:
27051 // - A user defined a `submitHandler`
27052 // - There was a pending request due to `remote` method and `stopRequest()`
27053 // was called to submit the form in case it's valid
27054 if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
27055 hidden = $( "<input type='hidden'/>" )
27056 .attr( "name", validator.submitButton.name )
27057 .val( $( validator.submitButton ).val() )
27058 .appendTo( validator.currentForm );
27059 }
27060
27061 if ( validator.settings.submitHandler && !validator.settings.debug ) {
27062 result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
27063 if ( hidden ) {
27064
27065 // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
27066 hidden.remove();
27067 }
27068 if ( result !== undefined ) {
27069 return result;
27070 }
27071 return false;
27072 }
27073 return true;
27074 }
27075
27076 // Prevent submit for invalid forms or custom submit handlers
27077 if ( validator.cancelSubmit ) {
27078 validator.cancelSubmit = false;
27079 return handle();
27080 }
27081 if ( validator.form() ) {
27082 if ( validator.pendingRequest ) {
27083 validator.formSubmitted = true;
27084 return false;
27085 }
27086 return handle();
27087 } else {
27088 validator.focusInvalid();
27089 return false;
27090 }
27091 } );
27092 }
27093
27094 return validator;
27095 },
27096
27097 // https://jqueryvalidation.org/valid/
27098 valid: function() {
27099 var valid, validator, errorList;
27100
27101 if ( $( this[ 0 ] ).is( "form" ) ) {
27102 valid = this.validate().form();
27103 } else {
27104 errorList = [];
27105 valid = true;
27106 validator = $( this[ 0 ].form ).validate();
27107 this.each( function() {
27108 valid = validator.element( this ) && valid;
27109 if ( !valid ) {
27110 errorList = errorList.concat( validator.errorList );
27111 }
27112 } );
27113 validator.errorList = errorList;
27114 }
27115 return valid;
27116 },
27117
27118 // https://jqueryvalidation.org/rules/
27119 rules: function( command, argument ) {
27120 var element = this[ 0 ],
27121 isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false",
27122 settings, staticRules, existingRules, data, param, filtered;
27123
27124 // If nothing is selected, return empty object; can't chain anyway
27125 if ( element == null ) {
27126 return;
27127 }
27128
27129 if ( !element.form && isContentEditable ) {
27130 element.form = this.closest( "form" )[ 0 ];
27131 element.name = this.attr( "name" );
27132 }
27133
27134 if ( element.form == null ) {
27135 return;
27136 }
27137
27138 if ( command ) {
27139 settings = $.data( element.form, "validator" ).settings;
27140 staticRules = settings.rules;
27141 existingRules = $.validator.staticRules( element );
27142 switch ( command ) {
27143 case "add":
27144 $.extend( existingRules, $.validator.normalizeRule( argument ) );
27145
27146 // Remove messages from rules, but allow them to be set separately
27147 delete existingRules.messages;
27148 staticRules[ element.name ] = existingRules;
27149 if ( argument.messages ) {
27150 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
27151 }
27152 break;
27153 case "remove":
27154 if ( !argument ) {
27155 delete staticRules[ element.name ];
27156 return existingRules;
27157 }
27158 filtered = {};
27159 $.each( argument.split( /\s/ ), function( index, method ) {
27160 filtered[ method ] = existingRules[ method ];
27161 delete existingRules[ method ];
27162 } );
27163 return filtered;
27164 }
27165 }
27166
27167 data = $.validator.normalizeRules(
27168 $.extend(
27169 {},
27170 $.validator.classRules( element ),
27171 $.validator.attributeRules( element ),
27172 $.validator.dataRules( element ),
27173 $.validator.staticRules( element )
27174 ), element );
27175
27176 // Make sure required is at front
27177 if ( data.required ) {
27178 param = data.required;
27179 delete data.required;
27180 data = $.extend( { required: param }, data );
27181 }
27182
27183 // Make sure remote is at back
27184 if ( data.remote ) {
27185 param = data.remote;
27186 delete data.remote;
27187 data = $.extend( data, { remote: param } );
27188 }
27189
27190 return data;
27191 }
27192 } );
27193
27194 // JQuery trim is deprecated, provide a trim method based on String.prototype.trim
27195 var trim = function( str ) {
27196
27197 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
27198 return str.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "" );
27199 };
27200
27201 // Custom selectors
27202 $.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
27203
27204 // https://jqueryvalidation.org/blank-selector/
27205 blank: function( a ) {
27206 return !trim( "" + $( a ).val() );
27207 },
27208
27209 // https://jqueryvalidation.org/filled-selector/
27210 filled: function( a ) {
27211 var val = $( a ).val();
27212 return val !== null && !!trim( "" + val );
27213 },
27214
27215 // https://jqueryvalidation.org/unchecked-selector/
27216 unchecked: function( a ) {
27217 return !$( a ).prop( "checked" );
27218 }
27219 } );
27220
27221 // Constructor for validator
27222 $.validator = function( options, form ) {
27223 this.settings = $.extend( true, {}, $.validator.defaults, options );
27224 this.currentForm = form;
27225 this.init();
27226 };
27227
27228 // https://jqueryvalidation.org/jQuery.validator.format/
27229 $.validator.format = function( source, params ) {
27230 if ( arguments.length === 1 ) {
27231 return function() {
27232 var args = $.makeArray( arguments );
27233 args.unshift( source );
27234 return $.validator.format.apply( this, args );
27235 };
27236 }
27237 if ( params === undefined ) {
27238 return source;
27239 }
27240 if ( arguments.length > 2 && params.constructor !== Array ) {
27241 params = $.makeArray( arguments ).slice( 1 );
27242 }
27243 if ( params.constructor !== Array ) {
27244 params = [ params ];
27245 }
27246 $.each( params, function( i, n ) {
27247 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
27248 return n;
27249 } );
27250 } );
27251 return source;
27252 };
27253
27254 $.extend( $.validator, {
27255
27256 defaults: {
27257 messages: {},
27258 groups: {},
27259 rules: {},
27260 errorClass: "error",
27261 pendingClass: "pending",
27262 validClass: "valid",
27263 errorElement: "label",
27264 focusCleanup: false,
27265 focusInvalid: true,
27266 errorContainer: $( [] ),
27267 errorLabelContainer: $( [] ),
27268 onsubmit: true,
27269 ignore: ":hidden",
27270 ignoreTitle: false,
27271 onfocusin: function( element ) {
27272 this.lastActive = element;
27273
27274 // Hide error label and remove error class on focus if enabled
27275 if ( this.settings.focusCleanup ) {
27276 if ( this.settings.unhighlight ) {
27277 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
27278 }
27279 this.hideThese( this.errorsFor( element ) );
27280 }
27281 },
27282 onfocusout: function( element ) {
27283 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
27284 this.element( element );
27285 }
27286 },
27287 onkeyup: function( element, event ) {
27288
27289 // Avoid revalidate the field when pressing one of the following keys
27290 // Shift => 16
27291 // Ctrl => 17
27292 // Alt => 18
27293 // Caps lock => 20
27294 // End => 35
27295 // Home => 36
27296 // Left arrow => 37
27297 // Up arrow => 38
27298 // Right arrow => 39
27299 // Down arrow => 40
27300 // Insert => 45
27301 // Num lock => 144
27302 // AltGr key => 225
27303 var excludedKeys = [
27304 16, 17, 18, 20, 35, 36, 37,
27305 38, 39, 40, 45, 144, 225
27306 ];
27307
27308 if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
27309 return;
27310 } else if ( element.name in this.submitted || element.name in this.invalid ) {
27311 this.element( element );
27312 }
27313 },
27314 onclick: function( element ) {
27315
27316 // Click on selects, radiobuttons and checkboxes
27317 if ( element.name in this.submitted ) {
27318 this.element( element );
27319
27320 // Or option elements, check parent select in that case
27321 } else if ( element.parentNode.name in this.submitted ) {
27322 this.element( element.parentNode );
27323 }
27324 },
27325 highlight: function( element, errorClass, validClass ) {
27326 if ( element.type === "radio" ) {
27327 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
27328 } else {
27329 $( element ).addClass( errorClass ).removeClass( validClass );
27330 }
27331 },
27332 unhighlight: function( element, errorClass, validClass ) {
27333 if ( element.type === "radio" ) {
27334 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
27335 } else {
27336 $( element ).removeClass( errorClass ).addClass( validClass );
27337 }
27338 }
27339 },
27340
27341 // https://jqueryvalidation.org/jQuery.validator.setDefaults/
27342 setDefaults: function( settings ) {
27343 $.extend( $.validator.defaults, settings );
27344 },
27345
27346 messages: {
27347 required: "This field is required.",
27348 remote: "Please fix this field.",
27349 email: "Please enter a valid email address.",
27350 url: "Please enter a valid URL.",
27351 date: "Please enter a valid date.",
27352 dateISO: "Please enter a valid date (ISO).",
27353 number: "Please enter a valid number.",
27354 digits: "Please enter only digits.",
27355 equalTo: "Please enter the same value again.",
27356 maxlength: $.validator.format( "Please enter no more than {0} characters." ),
27357 minlength: $.validator.format( "Please enter at least {0} characters." ),
27358 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
27359 range: $.validator.format( "Please enter a value between {0} and {1}." ),
27360 max: $.validator.format( "Please enter a value less than or equal to {0}." ),
27361 min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
27362 step: $.validator.format( "Please enter a multiple of {0}." )
27363 },
27364
27365 autoCreateRanges: false,
27366
27367 prototype: {
27368
27369 init: function() {
27370 this.labelContainer = $( this.settings.errorLabelContainer );
27371 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
27372 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
27373 this.submitted = {};
27374 this.valueCache = {};
27375 this.pendingRequest = 0;
27376 this.pending = {};
27377 this.invalid = {};
27378 this.reset();
27379
27380 var currentForm = this.currentForm,
27381 groups = ( this.groups = {} ),
27382 rules;
27383 $.each( this.settings.groups, function( key, value ) {
27384 if ( typeof value === "string" ) {
27385 value = value.split( /\s/ );
27386 }
27387 $.each( value, function( index, name ) {
27388 groups[ name ] = key;
27389 } );
27390 } );
27391 rules = this.settings.rules;
27392 $.each( rules, function( key, value ) {
27393 rules[ key ] = $.validator.normalizeRule( value );
27394 } );
27395
27396 function delegate( event ) {
27397 var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
27398
27399 // Set form expando on contenteditable
27400 if ( !this.form && isContentEditable ) {
27401 this.form = $( this ).closest( "form" )[ 0 ];
27402 this.name = $( this ).attr( "name" );
27403 }
27404
27405 // Ignore the element if it belongs to another form. This will happen mainly
27406 // when setting the `form` attribute of an input to the id of another form.
27407 if ( currentForm !== this.form ) {
27408 return;
27409 }
27410
27411 var validator = $.data( this.form, "validator" ),
27412 eventType = "on" + event.type.replace( /^validate/, "" ),
27413 settings = validator.settings;
27414 if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
27415 settings[ eventType ].call( validator, this, event );
27416 }
27417 }
27418
27419 $( this.currentForm )
27420 .on( "focusin.validate focusout.validate keyup.validate",
27421 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
27422 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
27423 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
27424 "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
27425
27426 // Support: Chrome, oldIE
27427 // "select" is provided as event.target when clicking a option
27428 .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
27429
27430 if ( this.settings.invalidHandler ) {
27431 $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
27432 }
27433 },
27434
27435 // https://jqueryvalidation.org/Validator.form/
27436 form: function() {
27437 this.checkForm();
27438 $.extend( this.submitted, this.errorMap );
27439 this.invalid = $.extend( {}, this.errorMap );
27440 if ( !this.valid() ) {
27441 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
27442 }
27443 this.showErrors();
27444 return this.valid();
27445 },
27446
27447 checkForm: function() {
27448 this.prepareForm();
27449 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
27450 this.check( elements[ i ] );
27451 }
27452 return this.valid();
27453 },
27454
27455 // https://jqueryvalidation.org/Validator.element/
27456 element: function( element ) {
27457 var cleanElement = this.clean( element ),
27458 checkElement = this.validationTargetFor( cleanElement ),
27459 v = this,
27460 result = true,
27461 rs, group;
27462
27463 if ( checkElement === undefined ) {
27464 delete this.invalid[ cleanElement.name ];
27465 } else {
27466 this.prepareElement( checkElement );
27467 this.currentElements = $( checkElement );
27468
27469 // If this element is grouped, then validate all group elements already
27470 // containing a value
27471 group = this.groups[ checkElement.name ];
27472 if ( group ) {
27473 $.each( this.groups, function( name, testgroup ) {
27474 if ( testgroup === group && name !== checkElement.name ) {
27475 cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
27476 if ( cleanElement && cleanElement.name in v.invalid ) {
27477 v.currentElements.push( cleanElement );
27478 result = v.check( cleanElement ) && result;
27479 }
27480 }
27481 } );
27482 }
27483
27484 rs = this.check( checkElement ) !== false;
27485 result = result && rs;
27486 if ( rs ) {
27487 this.invalid[ checkElement.name ] = false;
27488 } else {
27489 this.invalid[ checkElement.name ] = true;
27490 }
27491
27492 if ( !this.numberOfInvalids() ) {
27493
27494 // Hide error containers on last error
27495 this.toHide = this.toHide.add( this.containers );
27496 }
27497 this.showErrors();
27498
27499 // Add aria-invalid status for screen readers
27500 $( element ).attr( "aria-invalid", !rs );
27501 }
27502
27503 return result;
27504 },
27505
27506 // https://jqueryvalidation.org/Validator.showErrors/
27507 showErrors: function( errors ) {
27508 if ( errors ) {
27509 var validator = this;
27510
27511 // Add items to error list and map
27512 $.extend( this.errorMap, errors );
27513 this.errorList = $.map( this.errorMap, function( message, name ) {
27514 return {
27515 message: message,
27516 element: validator.findByName( name )[ 0 ]
27517 };
27518 } );
27519
27520 // Remove items from success list
27521 this.successList = $.grep( this.successList, function( element ) {
27522 return !( element.name in errors );
27523 } );
27524 }
27525 if ( this.settings.showErrors ) {
27526 this.settings.showErrors.call( this, this.errorMap, this.errorList );
27527 } else {
27528 this.defaultShowErrors();
27529 }
27530 },
27531
27532 // https://jqueryvalidation.org/Validator.resetForm/
27533 resetForm: function() {
27534 if ( $.fn.resetForm ) {
27535 $( this.currentForm ).resetForm();
27536 }
27537 this.invalid = {};
27538 this.submitted = {};
27539 this.prepareForm();
27540 this.hideErrors();
27541 var elements = this.elements()
27542 .removeData( "previousValue" )
27543 .removeAttr( "aria-invalid" );
27544
27545 this.resetElements( elements );
27546 },
27547
27548 resetElements: function( elements ) {
27549 var i;
27550
27551 if ( this.settings.unhighlight ) {
27552 for ( i = 0; elements[ i ]; i++ ) {
27553 this.settings.unhighlight.call( this, elements[ i ],
27554 this.settings.errorClass, "" );
27555 this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
27556 }
27557 } else {
27558 elements
27559 .removeClass( this.settings.errorClass )
27560 .removeClass( this.settings.validClass );
27561 }
27562 },
27563
27564 numberOfInvalids: function() {
27565 return this.objectLength( this.invalid );
27566 },
27567
27568 objectLength: function( obj ) {
27569 /* jshint unused: false */
27570 var count = 0,
27571 i;
27572 for ( i in obj ) {
27573
27574 // This check allows counting elements with empty error
27575 // message as invalid elements
27576 if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
27577 count++;
27578 }
27579 }
27580 return count;
27581 },
27582
27583 hideErrors: function() {
27584 this.hideThese( this.toHide );
27585 },
27586
27587 hideThese: function( errors ) {
27588 errors.not( this.containers ).text( "" );
27589 this.addWrapper( errors ).hide();
27590 },
27591
27592 valid: function() {
27593 return this.size() === 0;
27594 },
27595
27596 size: function() {
27597 return this.errorList.length;
27598 },
27599
27600 focusInvalid: function() {
27601 if ( this.settings.focusInvalid ) {
27602 try {
27603 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
27604 .filter( ":visible" )
27605 .trigger( "focus" )
27606
27607 // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
27608 .trigger( "focusin" );
27609 } catch ( e ) {
27610
27611 // Ignore IE throwing errors when focusing hidden elements
27612 }
27613 }
27614 },
27615
27616 findLastActive: function() {
27617 var lastActive = this.lastActive;
27618 return lastActive && $.grep( this.errorList, function( n ) {
27619 return n.element.name === lastActive.name;
27620 } ).length === 1 && lastActive;
27621 },
27622
27623 elements: function() {
27624 var validator = this,
27625 rulesCache = {};
27626
27627 // Select all valid inputs inside the form (no submit or reset buttons)
27628 return $( this.currentForm )
27629 .find( "input, select, textarea, [contenteditable]" )
27630 .not( ":submit, :reset, :image, :disabled" )
27631 .not( this.settings.ignore )
27632 .filter( function() {
27633 var name = this.name || $( this ).attr( "name" ); // For contenteditable
27634 var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
27635
27636 if ( !name && validator.settings.debug && window.console ) {
27637 console.error( "%o has no name assigned", this );
27638 }
27639
27640 // Set form expando on contenteditable
27641 if ( isContentEditable ) {
27642 this.form = $( this ).closest( "form" )[ 0 ];
27643 this.name = name;
27644 }
27645
27646 // Ignore elements that belong to other/nested forms
27647 if ( this.form !== validator.currentForm ) {
27648 return false;
27649 }
27650
27651 // Select only the first element for each name, and only those with rules specified
27652 if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
27653 return false;
27654 }
27655
27656 rulesCache[ name ] = true;
27657 return true;
27658 } );
27659 },
27660
27661 clean: function( selector ) {
27662 return $( selector )[ 0 ];
27663 },
27664
27665 errors: function() {
27666 var errorClass = this.settings.errorClass.split( " " ).join( "." );
27667 return $( this.settings.errorElement + "." + errorClass, this.errorContext );
27668 },
27669
27670 resetInternals: function() {
27671 this.successList = [];
27672 this.errorList = [];
27673 this.errorMap = {};
27674 this.toShow = $( [] );
27675 this.toHide = $( [] );
27676 },
27677
27678 reset: function() {
27679 this.resetInternals();
27680 this.currentElements = $( [] );
27681 },
27682
27683 prepareForm: function() {
27684 this.reset();
27685 this.toHide = this.errors().add( this.containers );
27686 },
27687
27688 prepareElement: function( element ) {
27689 this.reset();
27690 this.toHide = this.errorsFor( element );
27691 },
27692
27693 elementValue: function( element ) {
27694 var $element = $( element ),
27695 type = element.type,
27696 isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false",
27697 val, idx;
27698
27699 if ( type === "radio" || type === "checkbox" ) {
27700 return this.findByName( element.name ).filter( ":checked" ).val();
27701 } else if ( type === "number" && typeof element.validity !== "undefined" ) {
27702 return element.validity.badInput ? "NaN" : $element.val();
27703 }
27704
27705 if ( isContentEditable ) {
27706 val = $element.text();
27707 } else {
27708 val = $element.val();
27709 }
27710
27711 if ( type === "file" ) {
27712
27713 // Modern browser (chrome & safari)
27714 if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
27715 return val.substr( 12 );
27716 }
27717
27718 // Legacy browsers
27719 // Unix-based path
27720 idx = val.lastIndexOf( "/" );
27721 if ( idx >= 0 ) {
27722 return val.substr( idx + 1 );
27723 }
27724
27725 // Windows-based path
27726 idx = val.lastIndexOf( "\\" );
27727 if ( idx >= 0 ) {
27728 return val.substr( idx + 1 );
27729 }
27730
27731 // Just the file name
27732 return val;
27733 }
27734
27735 if ( typeof val === "string" ) {
27736 return val.replace( /\r/g, "" );
27737 }
27738 return val;
27739 },
27740
27741 check: function( element ) {
27742 element = this.validationTargetFor( this.clean( element ) );
27743
27744 var rules = $( element ).rules(),
27745 rulesCount = $.map( rules, function( n, i ) {
27746 return i;
27747 } ).length,
27748 dependencyMismatch = false,
27749 val = this.elementValue( element ),
27750 result, method, rule, normalizer;
27751
27752 // Prioritize the local normalizer defined for this element over the global one
27753 // if the former exists, otherwise user the global one in case it exists.
27754 if ( typeof rules.normalizer === "function" ) {
27755 normalizer = rules.normalizer;
27756 } else if ( typeof this.settings.normalizer === "function" ) {
27757 normalizer = this.settings.normalizer;
27758 }
27759
27760 // If normalizer is defined, then call it to retreive the changed value instead
27761 // of using the real one.
27762 // Note that `this` in the normalizer is `element`.
27763 if ( normalizer ) {
27764 val = normalizer.call( element, val );
27765
27766 // Delete the normalizer from rules to avoid treating it as a pre-defined method.
27767 delete rules.normalizer;
27768 }
27769
27770 for ( method in rules ) {
27771 rule = { method: method, parameters: rules[ method ] };
27772 try {
27773 result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
27774
27775 // If a method indicates that the field is optional and therefore valid,
27776 // don't mark it as valid when there are no other rules
27777 if ( result === "dependency-mismatch" && rulesCount === 1 ) {
27778 dependencyMismatch = true;
27779 continue;
27780 }
27781 dependencyMismatch = false;
27782
27783 if ( result === "pending" ) {
27784 this.toHide = this.toHide.not( this.errorsFor( element ) );
27785 return;
27786 }
27787
27788 if ( !result ) {
27789 this.formatAndAdd( element, rule );
27790 return false;
27791 }
27792 } catch ( e ) {
27793 if ( this.settings.debug && window.console ) {
27794 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
27795 }
27796 if ( e instanceof TypeError ) {
27797 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
27798 }
27799
27800 throw e;
27801 }
27802 }
27803 if ( dependencyMismatch ) {
27804 return;
27805 }
27806 if ( this.objectLength( rules ) ) {
27807 this.successList.push( element );
27808 }
27809 return true;
27810 },
27811
27812 // Return the custom message for the given element and validation method
27813 // specified in the element's HTML5 data attribute
27814 // return the generic message if present and no method specific message is present
27815 customDataMessage: function( element, method ) {
27816 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
27817 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
27818 },
27819
27820 // Return the custom message for the given element name and validation method
27821 customMessage: function( name, method ) {
27822 var m = this.settings.messages[ name ];
27823 return m && ( m.constructor === String ? m : m[ method ] );
27824 },
27825
27826 // Return the first defined argument, allowing empty strings
27827 findDefined: function() {
27828 for ( var i = 0; i < arguments.length; i++ ) {
27829 if ( arguments[ i ] !== undefined ) {
27830 return arguments[ i ];
27831 }
27832 }
27833 return undefined;
27834 },
27835
27836 // The second parameter 'rule' used to be a string, and extended to an object literal
27837 // of the following form:
27838 // rule = {
27839 // method: "method name",
27840 // parameters: "the given method parameters"
27841 // }
27842 //
27843 // The old behavior still supported, kept to maintain backward compatibility with
27844 // old code, and will be removed in the next major release.
27845 defaultMessage: function( element, rule ) {
27846 if ( typeof rule === "string" ) {
27847 rule = { method: rule };
27848 }
27849
27850 var message = this.findDefined(
27851 this.customMessage( element.name, rule.method ),
27852 this.customDataMessage( element, rule.method ),
27853
27854 // 'title' is never undefined, so handle empty string as undefined
27855 !this.settings.ignoreTitle && element.title || undefined,
27856 $.validator.messages[ rule.method ],
27857 "<strong>Warning: No message defined for " + element.name + "</strong>"
27858 ),
27859 theregex = /\$?\{(\d+)\}/g;
27860 if ( typeof message === "function" ) {
27861 message = message.call( this, rule.parameters, element );
27862 } else if ( theregex.test( message ) ) {
27863 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
27864 }
27865
27866 return message;
27867 },
27868
27869 formatAndAdd: function( element, rule ) {
27870 var message = this.defaultMessage( element, rule );
27871
27872 this.errorList.push( {
27873 message: message,
27874 element: element,
27875 method: rule.method
27876 } );
27877
27878 this.errorMap[ element.name ] = message;
27879 this.submitted[ element.name ] = message;
27880 },
27881
27882 addWrapper: function( toToggle ) {
27883 if ( this.settings.wrapper ) {
27884 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
27885 }
27886 return toToggle;
27887 },
27888
27889 defaultShowErrors: function() {
27890 var i, elements, error;
27891 for ( i = 0; this.errorList[ i ]; i++ ) {
27892 error = this.errorList[ i ];
27893 if ( this.settings.highlight ) {
27894 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
27895 }
27896 this.showLabel( error.element, error.message );
27897 }
27898 if ( this.errorList.length ) {
27899 this.toShow = this.toShow.add( this.containers );
27900 }
27901 if ( this.settings.success ) {
27902 for ( i = 0; this.successList[ i ]; i++ ) {
27903 this.showLabel( this.successList[ i ] );
27904 }
27905 }
27906 if ( this.settings.unhighlight ) {
27907 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
27908 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
27909 }
27910 }
27911 this.toHide = this.toHide.not( this.toShow );
27912 this.hideErrors();
27913 this.addWrapper( this.toShow ).show();
27914 },
27915
27916 validElements: function() {
27917 return this.currentElements.not( this.invalidElements() );
27918 },
27919
27920 invalidElements: function() {
27921 return $( this.errorList ).map( function() {
27922 return this.element;
27923 } );
27924 },
27925
27926 showLabel: function( element, message ) {
27927 var place, group, errorID, v,
27928 error = this.errorsFor( element ),
27929 elementID = this.idOrName( element ),
27930 describedBy = $( element ).attr( "aria-describedby" );
27931
27932 if ( error.length ) {
27933
27934 // Refresh error/success class
27935 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
27936
27937 // Replace message on existing label
27938 error.html( message );
27939 } else {
27940
27941 // Create error element
27942 error = $( "<" + this.settings.errorElement + ">" )
27943 .attr( "id", elementID + "-error" )
27944 .addClass( this.settings.errorClass )
27945 .html( message || "" );
27946
27947 // Maintain reference to the element to be placed into the DOM
27948 place = error;
27949 if ( this.settings.wrapper ) {
27950
27951 // Make sure the element is visible, even in IE
27952 // actually showing the wrapped element is handled elsewhere
27953 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
27954 }
27955 if ( this.labelContainer.length ) {
27956 this.labelContainer.append( place );
27957 } else if ( this.settings.errorPlacement ) {
27958 this.settings.errorPlacement.call( this, place, $( element ) );
27959 } else {
27960 place.insertAfter( element );
27961 }
27962
27963 // Link error back to the element
27964 if ( error.is( "label" ) ) {
27965
27966 // If the error is a label, then associate using 'for'
27967 error.attr( "for", elementID );
27968
27969 // If the element is not a child of an associated label, then it's necessary
27970 // to explicitly apply aria-describedby
27971 } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
27972 errorID = error.attr( "id" );
27973
27974 // Respect existing non-error aria-describedby
27975 if ( !describedBy ) {
27976 describedBy = errorID;
27977 } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
27978
27979 // Add to end of list if not already present
27980 describedBy += " " + errorID;
27981 }
27982 $( element ).attr( "aria-describedby", describedBy );
27983
27984 // If this element is grouped, then assign to all elements in the same group
27985 group = this.groups[ element.name ];
27986 if ( group ) {
27987 v = this;
27988 $.each( v.groups, function( name, testgroup ) {
27989 if ( testgroup === group ) {
27990 $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
27991 .attr( "aria-describedby", error.attr( "id" ) );
27992 }
27993 } );
27994 }
27995 }
27996 }
27997 if ( !message && this.settings.success ) {
27998 error.text( "" );
27999 if ( typeof this.settings.success === "string" ) {
28000 error.addClass( this.settings.success );
28001 } else {
28002 this.settings.success( error, element );
28003 }
28004 }
28005 this.toShow = this.toShow.add( error );
28006 },
28007
28008 errorsFor: function( element ) {
28009 var name = this.escapeCssMeta( this.idOrName( element ) ),
28010 describer = $( element ).attr( "aria-describedby" ),
28011 selector = "label[for='" + name + "'], label[for='" + name + "'] *";
28012
28013 // 'aria-describedby' should directly reference the error element
28014 if ( describer ) {
28015 selector = selector + ", #" + this.escapeCssMeta( describer )
28016 .replace( /\s+/g, ", #" );
28017 }
28018
28019 return this
28020 .errors()
28021 .filter( selector );
28022 },
28023
28024 // See https://api.jquery.com/category/selectors/, for CSS
28025 // meta-characters that should be escaped in order to be used with JQuery
28026 // as a literal part of a name/id or any selector.
28027 escapeCssMeta: function( string ) {
28028 if ( string === undefined ) {
28029 return "";
28030 }
28031
28032 return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
28033 },
28034
28035 idOrName: function( element ) {
28036 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
28037 },
28038
28039 validationTargetFor: function( element ) {
28040
28041 // If radio/checkbox, validate first element in group instead
28042 if ( this.checkable( element ) ) {
28043 element = this.findByName( element.name );
28044 }
28045
28046 // Always apply ignore filter
28047 return $( element ).not( this.settings.ignore )[ 0 ];
28048 },
28049
28050 checkable: function( element ) {
28051 return ( /radio|checkbox/i ).test( element.type );
28052 },
28053
28054 findByName: function( name ) {
28055 return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
28056 },
28057
28058 getLength: function( value, element ) {
28059 switch ( element.nodeName.toLowerCase() ) {
28060 case "select":
28061 return $( "option:selected", element ).length;
28062 case "input":
28063 if ( this.checkable( element ) ) {
28064 return this.findByName( element.name ).filter( ":checked" ).length;
28065 }
28066 }
28067 return value.length;
28068 },
28069
28070 depend: function( param, element ) {
28071 return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
28072 },
28073
28074 dependTypes: {
28075 "boolean": function( param ) {
28076 return param;
28077 },
28078 "string": function( param, element ) {
28079 return !!$( param, element.form ).length;
28080 },
28081 "function": function( param, element ) {
28082 return param( element );
28083 }
28084 },
28085
28086 optional: function( element ) {
28087 var val = this.elementValue( element );
28088 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
28089 },
28090
28091 startRequest: function( element ) {
28092 if ( !this.pending[ element.name ] ) {
28093 this.pendingRequest++;
28094 $( element ).addClass( this.settings.pendingClass );
28095 this.pending[ element.name ] = true;
28096 }
28097 },
28098
28099 stopRequest: function( element, valid ) {
28100 this.pendingRequest--;
28101
28102 // Sometimes synchronization fails, make sure pendingRequest is never < 0
28103 if ( this.pendingRequest < 0 ) {
28104 this.pendingRequest = 0;
28105 }
28106 delete this.pending[ element.name ];
28107 $( element ).removeClass( this.settings.pendingClass );
28108 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) {
28109 $( this.currentForm ).trigger( "submit" );
28110
28111 // Remove the hidden input that was used as a replacement for the
28112 // missing submit button. The hidden input is added by `handle()`
28113 // to ensure that the value of the used submit button is passed on
28114 // for scripted submits triggered by this method
28115 if ( this.submitButton ) {
28116 $( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
28117 }
28118
28119 this.formSubmitted = false;
28120 } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
28121 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
28122 this.formSubmitted = false;
28123 }
28124 },
28125
28126 previousValue: function( element, method ) {
28127 method = typeof method === "string" && method || "remote";
28128
28129 return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
28130 old: null,
28131 valid: true,
28132 message: this.defaultMessage( element, { method: method } )
28133 } );
28134 },
28135
28136 // Cleans up all forms and elements, removes validator-specific events
28137 destroy: function() {
28138 this.resetForm();
28139
28140 $( this.currentForm )
28141 .off( ".validate" )
28142 .removeData( "validator" )
28143 .find( ".validate-equalTo-blur" )
28144 .off( ".validate-equalTo" )
28145 .removeClass( "validate-equalTo-blur" )
28146 .find( ".validate-lessThan-blur" )
28147 .off( ".validate-lessThan" )
28148 .removeClass( "validate-lessThan-blur" )
28149 .find( ".validate-lessThanEqual-blur" )
28150 .off( ".validate-lessThanEqual" )
28151 .removeClass( "validate-lessThanEqual-blur" )
28152 .find( ".validate-greaterThanEqual-blur" )
28153 .off( ".validate-greaterThanEqual" )
28154 .removeClass( "validate-greaterThanEqual-blur" )
28155 .find( ".validate-greaterThan-blur" )
28156 .off( ".validate-greaterThan" )
28157 .removeClass( "validate-greaterThan-blur" );
28158 }
28159
28160 },
28161
28162 classRuleSettings: {
28163 required: { required: true },
28164 email: { email: true },
28165 url: { url: true },
28166 date: { date: true },
28167 dateISO: { dateISO: true },
28168 number: { number: true },
28169 digits: { digits: true },
28170 creditcard: { creditcard: true }
28171 },
28172
28173 addClassRules: function( className, rules ) {
28174 if ( className.constructor === String ) {
28175 this.classRuleSettings[ className ] = rules;
28176 } else {
28177 $.extend( this.classRuleSettings, className );
28178 }
28179 },
28180
28181 classRules: function( element ) {
28182 var rules = {},
28183 classes = $( element ).attr( "class" );
28184
28185 if ( classes ) {
28186 $.each( classes.split( " " ), function() {
28187 if ( this in $.validator.classRuleSettings ) {
28188 $.extend( rules, $.validator.classRuleSettings[ this ] );
28189 }
28190 } );
28191 }
28192 return rules;
28193 },
28194
28195 normalizeAttributeRule: function( rules, type, method, value ) {
28196
28197 // Convert the value to a number for number inputs, and for text for backwards compability
28198 // allows type="date" and others to be compared as strings
28199 if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
28200 value = Number( value );
28201
28202 // Support Opera Mini, which returns NaN for undefined minlength
28203 if ( isNaN( value ) ) {
28204 value = undefined;
28205 }
28206 }
28207
28208 if ( value || value === 0 ) {
28209 rules[ method ] = value;
28210 } else if ( type === method && type !== "range" ) {
28211
28212 // Exception: the jquery validate 'range' method
28213 // does not test for the html5 'range' type
28214 rules[ type === "date" ? "dateISO" : method ] = true;
28215 }
28216 },
28217
28218 attributeRules: function( element ) {
28219 var rules = {},
28220 $element = $( element ),
28221 type = element.getAttribute( "type" ),
28222 method, value;
28223
28224 for ( method in $.validator.methods ) {
28225
28226 // Support for <input required> in both html5 and older browsers
28227 if ( method === "required" ) {
28228 value = element.getAttribute( method );
28229
28230 // Some browsers return an empty string for the required attribute
28231 // and non-HTML5 browsers might have required="" markup
28232 if ( value === "" ) {
28233 value = true;
28234 }
28235
28236 // Force non-HTML5 browsers to return bool
28237 value = !!value;
28238 } else {
28239 value = $element.attr( method );
28240 }
28241
28242 this.normalizeAttributeRule( rules, type, method, value );
28243 }
28244
28245 // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
28246 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
28247 delete rules.maxlength;
28248 }
28249
28250 return rules;
28251 },
28252
28253 dataRules: function( element ) {
28254 var rules = {},
28255 $element = $( element ),
28256 type = element.getAttribute( "type" ),
28257 method, value;
28258
28259 for ( method in $.validator.methods ) {
28260 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
28261
28262 // Cast empty attributes like `data-rule-required` to `true`
28263 if ( value === "" ) {
28264 value = true;
28265 }
28266
28267 this.normalizeAttributeRule( rules, type, method, value );
28268 }
28269 return rules;
28270 },
28271
28272 staticRules: function( element ) {
28273 var rules = {},
28274 validator = $.data( element.form, "validator" );
28275
28276 if ( validator.settings.rules ) {
28277 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
28278 }
28279 return rules;
28280 },
28281
28282 normalizeRules: function( rules, element ) {
28283
28284 // Handle dependency check
28285 $.each( rules, function( prop, val ) {
28286
28287 // Ignore rule when param is explicitly false, eg. required:false
28288 if ( val === false ) {
28289 delete rules[ prop ];
28290 return;
28291 }
28292 if ( val.param || val.depends ) {
28293 var keepRule = true;
28294 switch ( typeof val.depends ) {
28295 case "string":
28296 keepRule = !!$( val.depends, element.form ).length;
28297 break;
28298 case "function":
28299 keepRule = val.depends.call( element, element );
28300 break;
28301 }
28302 if ( keepRule ) {
28303 rules[ prop ] = val.param !== undefined ? val.param : true;
28304 } else {
28305 $.data( element.form, "validator" ).resetElements( $( element ) );
28306 delete rules[ prop ];
28307 }
28308 }
28309 } );
28310
28311 // Evaluate parameters
28312 $.each( rules, function( rule, parameter ) {
28313 rules[ rule ] = typeof parameter === "function" && rule !== "normalizer" ? parameter( element ) : parameter;
28314 } );
28315
28316 // Clean number parameters
28317 $.each( [ "minlength", "maxlength" ], function() {
28318 if ( rules[ this ] ) {
28319 rules[ this ] = Number( rules[ this ] );
28320 }
28321 } );
28322 $.each( [ "rangelength", "range" ], function() {
28323 var parts;
28324 if ( rules[ this ] ) {
28325 if ( Array.isArray( rules[ this ] ) ) {
28326 rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
28327 } else if ( typeof rules[ this ] === "string" ) {
28328 parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
28329 rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
28330 }
28331 }
28332 } );
28333
28334 if ( $.validator.autoCreateRanges ) {
28335
28336 // Auto-create ranges
28337 if ( rules.min != null && rules.max != null ) {
28338 rules.range = [ rules.min, rules.max ];
28339 delete rules.min;
28340 delete rules.max;
28341 }
28342 if ( rules.minlength != null && rules.maxlength != null ) {
28343 rules.rangelength = [ rules.minlength, rules.maxlength ];
28344 delete rules.minlength;
28345 delete rules.maxlength;
28346 }
28347 }
28348
28349 return rules;
28350 },
28351
28352 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
28353 normalizeRule: function( data ) {
28354 if ( typeof data === "string" ) {
28355 var transformed = {};
28356 $.each( data.split( /\s/ ), function() {
28357 transformed[ this ] = true;
28358 } );
28359 data = transformed;
28360 }
28361 return data;
28362 },
28363
28364 // https://jqueryvalidation.org/jQuery.validator.addMethod/
28365 addMethod: function( name, method, message ) {
28366 $.validator.methods[ name ] = method;
28367 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
28368 if ( method.length < 3 ) {
28369 $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
28370 }
28371 },
28372
28373 // https://jqueryvalidation.org/jQuery.validator.methods/
28374 methods: {
28375
28376 // https://jqueryvalidation.org/required-method/
28377 required: function( value, element, param ) {
28378
28379 // Check if dependency is met
28380 if ( !this.depend( param, element ) ) {
28381 return "dependency-mismatch";
28382 }
28383 if ( element.nodeName.toLowerCase() === "select" ) {
28384
28385 // Could be an array for select-multiple or a string, both are fine this way
28386 var val = $( element ).val();
28387 return val && val.length > 0;
28388 }
28389 if ( this.checkable( element ) ) {
28390 return this.getLength( value, element ) > 0;
28391 }
28392 return value !== undefined && value !== null && value.length > 0;
28393 },
28394
28395 // https://jqueryvalidation.org/email-method/
28396 email: function( value, element ) {
28397
28398 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
28399 // Retrieved 2014-01-14
28400 // If you have a problem with this implementation, report a bug against the above spec
28401 // Or use custom methods to implement your own email validation
28402 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
28403 },
28404
28405 // https://jqueryvalidation.org/url-method/
28406 url: function( value, element ) {
28407
28408 // Copyright (c) 2010-2013 Diego Perini, MIT licensed
28409 // https://gist.github.com/dperini/729294
28410 // see also https://mathiasbynens.be/demo/url-regex
28411 // modified to allow protocol-relative URLs
28412 return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
28413 },
28414
28415 // https://jqueryvalidation.org/date-method/
28416 date: ( function() {
28417 var called = false;
28418
28419 return function( value, element ) {
28420 if ( !called ) {
28421 called = true;
28422 if ( this.settings.debug && window.console ) {
28423 console.warn(
28424 "The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
28425 "Please don't use it, since it relies on the Date constructor, which\n" +
28426 "behaves very differently across browsers and locales. Use `dateISO`\n" +
28427 "instead or one of the locale specific methods in `localizations/`\n" +
28428 "and `additional-methods.js`."
28429 );
28430 }
28431 }
28432
28433 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
28434 };
28435 }() ),
28436
28437 // https://jqueryvalidation.org/dateISO-method/
28438 dateISO: function( value, element ) {
28439 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
28440 },
28441
28442 // https://jqueryvalidation.org/number-method/
28443 number: function( value, element ) {
28444 return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
28445 },
28446
28447 // https://jqueryvalidation.org/digits-method/
28448 digits: function( value, element ) {
28449 return this.optional( element ) || /^\d+$/.test( value );
28450 },
28451
28452 // https://jqueryvalidation.org/minlength-method/
28453 minlength: function( value, element, param ) {
28454 var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
28455 return this.optional( element ) || length >= param;
28456 },
28457
28458 // https://jqueryvalidation.org/maxlength-method/
28459 maxlength: function( value, element, param ) {
28460 var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
28461 return this.optional( element ) || length <= param;
28462 },
28463
28464 // https://jqueryvalidation.org/rangelength-method/
28465 rangelength: function( value, element, param ) {
28466 var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
28467 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
28468 },
28469
28470 // https://jqueryvalidation.org/min-method/
28471 min: function( value, element, param ) {
28472 return this.optional( element ) || value >= param;
28473 },
28474
28475 // https://jqueryvalidation.org/max-method/
28476 max: function( value, element, param ) {
28477 return this.optional( element ) || value <= param;
28478 },
28479
28480 // https://jqueryvalidation.org/range-method/
28481 range: function( value, element, param ) {
28482 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
28483 },
28484
28485 // https://jqueryvalidation.org/step-method/
28486 step: function( value, element, param ) {
28487 var type = $( element ).attr( "type" ),
28488 errorMessage = "Step attribute on input type " + type + " is not supported.",
28489 supportedTypes = [ "text", "number", "range" ],
28490 re = new RegExp( "\\b" + type + "\\b" ),
28491 notSupported = type && !re.test( supportedTypes.join() ),
28492 decimalPlaces = function( num ) {
28493 var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
28494 if ( !match ) {
28495 return 0;
28496 }
28497
28498 // Number of digits right of decimal point.
28499 return match[ 1 ] ? match[ 1 ].length : 0;
28500 },
28501 toInt = function( num ) {
28502 return Math.round( num * Math.pow( 10, decimals ) );
28503 },
28504 valid = true,
28505 decimals;
28506
28507 // Works only for text, number and range input types
28508 // TODO find a way to support input types date, datetime, datetime-local, month, time and week
28509 if ( notSupported ) {
28510 throw new Error( errorMessage );
28511 }
28512
28513 decimals = decimalPlaces( param );
28514
28515 // Value can't have too many decimals
28516 if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
28517 valid = false;
28518 }
28519
28520 return this.optional( element ) || valid;
28521 },
28522
28523 // https://jqueryvalidation.org/equalTo-method/
28524 equalTo: function( value, element, param ) {
28525
28526 // Bind to the blur event of the target in order to revalidate whenever the target field is updated
28527 var target = $( param );
28528 if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
28529 target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
28530 $( element ).valid();
28531 } );
28532 }
28533 return value === target.val();
28534 },
28535
28536 // https://jqueryvalidation.org/remote-method/
28537 remote: function( value, element, param, method ) {
28538 if ( this.optional( element ) ) {
28539 return "dependency-mismatch";
28540 }
28541
28542 method = typeof method === "string" && method || "remote";
28543
28544 var previous = this.previousValue( element, method ),
28545 validator, data, optionDataString;
28546
28547 if ( !this.settings.messages[ element.name ] ) {
28548 this.settings.messages[ element.name ] = {};
28549 }
28550 previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
28551 this.settings.messages[ element.name ][ method ] = previous.message;
28552
28553 param = typeof param === "string" && { url: param } || param;
28554 optionDataString = $.param( $.extend( { data: value }, param.data ) );
28555 if ( previous.old === optionDataString ) {
28556 return previous.valid;
28557 }
28558
28559 previous.old = optionDataString;
28560 validator = this;
28561 this.startRequest( element );
28562 data = {};
28563 data[ element.name ] = value;
28564 $.ajax( $.extend( true, {
28565 mode: "abort",
28566 port: "validate" + element.name,
28567 dataType: "json",
28568 data: data,
28569 context: validator.currentForm,
28570 success: function( response ) {
28571 var valid = response === true || response === "true",
28572 errors, message, submitted;
28573
28574 validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
28575 if ( valid ) {
28576 submitted = validator.formSubmitted;
28577 validator.resetInternals();
28578 validator.toHide = validator.errorsFor( element );
28579 validator.formSubmitted = submitted;
28580 validator.successList.push( element );
28581 validator.invalid[ element.name ] = false;
28582 validator.showErrors();
28583 } else {
28584 errors = {};
28585 message = response || validator.defaultMessage( element, { method: method, parameters: value } );
28586 errors[ element.name ] = previous.message = message;
28587 validator.invalid[ element.name ] = true;
28588 validator.showErrors( errors );
28589 }
28590 previous.valid = valid;
28591 validator.stopRequest( element, valid );
28592 }
28593 }, param ) );
28594 return "pending";
28595 }
28596 }
28597
28598 } );
28599
28600 // Ajax mode: abort
28601 // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
28602 // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
28603
28604 var pendingRequests = {},
28605 ajax;
28606
28607 // Use a prefilter if available (1.5+)
28608 if ( $.ajaxPrefilter ) {
28609 $.ajaxPrefilter( function( settings, _, xhr ) {
28610 var port = settings.port;
28611 if ( settings.mode === "abort" ) {
28612 if ( pendingRequests[ port ] ) {
28613 pendingRequests[ port ].abort();
28614 }
28615 pendingRequests[ port ] = xhr;
28616 }
28617 } );
28618 } else {
28619
28620 // Proxy ajax
28621 ajax = $.ajax;
28622 $.ajax = function( settings ) {
28623 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
28624 port = ( "port" in settings ? settings : $.ajaxSettings ).port;
28625 if ( mode === "abort" ) {
28626 if ( pendingRequests[ port ] ) {
28627 pendingRequests[ port ].abort();
28628 }
28629 pendingRequests[ port ] = ajax.apply( this, arguments );
28630 return pendingRequests[ port ];
28631 }
28632 return ajax.apply( this, arguments );
28633 };
28634 }
28635 return $;
28636 }));
28637 }(jquery_validate));
28638
26974 /** 28639 /**
26975 * SSR Window 4.0.2 28640 * SSR Window 4.0.2
26976 * Better handling for window object in SSR environment 28641 * Better handling for window object in SSR environment
...@@ -33677,6 +35342,31 @@ ...@@ -33677,6 +35342,31 @@
33677 $('.search-button').toggleClass('open'); 35342 $('.search-button').toggleClass('open');
33678 $('.search').toggleClass('open'); 35343 $('.search').toggleClass('open');
33679 }); 35344 });
35345 $('.register').attr('id', 'register');
35346 $("#register").validate({
35347 // Specify validation rules
35348 rules: {
35349 billing_first_name: {
35350 required: true
35351 },
35352 billing_last_name: {
35353 required: true
35354 },
35355 email: {
35356 required: true,
35357 email: true
35358 },
35359 password: {
35360 required: true,
35361 minlength: 10
35362 },
35363 password2: {
35364 required: true,
35365 minlength: 10,
35366 equalTo: "#reg_password"
35367 }
35368 }
35369 });
33680 }); 35370 });
33681 35371
33682 exports.Alert = alert$1; 35372 exports.Alert = alert$1;
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
...@@ -3024,6 +3024,11 @@ ...@@ -3024,6 +3024,11 @@
3024 "jquery": ">=1.4.2 <4" 3024 "jquery": ">=1.4.2 <4"
3025 } 3025 }
3026 }, 3026 },
3027 "jquery-validation": {
3028 "version": "1.19.5",
3029 "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.19.5.tgz",
3030 "integrity": "sha512-X2SmnPq1mRiDecVYL8edWx+yTBZDyC8ohWXFhXdtqFHgU9Wd4KHkvcbCoIZ0JaSaumzS8s2gXSkP8F7ivg/8ZQ=="
3031 },
3027 "js-tokens": { 3032 "js-tokens": {
3028 "version": "4.0.0", 3033 "version": "4.0.0",
3029 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 3034 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
51 "isotope": "^1.0.0-alpha.3", 51 "isotope": "^1.0.0-alpha.3",
52 "isotope-layout": "^3.0.6", 52 "isotope-layout": "^3.0.6",
53 "jquery-bridget": "^3.0.1", 53 "jquery-bridget": "^3.0.1",
54 "jquery-validation": "^1.19.5",
54 "jssocials": "^1.5.0", 55 "jssocials": "^1.5.0",
55 "rollup-plugin-postcss": "^4.0.2", 56 "rollup-plugin-postcss": "^4.0.2",
56 "swiper": "^8.4.7" 57 "swiper": "^8.4.7"
......
...@@ -2,6 +2,8 @@ import jQuery from 'jquery'; ...@@ -2,6 +2,8 @@ import jQuery from 'jquery';
2 import jQueryBridget from 'jquery-bridget'; 2 import jQueryBridget from 'jquery-bridget';
3 import Isotope from "isotope-layout"; 3 import Isotope from "isotope-layout";
4 import DataTable from 'datatables.net-bs5'; 4 import DataTable from 'datatables.net-bs5';
5 import validate from 'jquery-validation';
6
5 7
6 jQueryBridget( 'isotope', Isotope, $ ); 8 jQueryBridget( 'isotope', Isotope, $ );
7 9
...@@ -87,6 +89,34 @@ $('#navbarNavDropdown').prepend($search); ...@@ -87,6 +89,34 @@ $('#navbarNavDropdown').prepend($search);
87 89
88 }); 90 });
89 91
92 $('.register').attr('id','register');
93
94 $("#register").validate({
95 // Specify validation rules
96 rules: {
97 billing_first_name: {
98 required: true,
99 },
100 billing_last_name:{
101 required: true,
102 },
103 email: {
104 required: true,
105 email: true
106 },
107 password: {
108 required: true,
109 minlength: 10
110 },
111 password2: {
112 required: true,
113 minlength: 10,
114 equalTo: "#reg_password"
115 }
116 },
117
118 });
119
120 });
90 121
91 122
92 });
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -180,4 +180,9 @@ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/s ...@@ -180,4 +180,9 @@ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/s
180 } 180 }
181 .has-medium-font-size{ 181 .has-medium-font-size{
182 line-height: 34px !important; 182 line-height: 34px !important;
183 }
184 .woocommerce-form-register{
185 .error{
186 color: red;
187 }
183 } 188 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
5 Author: Tenzing Communications 5 Author: Tenzing Communications
6 Author URI: https://tenzingbrand.com 6 Author URI: https://tenzingbrand.com
7 Template: understrap 7 Template: understrap
8 Version: 1.1.002 8 Version: 1.1.003
9 License: GNU General Public License v2 or later 9 License: GNU General Public License v2 or later
10 License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 License URI: http://www.gnu.org/licenses/gpl-2.0.html
11 Text Domain: understrap-child 11 Text Domain: understrap-child
......