Skip to content

Commit a688f0d

Browse files
committed
[PRAC/cont] Add logic/check data in modal-inputs
Organiz checks for valid data in modal-inputs: main/contact (confirm). Worth noting: - correction in logic of deleting empty/invalid row-contacts. core: B-3 / JS-BL
1 parent 74d632c commit a688f0d

File tree

1 file changed

+94
-63
lines changed
  • core-courses/3-js-basic-level/practicum-js-basic-level/sb-crm-client/js

1 file changed

+94
-63
lines changed

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

Lines changed: 94 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,13 +1161,24 @@
11611161
});
11621162
});
11631163

1164-
// запуск проверки, последующего удаления/сохранения строк контактов в зависимости от состояний/наполнения (при закрытии модального окна, передача объекта/context(a))
1164+
// отработка/момента закрытия модального окна (ряд сопутствующих действий, передача объекта/context(a))
11651165
modalWrap.addEventListener('hide.bs.modal', (event) => {
1166-
deleteModalRowContacts(event, {
1166+
const context = {
11671167
modalWrap,
11681168
modalBodyAddContactsRowWrap,
11691169
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);
11711182
});
11721183

11731184
// очистка массива после закрытия модального окна
@@ -1198,6 +1209,50 @@
11981209
// return observer; // можно вернуть observe (если более не требуется)
11991210
}
12001211

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+
12011256
// ** организация "динамического" добавления строки контакта/row-contact (по нажатию "Добавить контакт" кнопки, в модальных/универсальных окнах)
12021257
function createModalContactsElement(context = {}) {
12031258
const { modalWrap, modalBodyAddContactsRowWrap, modalBodyAddBtn } = context; // получение необходимых элементов (через деструктуризациию входящего/передаваемого объекта)
@@ -1664,10 +1719,12 @@
16641719

16651720
const isCurrentInputFilled =
16661721
currentInput && currentInput.value.trim() !== '';
1722+
const isCurrentInputValid =
1723+
currentInput && !currentInput.classList.contains('is-invalid');
16671724
let confirmed = true; // изначально подтверждение/confirm не требуется
16681725

1669-
if (isCurrentInputFilled) {
1670-
confirmed = confirm('Вы действительно хотите удалить этот контакт?'); // если/есть данные в инпуте, то тогда confirm/подтверждение при удалении
1726+
if (isCurrentInputFilled && isCurrentInputValid) {
1727+
confirmed = confirm('Вы действительно хотите удалить этот контакт?'); // если/есть валидные данные в инпуте, то тогда confirm/подтверждение при удалении (так, сразу удаление)
16711728
}
16721729

16731730
if (confirmed) {
@@ -1698,73 +1755,47 @@
16981755
}
16991756
}
17001757

1701-
// ** проверка/последующее удаление незаполненных/невалидных, "просто" row-контактов (при закрытии модального окна)
1702-
function deleteModalRowContacts(event, context = {}) {
1758+
// ** проверка/последующее удаление незаполненных/невалидных row-контактов (при закрытии модального окна)
1759+
function deleteModalRowContacts(context = {}) {
17031760
const { modalWrap, modalBodyAddContactsRowWrap, modalBodyAddBtn } = context; // получение необходимых элементов (через деструктуризациию входящего/передаваемого объекта)
1704-
const allContactRows = Array.from(
1705-
modalWrap.querySelectorAll('.modal-contact-element') // фиксация всех строк контактов
1706-
);
17071761

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 "вообще" не определён, выход из функции
17421763

1743-
return; // при "cancel" по confirm, всё остаётся как было (т.е. вообще/без удалений)
1744-
}
1745-
}
1764+
const allContactRows = Array.from(
1765+
modalWrap.querySelectorAll('.modal-contact-element') // фиксация всех строк контактов (если имеются)
1766+
);
17461767

1747-
// удаления "любых" строк, через задержку (ряд дополнительных действий)
1768+
// перебор полученных контактов (ряд дополнительных действий)
17481769
allContactRows.forEach((contactRow) => {
1770+
// отработка через задержку
17491771
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'); // фиксация контактных инпутов
17561773

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+
}
17611786

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+
}
17661797
}
1767-
}, 500); // минимальная задержка (что бы не видеть удаления при анимации/закрытия)
1798+
}, 500); // минимальная задержка (чтобы не видеть удаления при анимации/закрытии)
17681799
});
17691800
}
17701801

0 commit comments

Comments
 (0)