|
1161 | 1161 | }); |
1162 | 1162 | }); |
1163 | 1163 |
|
1164 | | - // запуск проверки, последующего удаления/сохранения строк контактов в зависимости от состояний/наполнения (при закрытии модального окна, передача объекта/context(a)) |
| 1164 | + // отработка/момента закрытия модального окна (ряд сопутствующих действий, передача объекта/context(a)) |
1165 | 1165 | modalWrap.addEventListener('hide.bs.modal', (event) => { |
1166 | | - deleteModalRowContacts(event, { |
| 1166 | + const context = { |
1167 | 1167 | modalWrap, |
1168 | 1168 | modalBodyAddContactsRowWrap, |
1169 | 1169 | modalBodyAddBtn, |
1170 | | - }); |
| 1170 | + }; |
| 1171 | + |
| 1172 | + // проверка на наличие валидных данных в инпутах: основных, контактных (хотя бы в одном.. отработка confirm) |
| 1173 | + const hasAnyData = checkModalInputsBeforeClose(event, context); |
| 1174 | + |
| 1175 | + // если/там "cancel" в confirm, перевод focus на кнопку "Сохранить" |
| 1176 | + if (!hasAnyData) { |
| 1177 | + return; // т.е. без/вообще удалений инпутов (и "пустые" и не валидные остаются.. пока) |
| 1178 | + } |
| 1179 | + |
| 1180 | + // если/там "ок" в confirm, отработка удаления и "пустых", и невалидных контактов (если такие были) |
| 1181 | + deleteModalRowContacts(context); |
1171 | 1182 | }); |
1172 | 1183 |
|
1173 | 1184 | // очистка массива после закрытия модального окна |
|
1198 | 1209 | // return observer; // можно вернуть observe (если более не требуется) |
1199 | 1210 | } |
1200 | 1211 |
|
| 1212 | + // ** организация проверки на наличие валидных данных в модальных инпутах: основных, контактных (отработка "уточняющего" confirm, возврат true/false) |
| 1213 | + function checkModalInputsBeforeClose(event, context = {}) { |
| 1214 | + const { modalWrap } = context; // получение необходимого элемента (через деструктуризациию входящего/передаваемого объекта) |
| 1215 | + const modalInputs = Array.from(modalWrap.querySelectorAll('.modal-input')); // фиксация всех модальных инпутов |
| 1216 | + |
| 1217 | + // определение заполненных/валидных инпутов (хотя бы одного) |
| 1218 | + const hasValidInputs = modalInputs.some((input) => { |
| 1219 | + return ( |
| 1220 | + input.value.trim() !== '' && !input.classList.contains('is-invalid') |
| 1221 | + ); |
| 1222 | + }); |
| 1223 | + |
| 1224 | + // отработка уточняющего сообщения (если есть заполненные/валидные инпуты) |
| 1225 | + if (hasValidInputs) { |
| 1226 | + const userConfirmed = confirm( |
| 1227 | + 'Есть не сохранённые данные! Закрыть окно?' |
| 1228 | + ); |
| 1229 | + |
| 1230 | + if (!userConfirmed) { |
| 1231 | + event.preventDefault(); // исключение закрытия модального окна |
| 1232 | + event.stopPropagation(); // исключение передачи данного события (выше) |
| 1233 | + |
| 1234 | + // организация/перевод focus на кнопку "Сохранить" (при введённых данных, при "cancel" в confirm) |
| 1235 | + const saveButton = modalWrap.querySelector('#modal-body-save-btn'); |
| 1236 | + if (saveButton) { |
| 1237 | + // установка через задержку (без задержки не фокусируется) |
| 1238 | + setTimeout(() => { |
| 1239 | + saveButton.classList.add('custom-focus'); // добавление "класса" для выделения |
| 1240 | + saveButton.focus(); // добавление "программного/TAB" фокуса |
| 1241 | + |
| 1242 | + // очистка выделения кнопки (при переводе фокуса) |
| 1243 | + saveButton.addEventListener('blur', () => { |
| 1244 | + saveButton.classList.remove('custom-focus'); |
| 1245 | + }); |
| 1246 | + }, 100); // минимальная задержка |
| 1247 | + } |
| 1248 | + |
| 1249 | + return false; // т.е. при "cancel" в confirm, всё остаётся как было (т.е. вообще/без удалений) |
| 1250 | + } |
| 1251 | + } |
| 1252 | + |
| 1253 | + return true; // т.е. при "ok" в confirm, всё можно очищать.. удалять и "пустые", и невалидные контакты |
| 1254 | + } |
| 1255 | + |
1201 | 1256 | // ** организация "динамического" добавления строки контакта/row-contact (по нажатию "Добавить контакт" кнопки, в модальных/универсальных окнах) |
1202 | 1257 | function createModalContactsElement(context = {}) { |
1203 | 1258 | const { modalWrap, modalBodyAddContactsRowWrap, modalBodyAddBtn } = context; // получение необходимых элементов (через деструктуризациию входящего/передаваемого объекта) |
|
1664 | 1719 |
|
1665 | 1720 | const isCurrentInputFilled = |
1666 | 1721 | currentInput && currentInput.value.trim() !== ''; |
| 1722 | + const isCurrentInputValid = |
| 1723 | + currentInput && !currentInput.classList.contains('is-invalid'); |
1667 | 1724 | let confirmed = true; // изначально подтверждение/confirm не требуется |
1668 | 1725 |
|
1669 | | - if (isCurrentInputFilled) { |
1670 | | - confirmed = confirm('Вы действительно хотите удалить этот контакт?'); // если/есть данные в инпуте, то тогда confirm/подтверждение при удалении |
| 1726 | + if (isCurrentInputFilled && isCurrentInputValid) { |
| 1727 | + confirmed = confirm('Вы действительно хотите удалить этот контакт?'); // если/есть валидные данные в инпуте, то тогда confirm/подтверждение при удалении (так, сразу удаление) |
1671 | 1728 | } |
1672 | 1729 |
|
1673 | 1730 | if (confirmed) { |
|
1698 | 1755 | } |
1699 | 1756 | } |
1700 | 1757 |
|
1701 | | - // ** проверка/последующее удаление незаполненных/невалидных, "просто" row-контактов (при закрытии модального окна) |
1702 | | - function deleteModalRowContacts(event, context = {}) { |
| 1758 | + // ** проверка/последующее удаление незаполненных/невалидных row-контактов (при закрытии модального окна) |
| 1759 | + function deleteModalRowContacts(context = {}) { |
1703 | 1760 | const { modalWrap, modalBodyAddContactsRowWrap, modalBodyAddBtn } = context; // получение необходимых элементов (через деструктуризациию входящего/передаваемого объекта) |
1704 | | - const allContactRows = Array.from( |
1705 | | - modalWrap.querySelectorAll('.modal-contact-element') // фиксация всех строк контактов |
1706 | | - ); |
1707 | 1761 |
|
1708 | | - // определение заполненных/валидных контактов (хотя бы одного) |
1709 | | - const validContactsExist = allContactRows.some((row) => { |
1710 | | - const input = row.querySelector('.modal-contact-input'); |
1711 | | - return ( |
1712 | | - input && |
1713 | | - input.value.trim() !== '' && |
1714 | | - !input.classList.contains('is-invalid') |
1715 | | - ); |
1716 | | - }); |
1717 | | - |
1718 | | - // отработка уточняющего сообщения (если есть заполненные/валидные контакты) |
1719 | | - if (validContactsExist) { |
1720 | | - const userConfirmed = confirm( |
1721 | | - 'Есть не сохранённые данные! Закрыть окно?' |
1722 | | - ); |
1723 | | - |
1724 | | - if (!userConfirmed) { |
1725 | | - event.preventDefault(); // исключение закрытия модального окна |
1726 | | - event.stopPropagation(); // исключение передачи данного события (выше) |
1727 | | - |
1728 | | - // организация/перевод focus на кнопку "Сохранить" (при введённых данных, при "cancel" в confirm) |
1729 | | - const saveButton = modalWrap.querySelector('#modal-body-save-btn'); |
1730 | | - if (saveButton) { |
1731 | | - // установка через задержку (без задержки не фокусируется) |
1732 | | - setTimeout(() => { |
1733 | | - saveButton.classList.add('custom-focus'); // добавление "класса" для выделения |
1734 | | - saveButton.focus(); // добавление фокуса (программно) |
1735 | | - |
1736 | | - // очистка выделения (при переводе фокуса) |
1737 | | - saveButton.addEventListener('blur', () => { |
1738 | | - saveButton.classList.remove('custom-focus'); |
1739 | | - }); |
1740 | | - }, 100); // минимальная задержка |
1741 | | - } |
| 1762 | + if (!modalWrap) return; // если modalWrap "вообще" не определён, выход из функции |
1742 | 1763 |
|
1743 | | - return; // при "cancel" по confirm, всё остаётся как было (т.е. вообще/без удалений) |
1744 | | - } |
1745 | | - } |
| 1764 | + const allContactRows = Array.from( |
| 1765 | + modalWrap.querySelectorAll('.modal-contact-element') // фиксация всех строк контактов (если имеются) |
| 1766 | + ); |
1746 | 1767 |
|
1747 | | - // удаления "любых" строк, через задержку (ряд дополнительных действий) |
| 1768 | + // перебор полученных контактов (ряд дополнительных действий) |
1748 | 1769 | allContactRows.forEach((contactRow) => { |
| 1770 | + // отработка через задержку |
1749 | 1771 | setTimeout(() => { |
1750 | | - // удаление, обновление массива |
1751 | | - contactRow.remove(); |
1752 | | - const contactIndex = modalContactsArr.indexOf(contactRow); |
1753 | | - if (contactIndex > -1) { |
1754 | | - modalContactsArr.splice(contactIndex, 1); |
1755 | | - } |
| 1772 | + const rowInput = contactRow.querySelector('.modal-contact-input'); // фиксация контактных инпутов |
1756 | 1773 |
|
1757 | | - // проверка общего количества row-контактов |
1758 | | - if (modalContactsArr.length < 10) { |
1759 | | - modalBodyAddBtn.disabled = false; // разблокировка кнопки "Добавить контакт", если меньше 10 контактов |
1760 | | - } |
| 1774 | + // проверка/удаление только "пустых" и невалидных строк |
| 1775 | + if ( |
| 1776 | + !rowInput || |
| 1777 | + rowInput.value.trim() === '' || |
| 1778 | + rowInput.classList.contains('is-invalid') |
| 1779 | + ) { |
| 1780 | + contactRow.remove(); |
| 1781 | + // обновление массива |
| 1782 | + const contactIndex = modalContactsArr.indexOf(contactRow); |
| 1783 | + if (contactIndex > -1) { |
| 1784 | + modalContactsArr.splice(contactIndex, 1); |
| 1785 | + } |
1761 | 1786 |
|
1762 | | - // скрытие "обвёртки" контактов если в массиве контактов пусто |
1763 | | - if (modalContactsArr.length === 0) { |
1764 | | - modalBodyAddContactsRowWrap.classList.add('d-none'); |
1765 | | - modalBodyAddBtn.classList.remove('modal-contact-btn-margin'); // удаление дополнительных отступов |
| 1787 | + // проверка общего количества row-контактов |
| 1788 | + if (modalContactsArr.length < 10) { |
| 1789 | + modalBodyAddBtn.disabled = false; // разблокировка кнопки "Добавить контакт", если меньше 10 контактов |
| 1790 | + } |
| 1791 | + |
| 1792 | + // скрытие "обвёртки" контактов если в массиве контактов пусто |
| 1793 | + if (modalContactsArr.length === 0) { |
| 1794 | + modalBodyAddContactsRowWrap.classList.add('d-none'); |
| 1795 | + modalBodyAddBtn.classList.remove('modal-contact-btn-margin'); // удаление дополнительных отступов |
| 1796 | + } |
1766 | 1797 | } |
1767 | | - }, 500); // минимальная задержка (что бы не видеть удаления при анимации/закрытия) |
| 1798 | + }, 500); // минимальная задержка (чтобы не видеть удаления при анимации/закрытии) |
1768 | 1799 | }); |
1769 | 1800 | } |
1770 | 1801 |
|
|
0 commit comments