Skip to content

Commit 2f7dd0c

Browse files
committed
[PRAC/cont] Move to obj/context transfer logic
Organiz transit to logic of transfer obj's/context, not just arguments. Worth noting: - changing to "as is" repeating names/naming for incoming elements/parameters (in functions). core: B-3 / JS-BL
1 parent 3be6dd0 commit 2f7dd0c

File tree

2 files changed

+79
-59
lines changed

2 files changed

+79
-59
lines changed

core-courses/3-js-basic-level/practicum-js-basic-level/sb-crm-client/js/customTippy.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@
5656
initTippy('#table-th-change', 'сортировать ⇵', 'bottom', {
5757
offset: [0, 2],
5858
});
59-
initTippy('.modal__add-header-x-btn', 'закрыть', 'left', {
60-
offset: [0, 13],
61-
});
6259
}
6360

6461
initTippyForSearchLogo();

core-courses/3-js-basic-level/practicum-js-basic-level/sb-crm-client/js/index.js

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,8 @@
907907
const modalTitle = type === 'add' ? 'Новый клиент' : 'Изменить данные';
908908
const modalCancelBtn = type === 'add' ? 'Отмена' : 'Удалить клиента';
909909

910+
const modalContactsArr = []; // организация массива контактов (будущих контактов)
911+
910912
const modalWrap = document.createElement('div');
911913
const modalDialog = document.createElement('div');
912914
const modalContent = document.createElement('div');
@@ -1145,12 +1147,31 @@
11451147
modalDialog.append(modalContent);
11461148
modalWrap.append(modalDialog);
11471149

1148-
// !
1149-
// запуск логики добавления/создания строки контактов
1150+
// вызов/инициализация tooltips для "X" модальной кнопки (для кнопки закрытия модального окна, с задержкой)
1151+
setTimeout(() => {
1152+
initTippy(modalHeaderXBtn, 'закрыть', 'left');
1153+
}, 0);
1154+
1155+
// запуск логики добавления/создания "внутренней" строки контактов (передача объекта/context(a) с необходимыми элементами/сущностями)
11501156
modalBodyAddBtn.addEventListener('click', () => {
1151-
createModalContactsElement();
1157+
createModalContactsElement({
1158+
modalWrap,
1159+
modalBodyAddBtn,
1160+
modalContactsArr,
1161+
});
11521162
});
11531163

1164+
// запуск проверки на "пустые" контакты (перед закрытием модального окна)
1165+
modalWrap.addEventListener('hide.bs.modal', checkEmptyRowContacts);
1166+
1167+
// удаление/очистка от невалидных row-контактов (при закрытие модального окна, передача объекта/context(a))
1168+
modalWrap.addEventListener('hidden.bs.modal', () =>
1169+
removeInvalidRowContacts({
1170+
modalBodyAddBtn,
1171+
modalContactsArr,
1172+
})
1173+
);
1174+
11541175
return modalWrap; // возврат модального окна (т.е. здесь/без добавления в DOM.. позже, при клике)
11551176
}
11561177

@@ -1175,9 +1196,9 @@
11751196
}
11761197

11771198
// ** организация "динамического" добавления строки контакта/row-contact (по нажатию "Добавить контакт" кнопки, в модальных/универсальных окнах)
1178-
const modalContactsArr = [];
1199+
function createModalContactsElement(context = {}) {
1200+
const { modalWrap, modalBodyAddBtn, modalContactsArr } = context; // получение необходимых элементов/сущностей (через деструктуризациию входящего/передаваемого объекта)
11791201

1180-
function createModalContactsElement() {
11811202
if (modalContactsArr.length >= 10) return; // проверка количества контактов (не более 10)
11821203

11831204
const modalContactElement = document.createElement('div');
@@ -1354,7 +1375,7 @@
13541375
dynamicContactValidation: true,
13551376
});
13561377

1357-
modalContactsArr.push(modalContactElement); // добавление контакта во внешний/глобальный массив
1378+
modalContactsArr.push(modalContactElement); // добавление контакта во "внешний" массив
13581379

13591380
// исключение ещё/прожатия кнопки "Добавить контакт", если контактов/уже 10 (вывод сообщения)
13601381
if (modalContactsArr.length >= 10) {
@@ -1397,26 +1418,24 @@
13971418
// замена/обновление содержимого/контента кнопки, так.. и через TAB/Enter (согласно значений li/вариантов)
13981419
modalContactList.addEventListener('click', (event) => {
13991420
if (event.target.tagName === 'LI') {
1400-
getContactDropSelection(
1401-
event.target,
1421+
getContactDropSelection(event.target, {
14021422
modalContactDropBtn,
14031423
modalContactList,
14041424
modalContactHiddenInput,
1405-
modalContactInput
1406-
); // отработка выбора
1425+
modalContactInput,
1426+
}); // отработка выбора (передача context(a))
14071427
}
14081428
});
14091429

14101430
modalContactList.addEventListener('keydown', (event) => {
14111431
if (event.target.tagName === 'LI' && event.key === 'Enter') {
14121432
event.preventDefault(); // исключение непредвиденных событий/поведения
1413-
getContactDropSelection(
1414-
event.target,
1433+
getContactDropSelection(event.target, {
14151434
modalContactDropBtn,
14161435
modalContactList,
14171436
modalContactHiddenInput,
1418-
modalContactInput
1419-
); // отработка выбора
1437+
modalContactInput,
1438+
}); // отработка выбора (передача context(a))
14201439
}
14211440
});
14221441

@@ -1434,7 +1453,7 @@
14341453
}
14351454
});
14361455

1437-
addModalWrap.addEventListener('focusout', (event) => {
1456+
modalWrap.addEventListener('focusout', (event) => {
14381457
const openDropdownBtn = document.querySelector('.drop-open');
14391458

14401459
// закрытие/скрытие выпадающего списка (если "фокус" перешёл на другой элемент, в другое место)
@@ -1460,59 +1479,70 @@
14601479
// организация удаления строки контактов
14611480
modalContactXBtn.addEventListener('click', (event) => {
14621481
event.stopPropagation(); // исключение непредвиденных событий/поведения
1463-
deleteModalContactsElement(event); // удаление строки контактов (посредствам "X" кнопки)
1482+
deleteModalContactsElement(event, {
1483+
modalBodyAddBtn,
1484+
modalContactsArr,
1485+
}); // удаление строки контактов (посредствам "X" кнопки, передача объекта/context(a))
14641486
});
14651487

14661488
// организация удаления строки контактов и через TAB/Enter
14671489
modalContactXBtn.addEventListener('keydown', (event) => {
14681490
if (event.key === 'Enter') {
14691491
event.stopPropagation(); // исключение непредвиденных событий/поведения
1470-
deleteModalContactsElement(event); // удаление строки контактов (посредствам "X" кнопки)
1492+
deleteModalContactsElement(event, {
1493+
modalBodyAddBtn,
1494+
modalContactsArr,
1495+
}); // удаление строки контактов (посредствам "X" кнопки, передача объекта/context(a))
14711496
}
14721497
});
14731498
}
14741499

14751500
// ** обработка выбора/типа строки контакта, согласно вариантов выпадающего drop-btn списка (в модальных/универсальных окнах, ряд сопутствующих действий)
1476-
function getContactDropSelection(
1477-
target,
1478-
dropBtn,
1479-
contactList,
1480-
hiddenInput,
1481-
contactInput
1482-
) {
1501+
function getContactDropSelection(target, context = {}) {
14831502
const selectedItemValue = target.getAttribute('data-value');
1484-
const previousItemValue = hiddenInput.value; // фиксация скрытого значения
1503+
const {
1504+
modalContactDropBtn,
1505+
modalContactList,
1506+
modalContactHiddenInput,
1507+
modalContactInput,
1508+
} = context; // получение необходимых элементов/сущностей (через деструктуризациию входящего/передаваемого объекта)
1509+
1510+
const previousItemValue = modalContactHiddenInput.value; // фиксация скрытого значения
14851511

14861512
// обработка смены/типа контакта (если/с одного "вдруг" на другой решили)
14871513
if (
1488-
!changeContactRowType(contactInput, selectedItemValue, previousItemValue)
1514+
!changeContactRowType(
1515+
modalContactInput,
1516+
selectedItemValue,
1517+
previousItemValue
1518+
)
14891519
) {
14901520
return; // исключение корректировки, если/в confirm отмена
14911521
}
14921522

1493-
dropBtn.textContent = target.textContent;
1494-
hiddenInput.value = selectedItemValue; // обновление данных в "скрытом" input (для последующей отправки на сервер)
1523+
modalContactDropBtn.textContent = target.textContent;
1524+
modalContactHiddenInput.value = selectedItemValue; // обновление данных в "скрытом" input (для последующей отправки на сервер)
14951525

14961526
target.style.display = 'none'; // скрытие li/варианта в выпадающем списке (т.е. после выбора, отображения в drop-btn)
14971527

14981528
// отображение/снова li/варианта (т.е. до этого скрытого)
14991529
if (previousItemValue) {
1500-
const previousItem = contactList.querySelector(
1530+
const previousItem = modalContactList.querySelector(
15011531
`[data-value="${previousItemValue}"]`
15021532
);
15031533
if (previousItem) {
15041534
previousItem.style.display = ''; // сброс display: none;
15051535
}
15061536
}
15071537

1508-
updateRowInputType(contactInput, selectedItemValue); // обновление атрибута/значения "type" у/для инпута (кому возможно)
1509-
updateDropItemPaddings(contactList); // обновление/изменение отступов для li/вариантов выпадающего списка (для первого и последнего элементов)
1538+
updateRowInputType(modalContactInput, selectedItemValue); // обновление атрибута/значения "type" у/для инпута (кому возможно)
1539+
updateDropItemPaddings(modalContactList); // обновление/изменение отступов для li/вариантов выпадающего списка (для первого и последнего элементов)
15101540
closeBtnDropdown(); // закрытие выпадающего списка
1511-
contactInput.focus(); // перевод фокуса на соседний инпут (после выбора в выпадающем списке)
1541+
modalContactInput.focus(); // перевод фокуса на соседний инпут (после выбора в выпадающем списке)
15121542
}
15131543

15141544
// ** обновление атрибута/значения "type" у/для модального row-contact инпута (кому возможно, после выбора)
1515-
function updateRowInputType(input, contactType) {
1545+
function updateRowInputType(modalContactInput, contactType) {
15161546
// объект для сопоставления (кому заменять, на какое значение)
15171547
const typeMapping = {
15181548
phone: 'tel',
@@ -1522,18 +1552,17 @@
15221552

15231553
// корректировка атрибута/значения "type" (или будет text)
15241554
const newType = typeMapping[contactType] || 'text';
1525-
input.setAttribute('type', newType);
1555+
modalContactInput.setAttribute('type', newType);
15261556
}
15271557

1528-
// ! корректировка
15291558
// ** обновление/изменение отступов у/для модального row-contact списка (для первого и последнего li/элементов)
1530-
function updateDropItemPaddings(dropList) {
1531-
Array.from(dropList.children).forEach((item) => {
1559+
function updateDropItemPaddings(modalContactList) {
1560+
Array.from(modalContactList.children).forEach((item) => {
15321561
item.classList.remove('first-visible', 'last-visible'); // изначальная очистка от дополнительных классов
15331562
});
15341563

15351564
// фиксация li/вариантов находящихся "сейчас" в выпадающем списке
1536-
const visibleDropItems = Array.from(dropList.children).filter(
1565+
const visibleDropItems = Array.from(modalContactList.children).filter(
15371566
(item) => item.style.display !== 'none'
15381567
);
15391568

@@ -1546,7 +1575,6 @@
15461575
}
15471576
}
15481577

1549-
// ! корректировка
15501578
// ** организация закрытия/скрытия выпадающего row-contact списка в модальном окне (снятие фокуса)
15511579
function closeBtnDropdown() {
15521580
const openDropdownBtn = document.querySelector('.drop-open'); // фиксация "открывающей" drop-кнопки
@@ -1559,10 +1587,9 @@
15591587
}
15601588
}
15611589

1562-
// ! корректировка
15631590
// ** организация замены выбора/типа модального row-контакта, после начала/внесения данных в инпут (вывод уточняющего сообщения)
1564-
function changeContactRowType(input, newType, previousType) {
1565-
const inputCurrentValue = input.value.trim();
1591+
function changeContactRowType(modalContactInput, newType, previousType) {
1592+
const inputCurrentValue = modalContactInput.value.trim();
15661593

15671594
// определение типов контактов, которые схожи/одного формата (замена без изменений)
15681595
const phoneTypes = ['phone', 'extra-phone'];
@@ -1588,31 +1615,32 @@
15881615
return false; // отмена изменений
15891616
}
15901617

1591-
input.value = ''; // очистка инпута
1618+
modalContactInput.value = ''; // очистка инпута
15921619
}
15931620

15941621
// очистка от уведомлений на некорректный ввод/валидации (от предыдущих типов, кроме схожих/телефонов)
15951622
if (
15961623
!phoneTypes.includes(newType) ||
15971624
(phoneTypes.includes(newType) && !phoneTypes.includes(previousType))
15981625
) {
1599-
const feedback = input
1626+
const feedback = modalContactInput
16001627
.closest('.modal-contact-element')
16011628
.querySelector('.invalid-feedback');
1629+
16021630
if (feedback) {
16031631
feedback.textContent = ''; // удаление сообщений
16041632
}
1605-
input.classList.remove('is-invalid'); // исключение классов ошибки
1633+
modalContactInput.classList.remove('is-invalid'); // исключение классов ошибки
16061634
}
16071635

1608-
updateRowInputType(input, newType); // обновление атрибута/значения "type" у/дя инпута (нового выбора)
1636+
updateRowInputType(modalContactInput, newType); // обновление атрибута/значения "type" у/дя инпута (нового выбора)
16091637
return true; // факт завершения
16101638
}
16111639

1612-
// ! корректировка
16131640
// ** удаление строки row-контакта в модальном окне (через "X" кнопку, с/без уточняющего сообщения)
1614-
function deleteModalContactsElement(event) {
1641+
function deleteModalContactsElement(event, context = {}) {
16151642
const clickedContactsXBtn = event.currentTarget; // получение ИМЕННО кнопки, а не/может внутренней иконки (согласно "размазанного" события)
1643+
const { modalBodyAddBtn, modalContactsArr } = context; // получение необходимых элементов/сущностей (через деструктуризациию входящего/передаваемого объекта)
16161644

16171645
if (clickedContactsXBtn) {
16181646
tippy.hideAll(); // предварительное скрытие всех/вдруг "активных" tooltips (перед удалением искомой строки)
@@ -1658,7 +1686,7 @@
16581686
.length === 0
16591687
) {
16601688
const modalContactsRowWrap = document.querySelector(
1661-
'.modal__add-body-add-contacts-row-wrap'
1689+
'.modal__body-contacts-row-wrap'
16621690
);
16631691
modalContactsRowWrap.classList.add('d-none');
16641692
modalBodyAddBtn.classList.remove('modal-contact-btn-margin');
@@ -1670,7 +1698,6 @@
16701698
}
16711699
}
16721700

1673-
// ! корректировка
16741701
// ** организация проверки на "пустые" row-контакты, перед закрытием соответствующего модального окна (вывод сообщения)
16751702
function checkEmptyRowContacts(event) {
16761703
const allContactRows = document.querySelectorAll('.modal-contact-element');
@@ -1696,11 +1723,9 @@
16961723
}
16971724
}
16981725

1699-
addModalWrap.addEventListener('hide.bs.modal', checkEmptyRowContacts); // запуск проверки на "пустые" контакты (перед закрытием add-модального окна)
1700-
1701-
// ! корректировка
17021726
// ** удаление/очистка от невалидных row-контактов (при закрытии модального окна)
1703-
function removeInvalidRowContacts() {
1727+
function removeInvalidRowContacts(context) {
1728+
const { modalBodyAddBtn, modalContactsArr } = context; // получение необходимых элементов/сущностей (через деструктуризациию входящего/передаваемого объекта)
17041729
const invalidContactRows = document.querySelectorAll(
17051730
'.modal-contact-element .is-invalid'
17061731
);
@@ -1733,8 +1758,6 @@
17331758
}
17341759
}
17351760

1736-
addModalWrap.addEventListener('hidden.bs.modal', removeInvalidRowContacts); // удаление/очистка от невалидных row-контактов (при закрытие add-модального окна)
1737-
17381761
// ** дополнительная/местная организация логики для tooltips (т.е. помимо customTippy.js)
17391762
function initTippy(selector, content, side) {
17401763
// определение входящего элемента (селектор или DOM-элемент, поиск/корректировка)

0 commit comments

Comments
 (0)