|
275 | 275 | .classList.toggle('show-search-input'); |
276 | 276 | }); |
277 | 277 |
|
| 278 | + // TODO: |
| 279 | + // ** наполнение таблицы данных о клиентах (согласно откорректированного исходного, далее формирующегося массива) |
| 280 | + let updateClientsDataArr = []; |
| 281 | + |
278 | 282 | // ** организация "общей/универсальной" логики для валидации полей ввода/инпутов (согласно передаваемых параметров) |
279 | 283 | function mainInputsValidation(inputs, options) { |
280 | 284 | inputs.forEach((input) => |
|
1335 | 1339 | }); |
1336 | 1340 |
|
1337 | 1341 | // корректировка z-index у/для drop-btn кнопки |
1338 | | - handleDropDownZIndex(modalWrap); |
| 1342 | + correctDropDownZIndex(modalWrap); |
1339 | 1343 |
|
1340 | 1344 | // очистка массива после закрытия модального окна |
1341 | 1345 | modalWrap.addEventListener('hidden.bs.modal', () => { |
|
1578 | 1582 | }, 10); |
1579 | 1583 |
|
1580 | 1584 | // корректировка z-index у/для drop-btn кнопки |
1581 | | - handleDropDownZIndex(modalWrap); |
| 1585 | + correctDropDownZIndex(modalWrap); |
1582 | 1586 |
|
1583 | 1587 | // скрытие/сразу li/варианта, как "Телефон" (т.к. в drop-btn отображение по умолчанию) |
1584 | 1588 | if (modalContactDropBtn.textContent === 'Телефон') { |
|
1796 | 1800 | } |
1797 | 1801 |
|
1798 | 1802 | // ** корректировка z-index у/для drop-btn из строки контакта (при "focus" перекрытие соседнего row-contact инпута) |
1799 | | - function handleDropDownZIndex(modalWrap) { |
| 1803 | + function correctDropDownZIndex(modalWrap) { |
1800 | 1804 | const dropDownButtons = modalWrap.querySelectorAll( |
1801 | 1805 | '.modal__body-add-contact-drop-btn' |
1802 | 1806 | ); |
|
2056 | 2060 | } |
2057 | 2061 | } |
2058 | 2062 |
|
| 2063 | + // ** [СЕРВЕР] отправка данных/добавление клиентов на сервер, получение обратно (проверка статуса) |
| 2064 | + async function addClientToServer(clientData) { |
| 2065 | + try { |
| 2066 | + const response = await fetch('http://localhost:3000/api/clients', { |
| 2067 | + method: 'POST', |
| 2068 | + headers: { |
| 2069 | + 'Content-Type': 'application/json', |
| 2070 | + }, |
| 2071 | + body: JSON.stringify(clientData), |
| 2072 | + }); |
| 2073 | + |
| 2074 | + if (!response.ok) { |
| 2075 | + if (response.status === 422) { |
| 2076 | + const errorData = await response.json(); |
| 2077 | + throw new Error( |
| 2078 | + `Ошибка валидации: ${errorData.errors |
| 2079 | + .map((e) => e.message) |
| 2080 | + .join(', ')}` |
| 2081 | + ); |
| 2082 | + } else { |
| 2083 | + throw new Error(`Ошибка: ${response.status}`); |
| 2084 | + } |
| 2085 | + } |
| 2086 | + |
| 2087 | + // TODO: |
| 2088 | + // await getClientsServerListData(); // обновление списка студентов (в контексте.. перерисовка таблицы) |
| 2089 | + } catch (error) { |
| 2090 | + console.error('Ошибка при добавлении клиента..', error); |
| 2091 | + alert('Ошибка при добавлении клиента на сервер!'); |
| 2092 | + } |
| 2093 | + } |
| 2094 | + |
2059 | 2095 | // ** универсальная обработка модальных форм их "submit" событий, т.е. при добавление/изменении данных клиента (после валидаций, после проверки по ФИО) |
2060 | | - // ! за основу берётся students-db.. |
2061 | | - |
2062 | | - // const allFormInInputs = document.querySelectorAll( |
2063 | | - // '.dboard__input-form input' |
2064 | | - // ); |
2065 | | - // |
2066 | | - // // корректировка регистра, для полей Ф.И.О. |
2067 | | - // function toUpFirstLetter(value) { |
2068 | | - // if (!value) return ''; // если вдруг "пусто" |
2069 | | - // return value[0].toUpperCase() + value.slice(1).toLowerCase(); |
2070 | | - // } |
2071 | | - // |
2072 | | - // // проверка на совпадение по ФИО, в исходном/формирующемся массиве |
2073 | | - // function checkStudentFIO( |
2074 | | - // formInSurname, |
2075 | | - // formInName, |
2076 | | - // formInPatronymic, |
2077 | | - // updateStudentsDataArr |
2078 | | - // ) { |
2079 | | - // return updateStudentsDataArr.some( |
2080 | | - // (student) => |
2081 | | - // student.surname === formInSurname && |
2082 | | - // student.name === formInName && |
2083 | | - // student.patronymic === formInPatronymic |
2084 | | - // ); |
2085 | | - // } |
2086 | | - // |
2087 | | - // allFormInInputs.forEach((input) => { |
2088 | | - // additionalFormInputsValidation(input); // !! дополнительная валидация (на корректный ввод) |
2089 | | - // }); |
| 2096 | + // корректировка регистра, для полей ФИО |
| 2097 | + function toUpFirstLetter(value) { |
| 2098 | + if (!value) return ''; // если вдруг "пусто" |
| 2099 | + return value[0].toUpperCase() + value.slice(1).toLowerCase(); |
| 2100 | + } |
| 2101 | + |
| 2102 | + // проверка на совпадение по ФИО, в исходном/формирующемся массиве |
| 2103 | + function checkClientFIO( |
| 2104 | + formInSurname, |
| 2105 | + formInName, |
| 2106 | + formInPatronymic, |
| 2107 | + updateClientsDataArr |
| 2108 | + ) { |
| 2109 | + return updateClientsDataArr.some( |
| 2110 | + (client) => |
| 2111 | + client.surname === formInSurname && |
| 2112 | + client.name === formInName && |
| 2113 | + client.patronymic === formInPatronymic |
| 2114 | + ); |
| 2115 | + } |
2090 | 2116 |
|
2091 | 2117 | function handleModalFormSubmit(context = {}) { |
2092 | 2118 | const { modalBodyForm, type, clientData } = context; // получение необходимых элементов (через деструктуризациию входящего/передаваемого объекта) |
|
2137 | 2163 |
|
2138 | 2164 | modalBodyForm.classList.add('was-validated'); // если всё "ок", т.е. нет ошибок, невалидных сообщений.. добавление всей форме валидационного класса (для/по Bootstrap) |
2139 | 2165 |
|
2140 | | - setTimeout(() => { |
2141 | | - alert('Клиент успешно добавлен!'); // вывод сообщения об успешном добавлении клиента |
2142 | | - |
2143 | | - // очистка всех полей формы (удаление классов/сообщений ошибок) |
2144 | | - allModalInputs.forEach((input) => { |
2145 | | - input.value = ''; |
2146 | | - input.classList.remove('is-invalid'); |
2147 | | - }); |
2148 | | - modalBodyForm.classList.remove('was-validated'); // удаление класса "was-validated" |
2149 | | - |
2150 | | - // закрытие модального окна (через/посредствам Bootstrap API) |
2151 | | - const bootstrapModal = bootstrap.Modal.getInstance( |
2152 | | - modalBodyForm.closest('.modal') |
| 2166 | + // фиксация/обработка вводимых данных, ФИО/контакты (формирование объекта "client") |
| 2167 | + const formInSurname = toUpFirstLetter( |
| 2168 | + modalBodyForm.querySelector('.modal-surname-input').value.trim() |
| 2169 | + ); |
| 2170 | + const formInName = toUpFirstLetter( |
| 2171 | + modalBodyForm.querySelector('.modal-name-input').value.trim() |
| 2172 | + ); |
| 2173 | + const formInPatronymicInput = modalBodyForm.querySelector( |
| 2174 | + '.modal-patronymic-input' |
| 2175 | + ); |
| 2176 | + const formInPatronymic = formInPatronymicInput |
| 2177 | + ? toUpFirstLetter(formInPatronymicInput.value.trim()) |
| 2178 | + : ''; |
| 2179 | + |
| 2180 | + // фиксация контактов |
| 2181 | + const formInContacts = Array.from( |
| 2182 | + modalBodyForm.querySelectorAll('.contact-row') |
| 2183 | + ).map((row) => ({ |
| 2184 | + type: row.querySelector('.contact-type').value.trim(), |
| 2185 | + value: row.querySelector('.contact-value').value.trim(), |
| 2186 | + })); |
| 2187 | + |
| 2188 | + // проверка на совпадение по ФИО |
| 2189 | + if ( |
| 2190 | + checkClientFIO( |
| 2191 | + formInSurname, |
| 2192 | + formInName, |
| 2193 | + formInPatronymic, |
| 2194 | + updateClientsDataArr |
| 2195 | + ) |
| 2196 | + ) { |
| 2197 | + const formInNotification = confirm( |
| 2198 | + 'Совпадение по Ф.И.О! Такой клиент уже существует! Всё равно добавить?' |
2153 | 2199 | ); |
2154 | | - if (bootstrapModal) { |
2155 | | - bootstrapModal.hide(); |
| 2200 | + if (!formInNotification) { |
| 2201 | + return; // не добавляем клиента |
2156 | 2202 | } |
| 2203 | + } |
| 2204 | + |
| 2205 | + // итоговый объект клиента (передаваемый на сервер) |
| 2206 | + const client = { |
| 2207 | + surname: formInSurname, |
| 2208 | + name: formInName, |
| 2209 | + patronymic: formInPatronymic, |
| 2210 | + contacts: formInContacts, |
| 2211 | + }; |
| 2212 | + |
| 2213 | + try { |
| 2214 | + await addClientToServer(client); // отправка клиента на сервер |
2157 | 2215 |
|
2158 | | - // и напоследок.. выделение/показ только что добавленного клиента/строки |
2159 | 2216 | setTimeout(() => { |
2160 | | - // movingToLastNewTableRow(); |
2161 | | - }, 300); // временная задержка, больше.. чтобы модальное окно успело закрыться |
2162 | | - }, 200); |
| 2217 | + alert('Клиент успешно добавлен!'); // вывод сообщения об успешном добавлении клиента |
| 2218 | + |
| 2219 | + // очистка всех полей формы (удаление классов/сообщений ошибок) |
| 2220 | + allModalInputs.forEach((input) => { |
| 2221 | + input.value = ''; |
| 2222 | + input.classList.remove('is-invalid'); |
| 2223 | + }); |
| 2224 | + modalBodyForm.classList.remove('was-validated'); // удаление класса "was-validated" |
| 2225 | + |
| 2226 | + // закрытие модального окна (через/посредствам Bootstrap API) |
| 2227 | + const bootstrapModal = bootstrap.Modal.getInstance( |
| 2228 | + modalBodyForm.closest('.modal') |
| 2229 | + ); |
| 2230 | + if (bootstrapModal) { |
| 2231 | + bootstrapModal.hide(); |
| 2232 | + } |
| 2233 | + |
| 2234 | + // и напоследок.. выделение/показ только что добавленного клиента/строки |
| 2235 | + setTimeout(() => { |
| 2236 | + // TODO: |
| 2237 | + // movingToLastNewTableRow(); |
| 2238 | + }, 300); // временная задержка, больше.. чтобы модальное окно успело закрыться |
| 2239 | + }, 200); |
| 2240 | + } catch (error) { |
| 2241 | + console.error('Ошибка при добавлении клиента:', error); |
| 2242 | + alert( |
| 2243 | + 'Не удалось добавить клиента! Проверьте данные и попробуйте снова!?' |
| 2244 | + ); |
| 2245 | + } |
2163 | 2246 | }, |
2164 | 2247 | false |
2165 | 2248 | ); |
|
0 commit comments