|
487 | 487 | // основные блоки/составляющие элементы приложения |
488 | 488 | crm.append(crmSearch, crmOutput, crmAdd); |
489 | 489 |
|
490 | | - // ** организация появления/скрытия поля для ввода данных/фильтрационного инпута (по нажатию на logo, на 320px) |
| 490 | + // ** появление/скрытие поля для ввода данных/фильтрационного инпута (по нажатию на logo, на 320px) |
491 | 491 | searchLogoImg.addEventListener('click', () => { |
492 | 492 | document |
493 | 493 | .querySelector('.crm__search-data') |
494 | 494 | .classList.toggle('show-search-input'); |
495 | 495 | }); |
496 | 496 |
|
497 | | - // ** организация валидации для ввода данных/фильтрационного инпута (для формы без submit) |
498 | | - function searchFormInputValidation(input) { |
499 | | - input.addEventListener('input', (event) => { |
500 | | - const target = event.target; |
501 | | - const targetParentNode = target.parentNode; |
502 | | - const invalidFeed = targetParentNode.querySelector('.invalid-feedback'); |
503 | | - |
504 | | - // принудительное исключение пробелов (в начале поля для ввода) |
505 | | - target.value = target.value.replace(/^\s+/, ''); |
506 | | - |
507 | | - // только русские буквы (без цифр/символов), "один" дефис (для двойных фамилий) и без необоснованных пробелов |
508 | | - if ( |
509 | | - /[^а-яА-ЯёЁ\s-]/.test(target.value) || |
510 | | - (target.value.match(/-/g) || []).length > 1 || |
511 | | - /\s{2,}/.test(target.value) |
512 | | - ) { |
513 | | - target.classList.add('is-invalid'); |
| 497 | + // ** организация "ОБЩЕЙ" логики для валидации полей ввода/инпутов (согласно передаваемых параметров) |
| 498 | + function addInputsValidation(inputs, options) { |
| 499 | + inputs.forEach((input) => |
| 500 | + input.addEventListener('input', (event) => { |
| 501 | + const target = event.target; |
| 502 | + const targetParentNode = target.parentNode; |
| 503 | + const invalidFeed = targetParentNode.querySelector('.invalid-feedback'); |
| 504 | + |
| 505 | + // принудительное исключение пробелов (в начале полей для ввода) |
| 506 | + target.value = target.value.replace(/^\s+/, ''); |
| 507 | + |
| 508 | + // принудительное исключение дефисов (в начале полей для ввода) |
| 509 | + if (options.singleHyphen) { |
| 510 | + target.value = target.value.replace(/^-+/, ''); |
| 511 | + } |
| 512 | + |
| 513 | + // принудительное удаление пробелов после дефисов (дефисов после пробелов) |
| 514 | + target.value = target.value.replace(/-\s+/g, '-'); |
| 515 | + target.value = target.value.replace(/\s+-/g, ''); |
| 516 | + |
| 517 | + // сбор ошибок/вывод "соответствующих" сообщений |
| 518 | + const errors = []; |
| 519 | + |
| 520 | + if (options.allowOnlyRussian && /[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
| 521 | + errors.push( |
| 522 | + 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!' |
| 523 | + ); |
| 524 | + } |
| 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('Дефисы НЕдопустимы!'); |
| 534 | + } |
| 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 | + ); |
| 542 | + } |
| 543 | + } |
| 544 | + } |
| 545 | + } |
| 546 | + |
| 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('Пробелы НЕдопустимы!'); |
| 557 | + } |
514 | 558 |
|
515 | | - if (/[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
516 | | - invalidFeed.textContent = |
517 | | - 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!'; |
518 | | - } else if ((target.value.match(/-/g) || []).length > 1) { |
519 | | - invalidFeed.textContent = 'Некорректный ввод! Только ОДИН дефис!'; |
| 559 | + // отработка ошибок |
| 560 | + if (errors.length > 0) { |
| 561 | + target.classList.add('is-invalid'); |
| 562 | + invalidFeed.textContent = errors.join(' '); |
520 | 563 | } else { |
521 | | - invalidFeed.textContent = |
522 | | - 'Некорректный ввод! Только ОДИН пробел между словами!'; |
| 564 | + target.classList.remove('is-invalid'); |
| 565 | + invalidFeed.textContent = ''; // очистка сообщений об ошибках |
523 | 566 | } |
524 | | - } else { |
525 | | - target.classList.remove('is-invalid'); |
526 | | - invalidFeed.textContent = ''; // очистка сообщения об ошибке |
527 | | - } |
528 | | - }); |
| 567 | + }) |
| 568 | + ); |
529 | 569 | } |
530 | 570 |
|
531 | | - // получение заглавного search-инпута (последующая валидация) |
| 571 | + // добавление валидации для заглавного фильтрационного инпута ("Введите запрос") |
532 | 572 | const searchFormMainInput = document.querySelector('.crm__search-form input'); |
533 | | - searchFormInputValidation(searchFormMainInput); |
| 573 | + addInputsValidation([searchFormMainInput], { |
| 574 | + allowOnlyRussian: true, |
| 575 | + singleHyphen: true, |
| 576 | + noExtraSpaces: true, |
| 577 | + }); |
| 578 | + |
| 579 | + // добавление валидации для ввода данных/в модальном окне (при добавлении нового/клиента) |
| 580 | + const allAddModalFormInputs = document.querySelectorAll( |
| 581 | + '.modal__add-body-input' |
| 582 | + ); |
| 583 | + addInputsValidation(allAddModalFormInputs, { |
| 584 | + allowOnlyRussian: true, |
| 585 | + singleHyphen: true, |
| 586 | + noExtraSpaces: true, |
| 587 | + }); |
534 | 588 |
|
535 | 589 | // ** изменение направления стрелки/svg-icon, согласно прожатия по заглавной ячейке (при сортировке данных) |
536 | 590 | const allHeaderRowCells = document.querySelectorAll( |
|
567 | 621 | }); |
568 | 622 | }); |
569 | 623 |
|
570 | | - // ** организация валидации для ввода данных/в модальном окне (при добавлении нового/клиента) |
571 | | - function addModalFormInputValidation(inputs) { |
572 | | - inputs.forEach((input) => |
573 | | - input.addEventListener('input', (event) => { |
574 | | - const target = event.target; |
575 | | - const targetParentNode = target.parentNode; |
576 | | - const invalidFeed = targetParentNode.querySelector('.invalid-feedback'); |
577 | | - |
578 | | - // принудительное исключение пробелов (в начале поля для ввода) |
579 | | - target.value = target.value.replace(/^\s+/, ''); |
580 | | - |
581 | | - // только русские буквы (без цифр/символов), "один" дефис (для двойных фамилий) и без необоснованных пробелов |
582 | | - if ( |
583 | | - /[^а-яА-ЯёЁ\s-]/.test(target.value) || |
584 | | - (target.value.match(/-/g) || []).length > 1 || |
585 | | - /\s{1,}/.test(target.value) |
586 | | - ) { |
587 | | - target.classList.add('is-invalid'); |
588 | | - |
589 | | - if (/[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
590 | | - invalidFeed.textContent = |
591 | | - 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!'; |
592 | | - } else if ((target.value.match(/-/g) || []).length > 1) { |
593 | | - invalidFeed.textContent = 'Некорректный ввод! Только ОДИН дефис!'; |
594 | | - } else { |
595 | | - invalidFeed.textContent = 'Некорректный ввод! Никаких пробелов!'; |
596 | | - } |
597 | | - } else { |
598 | | - target.classList.remove('is-invalid'); |
599 | | - invalidFeed.textContent = ''; // очистка сообщения об ошибке |
600 | | - } |
601 | | - }) |
602 | | - ); |
603 | | - } |
604 | | - |
605 | | - // получение всех add-модальных инпутов (последующая валидация) |
606 | | - const allAddModalFormInputs = document.querySelectorAll( |
607 | | - '.modal__add-body-input' |
608 | | - ); |
609 | | - addModalFormInputValidation(allAddModalFormInputs); |
610 | | - |
611 | 624 | // ** динамическое добавление строки контактов в add-модальном окне (по нажатию "Добавить контакт" кнопки) |
612 | 625 | const addModalContactsArr = []; |
613 | 626 |
|
614 | 627 | function createAddModalContactsElement() { |
615 | | - // проверка количества контактов (не более 10) |
616 | | - if (addModalContactsArr.length >= 10) return; |
| 628 | + if (addModalContactsArr.length >= 10) return; // проверка количества контактов (не более 10) |
617 | 629 |
|
618 | 630 | const addModalContactElement = document.createElement('div'); |
619 | 631 | const addModalContactCustomSelect = document.createElement('div'); |
|
752 | 764 |
|
753 | 765 | let isDropdownToggleAllowed = true; // возможность/разрешение на показ выпадающего списка |
754 | 766 |
|
755 | | - // ! может вынести в отдельную функцию.. после if.. просто вызов функции() которая всё делает?? |
756 | | - |
757 | 767 | // показ/скрытие выпадающего списка вариантов/контактов (открытым может быть только один, переключение) |
758 | 768 | addModalContactDropBtn.addEventListener('click', (event) => { |
759 | 769 | if (!isDropdownToggleAllowed) return; // проверка возможности/разрешения на показ списка |
|
0 commit comments