|
514 | 514 | target.value = target.value.replace(/-\s+/g, '-'); |
515 | 515 | target.value = target.value.replace(/\s+-/g, ''); |
516 | 516 |
|
517 | | - // сбор ошибок/вывод "соответствующих" сообщений |
| 517 | + // сбор ошибок/соответствующих сообщений |
518 | 518 | const errors = []; |
519 | 519 |
|
520 | | - if (options.allowOnlyRussian && /[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
521 | | - errors.push( |
522 | | - 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!' |
| 520 | + // изначально проверка на поля ввода из "динамической" строки контактов |
| 521 | + if (options.dynamicContactValidation) { |
| 522 | + const hiddenInput = targetParentNode.querySelector( |
| 523 | + '.modal__add-body-add-hidden-input' |
523 | 524 | ); |
524 | | - } |
525 | 525 |
|
526 | | - if (options.singleHyphen) { |
527 | | - // дополнительная проверка для двух инпутов (дефисы недопустимы) |
528 | | - if ( |
529 | | - target.classList.contains('add-name-input') || |
530 | | - target.classList.contains('add-patronymic-input') |
531 | | - ) { |
532 | | - if (/-/.test(target.value)) { |
533 | | - errors.push('Дефисы НЕдопустимы!'); |
| 526 | + if (hiddenInput) { |
| 527 | + const contactType = hiddenInput.value; |
| 528 | + |
| 529 | + switch (contactType) { |
| 530 | + case 'phone': |
| 531 | + case 'extra-phone': |
| 532 | + // первичная проверка на "пустое" поле ввода (выход из проверки соответствия) |
| 533 | + if (target.value === '') { |
| 534 | + invalidFeed.textContent = ''; |
| 535 | + target.classList.remove('is-invalid'); |
| 536 | + break; |
| 537 | + } |
| 538 | + |
| 539 | + // дополнительные/итоговая проверка вводимых данных (определённые условия для ввода) |
| 540 | + if ( |
| 541 | + target.value === '+' || // обязательно начало с "+" |
| 542 | + /^\+\d{1,4}\s?$/.test(target.value) || // далее "+X" или "+XXXX " (где X - код страны, 1 – 4 цифры, после пробел) |
| 543 | + /^\+\d{1,4} \(\d{0,4}\)?$/.test(target.value) || // дале скобки (...) 2 - 4 цифры, потом пробел |
| 544 | + /^\+\d{1,4} \(\d{2,4}\) \d{0,3}$/.test(target.value) || // далее 3 - цифры телефона, дефис |
| 545 | + /^\+\d{1,4} \(\d{2,4}\) \d{3}-\d{0,2}$/.test(target.value) || // 2 - цифры, дефис |
| 546 | + /^\+\d{1,4} \(\d{2,4}\) \d{3}-\d{2}-\d{0,2}$/.test( |
| 547 | + target.value |
| 548 | + ) // в конце 2 - цифры |
| 549 | + ) { |
| 550 | + invalidFeed.textContent = ''; |
| 551 | + target.classList.remove('is-invalid'); |
| 552 | + // момент с пробелами |
| 553 | + } else if (/\s{2,}/.test(target.value)) { |
| 554 | + errors.push('Только ОДИН пробел (подряд)!'); |
| 555 | + target.classList.add('is-invalid'); |
| 556 | + invalidFeed.textContent = 'Только ОДИН пробел (подряд)!'; |
| 557 | + } else if ( |
| 558 | + !/^\+\d{1,4} \(\d{2,4}\) \d{3}-\d{2}-\d{2}$/.test( |
| 559 | + target.value |
| 560 | + ) // итоговая проверка на вводимый формат |
| 561 | + ) { |
| 562 | + errors.push('Допустимый формат: +X (XXX) XXX-XX-XX'); |
| 563 | + target.classList.add('is-invalid'); |
| 564 | + invalidFeed.textContent = |
| 565 | + 'Допустимый формат: +X (XXX) XXX-XX-XX'; |
| 566 | + } else { |
| 567 | + // если всё корректно (сообщений нет) |
| 568 | + invalidFeed.textContent = ''; |
| 569 | + target.classList.remove('is-invalid'); |
| 570 | + } |
| 571 | + break; |
| 572 | + |
| 573 | + case 'email': |
| 574 | + // первичная проверка на "пустое" поле ввода (выход из проверки соответствия) |
| 575 | + if (target.value === '') { |
| 576 | + invalidFeed.textContent = ''; |
| 577 | + target.classList.remove('is-invalid'); |
| 578 | + break; |
| 579 | + } |
| 580 | + |
| 581 | + // дополнительные/итоговая проверка вводимых данных (определённые условия для ввода) |
| 582 | + if ( |
| 583 | + /^[a-zA-Z0-9]+$/.test(target.value) || // начало, только с букв или цифр |
| 584 | + /^[a-zA-Z0-9]+@$/.test(target.value) || // буквы/цифры и символ @ |
| 585 | + /^[a-zA-Z0-9]+@[a-zA-Z0-9]+$/.test(target.value) || // Буквы/цифры перед и после @ |
| 586 | + /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.$/.test(target.value) // Частично введенный домен с точкой |
| 587 | + ) { |
| 588 | + invalidFeed.textContent = ''; |
| 589 | + target.classList.remove('is-invalid'); |
| 590 | + } |
| 591 | + // Проверка на пробелы |
| 592 | + else if (/\s/.test(target.value)) { |
| 593 | + errors.push('Пробелы в почте не допускаются.'); |
| 594 | + target.classList.add('is-invalid'); |
| 595 | + invalidFeed.textContent = 'Пробелы в почте не допускаются.'; |
| 596 | + } |
| 597 | + // Проверка, что почта начинается с буквы или цифры |
| 598 | + else if (!/^[a-zA-Z0-9]/.test(target.value)) { |
| 599 | + errors.push('Почта должна начинаться с буквы или цифры.'); |
| 600 | + target.classList.add('is-invalid'); |
| 601 | + invalidFeed.textContent = |
| 602 | + 'Почта должна начинаться с буквы или цифры.'; |
| 603 | + } |
| 604 | + // Проверка, что почта не заканчивается на цифру |
| 605 | + else if (/\d$/.test(target.value)) { |
| 606 | + errors.push('Почта не может заканчиваться на цифру.'); |
| 607 | + target.classList.add('is-invalid'); |
| 608 | + invalidFeed.textContent = |
| 609 | + 'Почта не может заканчиваться на цифру.'; |
| 610 | + } |
| 611 | + // Итоговая проверка формата email |
| 612 | + else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(target.value)) { |
| 613 | + errors.push( |
| 614 | + 'Введите корректную почту, например: [email protected].' |
| 615 | + ); |
| 616 | + target.classList.add('is-invalid'); |
| 617 | + invalidFeed.textContent = |
| 618 | + 'Введите корректную почту, например: [email protected].'; |
| 619 | + } |
| 620 | + // Если все проверки пройдены |
| 621 | + else { |
| 622 | + invalidFeed.textContent = ''; |
| 623 | + target.classList.remove('is-invalid'); |
| 624 | + } |
| 625 | + break; |
| 626 | + |
| 627 | + case 'vk': |
| 628 | + if (target.value === '') { |
| 629 | + errors.length = 0; |
| 630 | + break; |
| 631 | + } |
| 632 | + if (!/^[a-zA-Z0-9_-]+$/.test(target.value)) { |
| 633 | + errors.push('Укажите корректный ID, например: id12345'); |
| 634 | + } |
| 635 | + break; |
| 636 | + |
| 637 | + case 'facebook': |
| 638 | + if (target.value === '') { |
| 639 | + errors.length = 0; |
| 640 | + break; |
| 641 | + } |
| 642 | + if (!/^[a-zA-Z0-9._-]+$/.test(target.value)) { |
| 643 | + errors.push( |
| 644 | + 'Укажите корректное имя пользователя, например: username1' |
| 645 | + ); |
| 646 | + } |
| 647 | + break; |
| 648 | + |
| 649 | + case 'twitter': |
| 650 | + if (target.value === '') { |
| 651 | + errors.length = 0; |
| 652 | + break; |
| 653 | + } |
| 654 | + if (!/^@[a-zA-Z0-9_]+$/.test(target.value)) { |
| 655 | + errors.push( |
| 656 | + 'Укажите корректное имя пользователя, например: @Im_123' |
| 657 | + ); |
| 658 | + } |
| 659 | + break; |
| 660 | + |
| 661 | + default: |
| 662 | + errors.push('Неизвестный тип контакта!'); |
| 663 | + break; |
534 | 664 | } |
535 | | - } else { |
536 | | - if ((target.value.match(/-/g) || []).length > 1) { |
537 | | - const hyphenCount = target.value.match(/-/g).length; |
538 | | - if (hyphenCount > 1) { |
539 | | - errors.push( |
540 | | - 'Допускается только ОДИН дефис (для двойных-фамилий)!' |
541 | | - ); |
| 665 | + } |
| 666 | + } else { |
| 667 | + if (options.allowOnlyRussian && /[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
| 668 | + errors.push( |
| 669 | + 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!' |
| 670 | + ); |
| 671 | + } |
| 672 | + |
| 673 | + if (options.singleHyphen) { |
| 674 | + // дополнительная проверка для двух инпутов (дефисы недопустимы) |
| 675 | + if ( |
| 676 | + target.classList.contains('add-name-input') || |
| 677 | + target.classList.contains('add-patronymic-input') |
| 678 | + ) { |
| 679 | + if (/-/.test(target.value)) { |
| 680 | + errors.push('Дефисы НЕдопустимы!'); |
| 681 | + } |
| 682 | + } else { |
| 683 | + if ((target.value.match(/-/g) || []).length > 1) { |
| 684 | + const hyphenCount = target.value.match(/-/g).length; |
| 685 | + if (hyphenCount > 1) { |
| 686 | + errors.push( |
| 687 | + 'Допускается только ОДИН дефис (для двойных-фамилий)!' |
| 688 | + ); |
| 689 | + } |
542 | 690 | } |
543 | 691 | } |
544 | 692 | } |
545 | | - } |
546 | 693 |
|
547 | | - // дополнительная проверка для "modal__add-body-input" (пробелы недопустимы) |
548 | | - if ( |
549 | | - target.classList.contains('modal__add-body-input') && |
550 | | - /\s/.test(target.value) |
551 | | - ) { |
552 | | - errors.push('Пробелы НЕдопустимы!'); |
553 | | - } else if (options.noExtraSpaces && /\s{2,}/.test(target.value)) { |
554 | | - errors.push('Допускается только ОДИН пробел (подряд)!'); |
555 | | - } else if (options.noSpaces && /\s/.test(target.value)) { |
556 | | - errors.push('Пробелы НЕдопустимы!'); |
| 694 | + // дополнительная проверка для "modal__add-body-input" (пробелы недопустимы) |
| 695 | + if ( |
| 696 | + target.classList.contains('modal__add-body-input') && |
| 697 | + /\s/.test(target.value) |
| 698 | + ) { |
| 699 | + errors.push('Пробелы НЕдопустимы!'); |
| 700 | + } else if (options.noExtraSpaces && /\s{2,}/.test(target.value)) { |
| 701 | + errors.push('Допускается только ОДИН пробел (подряд)!'); |
| 702 | + } else if (options.noSpaces && /\s/.test(target.value)) { |
| 703 | + errors.push('Пробелы НЕдопустимы!'); |
| 704 | + } |
557 | 705 | } |
558 | 706 |
|
559 | 707 | // отработка ошибок |
|
639 | 787 | const addModalContactInput = document.createElement('input'); |
640 | 788 | const addModalContactXBtn = document.createElement('button'); |
641 | 789 | const addModalContactXBtnIcon = document.createElement('i'); |
| 790 | + const addModalContactFeedback = document.createElement('div'); |
642 | 791 |
|
643 | 792 | addModalContactElement.classList.add( |
644 | 793 | 'modal__add-body-add-contact-element', |
|
689 | 838 | 'bi', |
690 | 839 | 'bi-x-circle' |
691 | 840 | ); |
| 841 | + addModalContactFeedback.classList.add( |
| 842 | + 'modal__add-body-add-contact-feedback', |
| 843 | + 'invalid-feedback' |
| 844 | + ); |
692 | 845 |
|
693 | 846 | addModalContactCustomSelect.setAttribute('name', 'contact-options'); |
694 | 847 | addModalContactDropBtn.setAttribute('id', 'add-modal-drop-btn'); |
|
706 | 859 | addModalContactHiddenInput.setAttribute('name', 'contact-type'); |
707 | 860 | addModalContactInput.setAttribute('type', 'text'); |
708 | 861 | addModalContactInput.setAttribute('name', 'contact-data'); |
| 862 | + // addModalContactInput.setAttribute('pattern', '[А-Яа-яЁё\\-]+'); |
709 | 863 | addModalContactInput.setAttribute('placeholder', 'Введите данные контакта'); |
| 864 | + addModalContactInput.setAttribute('required', ''); |
710 | 865 | addModalContactXBtn.setAttribute('type', 'button'); |
711 | 866 | addModalContactXBtn.setAttribute('tabindex', '0'); |
712 | 867 |
|
|
715 | 870 | addModalContactItemEmail.textContent = 'Email'; |
716 | 871 | addModalContactItemVk.textContent = 'Vk'; |
717 | 872 | addModalContactItemFacebook.textContent = 'Facebook'; |
| 873 | + addModalContactFeedback.textContent = 'НЕ корректный ввод данных контакта!'; |
718 | 874 |
|
719 | 875 | addModalContactList.append( |
720 | 876 | addModalContactItemExtraPhone, |
|
731 | 887 | addModalContactCustomSelect, |
732 | 888 | addModalContactHiddenInput, |
733 | 889 | addModalContactInput, |
734 | | - addModalContactXBtn |
| 890 | + addModalContactXBtn, |
| 891 | + addModalContactFeedback |
735 | 892 | ); |
736 | 893 |
|
737 | 894 | // отображение изначально скрытой обвёртки/родителя |
|
754 | 911 | addModalContactElement.style.opacity = '1'; |
755 | 912 | }, 10); |
756 | 913 |
|
| 914 | + // добавление валидации для вводимых данных контакта (при добавлении строки контактов) |
| 915 | + addInputsValidation([addModalContactInput], { |
| 916 | + dynamicContactValidation: true, |
| 917 | + }); |
| 918 | + |
757 | 919 | addModalContactsArr.push(addModalContactElement); // добавление контакта во внешний/глобальный массив |
758 | 920 |
|
759 | 921 | // исключение ещё/прожатия кнопки "Добавить контакт", если контактов/уже 10 (вывод сообщения) |
|
804 | 966 | } |
805 | 967 | }); |
806 | 968 |
|
807 | | - const allModalContactsListItems = document.querySelectorAll( |
808 | | - '.modal__add-body-add-contact-item' |
809 | | - ); |
810 | | - |
811 | 969 | // замена/обновление содержимого/контента кнопки, так и через TAB/Enter (согласно значений li/вариантов) |
812 | 970 | addModalContactList.addEventListener('click', (event) => { |
813 | 971 | if (event.target.tagName === 'LI') { |
|
0 commit comments