|
1 | 1 | (() => { |
2 | 2 | // ** получение существующих, создание "новых" элементов (глобальное объявление) |
3 | | - const page = document.getElementById('page'); |
4 | 3 | const crm = document.getElementById('crm'); |
5 | 4 | const crmSearch = document.getElementById('crm-search'); |
6 | 5 | const crmOutput = document.getElementById('crm-output'); |
|
13 | 12 | const searchLogoWrap = document.createElement('div'); |
14 | 13 | const searchLogo = document.createElement('a'); |
15 | 14 | const searchLogoImg = document.createElement('img'); |
16 | | - const searchFormInputWrap = document.createElement('div'); |
| 15 | + const searchFormWrap = document.createElement('div'); |
17 | 16 | const searchForm = document.createElement('form'); |
18 | 17 | const searchInputWrap = document.createElement('div'); |
19 | 18 | const searchInput = document.createElement('input'); |
|
22 | 21 | searchLogoWrap.classList.add('crm__search-logo-wrap'); |
23 | 22 | searchLogo.classList.add('crm__search-logo'); |
24 | 23 | searchLogoImg.classList.add('crm__search-logo-img'); |
25 | | - searchFormInputWrap.classList.add('crm__search-form-input-wrap'); |
| 24 | + searchFormWrap.classList.add('crm__search-form-wrap'); |
26 | 25 | searchForm.classList.add('crm__search-form', 'needs-validation'); |
27 | 26 | searchInputWrap.classList.add('crm__search-input-wrap'); |
28 | 27 | searchInput.classList.add('crm__search-input', 'form-control'); |
|
52 | 51 | searchLogoWrap.append(searchLogo); |
53 | 52 | searchInputWrap.append(searchInput, searchInputFeedback); |
54 | 53 | searchForm.append(searchInputWrap); |
55 | | - searchFormInputWrap.append(searchForm); |
56 | | - crmSearchContainer.append(searchLogoWrap, searchFormInputWrap); |
| 54 | + searchFormWrap.append(searchForm); |
| 55 | + crmSearchContainer.append(searchLogoWrap, searchFormWrap); |
57 | 56 |
|
58 | 57 | // организация таблицы данных о клиентах (структура, заголовки колонок, иконки) |
59 | 58 | const outputTitleWrap = document.createElement('div'); |
|
239 | 238 | const addModalBodyForm = document.createElement('form'); |
240 | 239 | const addModalBodySurnameInputWrap = document.createElement('div'); |
241 | 240 | const addModalBodySurnameInput = document.createElement('input'); |
| 241 | + const addModalBodySurnameFeedback = document.createElement('div'); |
242 | 242 | const addModalBodyNameInputWrap = document.createElement('div'); |
243 | 243 | const addModalBodyNameInput = document.createElement('input'); |
| 244 | + const addModalBodyNameFeedback = document.createElement('div'); |
244 | 245 | const addModalBodyPatronymicInputWrap = document.createElement('div'); |
245 | 246 | const addModalBodyPatronymicInput = document.createElement('input'); |
| 247 | + const addModalBodyPatronymicFeedback = document.createElement('div'); |
246 | 248 | const addModalFooter = document.createElement('div'); |
247 | 249 | const addModalFooterAddBtnWrap = document.createElement('div'); |
248 | 250 | const addModalFooterAddBtn = document.createElement('button'); |
|
256 | 258 | addBtnGrayIcon.classList.add('crm__add-btn-icon', 'gray-add-icon'); |
257 | 259 | addBtnText.classList.add('crm__add-btn-text'); |
258 | 260 | addModalWrap.classList.add('modal', 'crm__add-btn-modal', 'fade'); |
259 | | - addModalDialog.classList.add( |
260 | | - 'modal__add-dialog', |
261 | | - 'modal-dialog', |
262 | | - 'modal-dialog-centered' |
263 | | - ); |
| 261 | + addModalDialog.classList.add('modal__add-dialog', 'modal-dialog'); |
264 | 262 | addModalContent.classList.add('modal__add-content-wrap', 'modal-content'); |
265 | 263 | addModalHeader.classList.add('modal__add-header', 'modal-header'); |
266 | 264 | addModalHeaderTitle.classList.add('modal__add-header-title', 'modal-title'); |
267 | 265 | addModalHeaderXBtn.classList.add('modal__add-header-x-btn', 'btn-close'); |
268 | 266 | addModalBody.classList.add('modal__add-body', 'modal-body'); |
269 | | - addModalBodyForm.classList.add('modal__add-body-form'); |
| 267 | + addModalBodyForm.classList.add('modal__add-body-form', 'needs-validation'); |
270 | 268 | addModalBodySurnameInputWrap.classList.add( |
271 | 269 | 'modal__add-body-input-wrap', |
272 | 270 | 'add-surname-input-wrap' |
|
276 | 274 | 'add-surname-input', |
277 | 275 | 'form-control' |
278 | 276 | ); |
| 277 | + addModalBodySurnameFeedback.classList.add( |
| 278 | + 'modal__add-body-input-feedback', |
| 279 | + 'surname-input-feedback', |
| 280 | + 'invalid-feedback' |
| 281 | + ); |
279 | 282 | addModalBodyNameInputWrap.classList.add( |
280 | 283 | 'modal__add-body-input-wrap', |
281 | 284 | 'add-name-input-wrap' |
|
285 | 288 | 'add-name-input', |
286 | 289 | 'form-control' |
287 | 290 | ); |
| 291 | + addModalBodyNameFeedback.classList.add( |
| 292 | + 'modal__add-body-input-feedback', |
| 293 | + 'name-input-feedback', |
| 294 | + 'invalid-feedback' |
| 295 | + ); |
288 | 296 | addModalBodyPatronymicInputWrap.classList.add( |
289 | 297 | 'modal__add-body-input-wrap', |
290 | 298 | 'add-patronymic-input-wrap' |
|
294 | 302 | 'add-patronymic-input', |
295 | 303 | 'form-control' |
296 | 304 | ); |
| 305 | + addModalBodyPatronymicFeedback.classList.add( |
| 306 | + 'modal__add-body-input-feedback', |
| 307 | + 'patronymic-input-feedback', |
| 308 | + 'invalid-feedback' |
| 309 | + ); |
297 | 310 | addModalFooter.classList.add('modal__add-footer', 'modal-footer'); |
298 | 311 | addModalFooterAddBtnWrap.classList.add('modal__add-footer-add-btn-wrap'); |
299 | 312 | addModalFooterAddBtn.classList.add('modal__add-footer-add-btn'); |
|
338 | 351 |
|
339 | 352 | addBtnText.textContent = 'Добавить клиента'; |
340 | 353 | addModalHeaderTitle.textContent = 'Новый клиент'; |
| 354 | + addModalBodySurnameFeedback.textContent = |
| 355 | + 'Введены не корректные данные.. исключите: английские буквы, цифры!'; |
| 356 | + addModalBodyNameFeedback.textContent = |
| 357 | + 'Введены не корректные данные.. исключите: английские буквы, цифры!'; |
| 358 | + addModalBodyPatronymicFeedback.textContent = |
| 359 | + 'Введены не корректные данные.. исключите: английские буквы, цифры!'; |
341 | 360 | addModalFooterAddBtn.textContent = 'Добавить контакт'; |
342 | 361 | addModalFooterSaveBtn.textContent = 'Сохранить'; |
343 | 362 | addModalFooterCancelBtn.textContent = 'Отмена'; |
344 | 363 |
|
345 | 364 | addBtn.append(addBtnDefaultIcon, addBtnWhiteIcon, addBtnGrayIcon, addBtnText); |
346 | 365 | addBtnWrap.append(addBtn); |
347 | 366 | addModalHeader.append(addModalHeaderTitle, addModalHeaderXBtn); |
348 | | - addModalBodySurnameInputWrap.append(addModalBodySurnameInput); |
349 | | - addModalBodyNameInputWrap.append(addModalBodyNameInput); |
350 | | - addModalBodyPatronymicInputWrap.append(addModalBodyPatronymicInput); |
| 367 | + addModalBodySurnameInputWrap.append( |
| 368 | + addModalBodySurnameInput, |
| 369 | + addModalBodySurnameFeedback |
| 370 | + ); |
| 371 | + addModalBodyNameInputWrap.append( |
| 372 | + addModalBodyNameInput, |
| 373 | + addModalBodyNameFeedback |
| 374 | + ); |
| 375 | + addModalBodyPatronymicInputWrap.append( |
| 376 | + addModalBodyPatronymicInput, |
| 377 | + addModalBodyPatronymicFeedback |
| 378 | + ); |
351 | 379 | addModalBodyForm.append( |
352 | 380 | addModalBodySurnameInputWrap, |
353 | 381 | addModalBodyNameInputWrap, |
|
411 | 439 | }); |
412 | 440 | } |
413 | 441 |
|
414 | | - const searchFormInput = document.querySelector('.crm__search-form input'); // получение search-инпута |
415 | | - searchFormInputValidation(searchFormInput); |
| 442 | + const searchFormMainInput = document.querySelector('.crm__search-form input'); // получение search-инпута |
| 443 | + searchFormInputValidation(searchFormMainInput); |
416 | 444 |
|
417 | | - // изменение направления стрелки/svg-icon, согласно прожатия по заглавной ячейке (при сортировке данных) |
| 445 | + // ** изменение направления стрелки/svg-icon, согласно прожатия по заглавной ячейке (при сортировке данных) |
418 | 446 | const allHeaderRowCells = document.querySelectorAll( |
419 | 447 | '.crm__o-table-head-cell' |
420 | 448 | ); |
|
448 | 476 | } |
449 | 477 | }); |
450 | 478 | }); |
| 479 | + |
| 480 | + // ** организация валидации для ввода данных/в модальном окне (при добавлении нового/клиента) |
| 481 | + function addModalFormInputValidation(inputs) { |
| 482 | + inputs.forEach((input) => |
| 483 | + input.addEventListener('input', (event) => { |
| 484 | + const target = event.target; |
| 485 | + const targetParentNode = target.parentNode; |
| 486 | + const invalidFeed = targetParentNode.querySelector('.invalid-feedback'); |
| 487 | + |
| 488 | + // принудительное исключение пробелов (в начале поля для ввода) |
| 489 | + target.value = target.value.replace(/^\s+/, ''); |
| 490 | + |
| 491 | + // только русские буквы (без цифр/символов), "один" дефис (для двойных фамилий) и без необоснованных пробелов |
| 492 | + if ( |
| 493 | + /[^а-яА-ЯёЁ\s-]/.test(target.value) || |
| 494 | + (target.value.match(/-/g) || []).length > 1 || |
| 495 | + /\s{2,}/.test(target.value) |
| 496 | + ) { |
| 497 | + target.classList.add('is-invalid'); |
| 498 | + |
| 499 | + if (/[^а-яА-ЯёЁ\s-]/.test(target.value)) { |
| 500 | + invalidFeed.textContent = |
| 501 | + 'Некорректный ввод! Измените раскладку клавиатуры и/или исключите цифры/знаки!'; |
| 502 | + } else if ((target.value.match(/-/g) || []).length > 1) { |
| 503 | + invalidFeed.textContent = 'Некорректный ввод! Только ОДИН дефис!'; |
| 504 | + } else { |
| 505 | + invalidFeed.textContent = |
| 506 | + 'Некорректный ввод! Только ОДИН пробел между словами!'; |
| 507 | + } |
| 508 | + } else { |
| 509 | + target.classList.remove('is-invalid'); |
| 510 | + invalidFeed.textContent = ''; // очистка сообщения об ошибке |
| 511 | + } |
| 512 | + }) |
| 513 | + ); |
| 514 | + } |
| 515 | + |
| 516 | + const allAddModalFormInputs = document.querySelectorAll( |
| 517 | + '.modal__add-body-input' |
| 518 | + ); // получение всех модальных-инпутов |
| 519 | + addModalFormInputValidation(allAddModalFormInputs); |
451 | 520 | })(); |
0 commit comments