Register
Signed-off-by: Jeff <jeff@gotenzing.com>
Showing
15 changed files
with
1904 additions
and
8 deletions
| ... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment