Мета роботи
Опанувати принципи семантичної та адаптивної верстки сучасних елементів вебформ за допомогою Tailwind CSS. Вивчити механізми клієнтської валідації введення даних за допомогою регулярних виразів (RegEx) та JavaScript. Навчитися проектувати логіку обробки помилок та інтерактивних UX/UI станів (включаючи кастомні модальні вікна) в синергії з ШІ-інструментами генерації коду й компонентів.
Перші вебформи були примітивними сірими полями з браузера Netscape Navigator, а будь-яка валідація відбувалася виключно на стороні сервера. Користувач заповнював гігантську анкету, натискав «Надіслати», сторінка повністю перезавантажувалася через повільний Dial-up модем, і якщо в електронній пошті бракувало символу @, сервер повертав порожню сторінку з помилкою. Весь контент доводилося заповнювати заново. Це був жахливий користувацький досвід.
На сьогодні вебформи — це критично важливий інтерактивний вузол будь-якого продукту. Це міст між відвідувачем і бізнесом, головний інструмент збору потенційних клієнтів (лідів) та конверсії. Сучасна форма має бути:
- Семантичною. Використовувати правильні теги <form>, <input>, <label>, <button>, <select>.
- Адаптивною. Зручною для натискання пальцем на екрані смартфона і для введення з клавіатури комп’ютера.
- Інтерактивною в реальному часі. Попереджати про помилки в момент введення, а не після надсилання.
Стек інструментів для роботи
- Редактор коду Visual Studio Code з плагінами Tailwind CSS IntelliSense та Inline Fold.
- ШІ-асистенти генерації коду ChatGPT, Claude або локальні плагіни Codeium/GitHub Copilot.
- Контроль версій та хостинг коду: Git, GitHub.
- Хмарна платформа деплою: Vercel (vercel.com).
Вебформи
Сучасна вебформа — це не просто набір візуальних рамок для введення тексту, а складний інтерактивний вузол, який безпосередньо впливає на конверсію веб-ресурсу та його індексацію пошуковими роботами. З погляду сучасних стандартів консорціуму W3C, правильна верстка форми базується на двох фундаментальних стовпах: семантичній чіткості та загальній доступності.
Зв'язок елементів <label> та <input>
Кожен інтерактивний елемент форми (<input>, <select>, <textarea>) обов’язково повинен мати свій текстовий супровід, реалізований за допомогою тегу <label>. Використання звичайних тегів <div>, <span> або атрибуту placeholder замість повноцінного label є грубою технологічною помилкою.
Зв'язок між підписом та полем введення реалізується двома способами:
- Явний зв'язок (через атрибут for). Атрибут for в тезі <label> повинен повністю збігатися з атрибутом id відповідного інпуту.
- Неявний зв'язок (вкладеність). Інпут розміщується безпосередньо всередині тегу <label>. В такому разі атрибути id та for не є обов'язковими, проте перший спосіб вважається більш гнучким для стилізації за допомогою Tailwind CSS.
<label for="user-email" class="block text-sm font-medium text-gray-700">Електронна пошта</label>
<input type="email" id="user-email" name="email" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm">
Цей зв’язок є критично важливим через наступні фактори
- Доступність (Accessibility/a11y). Спеціальне програмне забезпечення — скрінрідери, якими користуються люди з порушеннями зору, — повністю орієнтується на семантичні зв'язки. Коли фокус припадає на поле введення, диктор зачитує текст з прив'язаного </label>. Якщо зв'язку немає, користувач почує лише фразу "поле введення, порожньо", що робить заповнення форми неможливим.
- Користувацький досвід (User Experience, UX). При правильному зв'язку клік мишкою або тач пальцем по тексту </label> автоматично переносить фокус (курсор) у відповідне поле введення. Це значно збільшує площу клікабельної зони, що особливо важливо для дрібних елементів — чекбоксів (checkbox) та радіокнопок (radio).
Мобільна оптимізація та семантичні типи даних
В сучасній веброзробці понад 50-70% трафіку припадає на мобільні пристрої. Атрибут type в тезі <input> виконує роль інструкції для операційних систем (iOS, Android), яка вказує, який саме тип екранної клавіатури потрібно викликати для максимальної зручності користувача.
- type="email" При фокусі на такому полі операційна система активує оптимізовану розкладку клавіатури. На головну панель мобільного екрана відразу виносяться символи «@» (собачка) та «.» (крапка). Користувачеві не потрібно перемикатися в режим символів чи цифр, щоб ввести адресу своєї пошти, що зменшує кількість рутинних дій і прискорює заповнення форми. На додачу, браузер автоматично застосовує базову перевірку на наявність знака @ в рядку перед надсиланням.
- type="tel" Замість стандартної клавіатури з літерами цей атрибут змушує смартфон відкрити виключно цифрову панель (Numpad), таку як в додатку для здійснення телефонних дзвінків. Великі цифрові клавіші мінімізують ризик помилкового натискання на маленькому екрані. Оскільки структура телефонних номерів в різних країнах відрізняється, цей тип не має жорсткої вбудованої валідації в браузері, тому його завжди комбінують з клієнтськими JS-скриптами (наприклад, масками введення) та регулярними виразами.
- Інші важливі типи для оптимізації UX
- type="number" — викликає цифрову клавіатуру з можливістю крок-зміни (стрілочки вгору/вниз), ідеально для кількості товарів чи віку.
- type="url" — додає на мобільну клавіатуру швидкі клавіші формати доменів типу .com, .ua чи /.
В процесі проектування взаємодії користувача з веб-ресурсом етап введення даних є найбільш критичним. Користувачі можуть припускатися одруків, вводити дані в невірному форматі або навмисно намагатися надіслати шкідливий код. Процес перевірки цих даних на відповідність встановленим бізнес-правилам та технічним вимогам називається валідацією.
Для забезпечення максимальної стабільності та безпеки веб-додатків архітектура перевірки даних завжди будується на основі концепції «двох ліній оборони».
- Клієнтська валідація (Client-side Validation). Ця лінія реалізується безпосередньо в браузері користувача на стороні фронтенду. Вона базується на декларативних методах HTML5 (атрибути required, type, minlength, pattern) та імперативній логіці мови JavaScript.
- Головною метою є забезпечення бездоганного UX (User Experience). Клієнтська валідація надає користувачеві миттєвий відгук. Інтерфейс реагує на помилку в момент її виникнення (наприклад, підсвічує поле червоним кольором або блокує кнопку надсилання), не змушуючи чекати відповіді від сервера. Це економить час клієнта та зменшує навантаження на мережу.
- Серверна валідація (Server-side Validation). Ця лінія спрацьовує на бекенді (Node.js, PHP, Python тощо) після того, як форма була офіційно надіслана.
- Головною метою є забезпечення абсолютної безпеки. Клієнтську валідацію ніколи не можна вважати надійною захисною мірою, оскільки будь-який користувач з базовими технічними навичками може відкрити панель розробника (DevTools), видалити атрибути required з HTML-тегів або повністю заблокувати виконання JavaScript-файлів в браузері. Серверна валідація є обов'язковою, оскільки вона гарантує, що в базу даних потраплять лише очищені та валідні матеріали.
Регулярні вирази як інструмент гнучкого аналізу даних
Для перевірки простих параметрів (наприклад, чи не є поле порожнім) достатньо базових умов. Проте, для перевірки складних текстових структур — таких як адреси електронної пошти, номери телефонів з врахуванням міжнародних кодів, або складність паролів — використовуються Регулярні вирази (Regular Expressions/RegEx).
RegEx — це спеціалізована мова опису текстових шаблонів за допомогою метасимволів. Вона надає фронтенд-інженеру можливість виконати посимвольний аналіз рядка та визначити, чи відповідає він строгій масці.
Глибокий розбір шаблону валідації Email
Розглянемо класичний регулярний вираз для перевірки електронної пошти:
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
Кожен елемент цього виразу виконує строгу логічну функцію:
- / ... / (Слеші). Обмежувачі, які вказують інтерпретатору JavaScript, що всередині них записано саме регулярний вираз, а не звичайний текстовий рядок.
- ^ (Карет). Метасимвол, який фіксує початок рядка. Він гарантує, що перевірка шаблону почнеться з найпершого введеного символу, і перед адресою пошти не буде стороннього тексту чи пробілів.
- [a-zA-Z0-9._%+-] (Символьний клас). Визначає діапазон дозволених символів для локальної частини email (до знака @). В цьому випадку дозволено: малі літери (a-z), великі літери (A-Z), цифри (0-9), а також крапку, підкреслення, відсоток, плюс та дефіс.
- + (Квантифікатор). Означає «один або більше разів». Він вимагає, щоб перед знаком «собачки» стояв принаймні один дозволений символ з попереднього класу.
- @ (Літерал). Пряме співпадіння. Рядок обов'язково повинен містити рівно один символ знака ат («собачку») саме в цій позиції.
- [a-zA-Z0-9.-]+. Другий символьний клас з квантифікатором. Визначає правила для імені домену (наприклад, gmail, ukr, lnu). Дозволяє літери, цифри, дефіси та крапки.
- \. (Екранована крапка). Оскільки символьна крапка . в мові RegEx є метасимволом, що означає «будь-який одиночний символ», для пошуку звичайної граматичної крапки її необхідно екранувати за допомогою зворотного слешу \. Вона відокремлює назву домену від доменної зони (наприклад, крапка перед com чи ua).
- [a-zA-Z]{2,}. Визначає правила для TLD (Top-Level Domain — доменної зони). Тут дозволені виключно літери (від 2 до більше символів, наприклад: .ua, .com, .tech).
- $ (Знак долара). Метасимвол, який фіксує кінець рядка. Він блокує можливість дописування будь-яких зайвих символів після завершення правильної доменної зони.
Класичний приклад регулярного виразу (RegEx) для валідації адреси електронної пошти, який найчастіше використовується у фронтенд-розробці:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Цей скрипт перевіряє введений текст і повертає true, якщо пошта валідна, або false, якщо користувач припустився помилки:
JavaScript
function validateEmail(email) {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
return emailRegex.test(email);
}
// Тестування різних варіантів:
console.log(validateEmail("developer.2026@domain.com")); // true (Валідно)
console.log(validateEmail("user@ukr.net")); // true (Валідно)
console.log(validateEmail("wrong-email@com")); // false (Немає крапки та доменної зони)
console.log(validateEmail("plainaddress")); // false (Відсутній символ @)
Покроковий розбір шаблону
- ^ (Початок рядка). Гарантує, що перевірка починається з першого символу і перед поштою немає зайвих пробілів чи тексту.
- [a-zA-Z0-9._%+-]+ (Локальна частина). Дозволяє використовувати в імені пошти (до знака @) великі й малі латинські літери, цифри, а також спецсимволи: крапку, підкреслення, відсоток, плюс і дефіс. Знак + означає, що має бути принаймні один такий символ.
- @ (Символ ат). Обов'язкова наявність рівно однієї «собачки» на своєму місці.
- [a-zA-Z0-9.-]+ (Доменне ім'я). Дозволяє літери, цифри, дефіси та крапки для назви поштового сервера (наприклад, gmail, ukr).
- \. (Екранована крапка). Оскільки крапка в RegEx означає «будь-який символ», екрануємо її зворотним слешем \, щоб знайти звичайну крапку перед доменною зоною.
- [a-zA-Z]{2,} (Доменна зона). Вимагає, щоб наприкінці йшли лише літери (мінімум дві), наприклад: .ua, .com, .org, .tech.
- $ (Кінець рядка). Фіксує кінець перевірки, щоб після доменної зони ніхто не міг дописати сторонні символи.
В сучасній інженерії інтерфейсів парадигма написання коду зазнала докорінних змін. Епоха ручного написання складних регулярних виразів та монолітних JS-валідаторів офіційно завершилася.
Сьогодні розробники використовують робочі процеси, що керовані штучним інтелектом (AI-driven workflows). ШІ-асистенти не просто заміняють пошук в переповненні стека — вони виступають в ролі інтелектуальних помічників для програмування.
Ручний аналіз та написання RegEx відходять в минуле. Синтаксис регулярних виразів є абстрактним, низькорівневим і «нечитабельним» з першого погляду. Достатньо пропустити один зворотний слеш (\), переплутати круглі дужки з квадратними або забути про квантифікатор, як вся логіка валідації зламається. Це призводить до двох критичних проблем:
- Висока ймовірність помилок. Складні вирази часто пропускають обробку винятків (edge cases) — наприклад, адреси з рідкісними доменними зонами (.technology) або специфічні внутрішні коди операторів зв'язку.
- Складність підтримки. Код, написаний іншим розробником вручну, важко читати. Через пів року розібратися в чужому RegEx-виразі без детальних коментарів стає справжнім випробуванням для команди.
Сучасний підхід полягає в тому, що розробник делегує генерацію рутинного коду до ШІ, фокусуючи свою увагу на архітектурі, тестуванні та користувацькому досвіді.
Методологія взаємодії з ШІ. Рольове моделювання та заземлення контексту
Щоб ШІ-асистент (ChatGPT, Claude, Codeium) видав не просто робочий, а оптимізований, безпечний і чистий код, який відповідає стандартам індустрії, необхідно застосовувати дві фундаментальні техніки промпт-інжинірингу:
- Рольове моделювання (Role-based Prompting). Замість банального запиту «напиши код перевірки форми», потрібно явно задати ШІ професійну роль — наприклад, Senior Frontend Engineer або UI/UX Tech Lead. Це змушує модель активувати найкращі світові практики: чистий код, дотримання принципів SOLID/DRY, оптимізацію швидкодії та детальне коментування.
- Заземлення контексту (Context Grounding). ШІ має чітко розуміти межі бізнес-логіки та локальні обмеження проєкту. Потрібно передати моделі точні вхідні параметри, технологічний стек (наприклад, Tailwind CSS + Vanilla JS) та регіональні особливості.
Практичний приклад проектування логіки з обробкою винятків
При роботі з українським цифровим простором ключовим завданням є сувора валідація номера телефону. Замість абстрактного шаблону, ШІ отримує чітке технічне завдання:
- Локальний контекст. Номер має строго відповідати українському стандарту +380XXXXXXXXX.
- Обробка винятків (Edge cases). Скрипт повинен не просто перевіряти форму в кінці, а динамічно покращувати UX. Наприклад, миттєво блокувати введення будь-яких літер або спецсимволів безпосередньо в процесі набору (подія input), автоматично підставляти префікс +380, якщо користувач починає писати з «0», та обмежувати максимальну довжину поля, щоб запобігти копіюванню зайвих цифр.
В результаті такої синергії розробник отримує надійний, адаптований під реальний ринок скрипт за лічені секунди, залишаючи за собою роль головного архітектора та контролера якості.
Покроковий хід виконання роботи
Етап 1. Аналіз завдання та проєктування форми
- Перед написанням коду студент повинен визначити, яку інформацію збирає форма і навіщо вона потрібна.
- Форма зворотного зв'язку повинна містити щонайменше:
- ім'я;
- електронну пошту;
- номер телефону;
- текст повідомлення;
- чекбокс згоди з політикою конфіденційності;
- кнопку «Надіслати».
- Для кожного поля потрібно визначити:
- Приклад промпту
| Поле | Тип | Обов'язковість | Правило |
| Ім'я | text | так | мін. 2–3 символи |
| Емейл | так | коректний формат | |
| Телефон | tel | так | +380XXXXXXXXX |
| Повідомлення | textarea | так | мін. 10 символів |
| Згода | checkbox | так | обов'язково |
| Надіслати | submit | - | активує перевірку |
Ти — UX/UI Designer та Frontend Engineer. Я створюю адаптивну форму зворотного зв'язку для лендингу. Стек: HTML5 + Tailwind CSS + Vanilla JavaScript. Форма повинна містити: - ім'я; - емейл; - телефон; - повідомлення; - чекбокс згоди; - кнопку "Надіслати". Спроєктуй логіку взаємодії користувача з формою. Для кожного поля визнач: 1. тип; 2. обов'язковість; 3. правило валідації; 4. повідомлення про помилку; 5. успішний стан; 6. поведінку на мобільному екрані. Не пиши код. Спочатку сформуй технічне завдання для реалізації форми.
Етап 2. Підготовка структури проєкту
- В VS Code створити структуру:
- Ініціалізувати Git git init.
- Якщо форма створюється безпосередньо всередині лендингу, студент може використовувати вже існуючу структуру проєкту.
feedback-form/ │ ├── index.html │ ├── assets/ │ ├── css/ │ │ └── styles.css │ │ │ └── js/ │ └── validation.js │ └── README.md
Етап 3. Проєктування HTML-структури
- На цьому етапі створити лише структуру, без складної JavaScript-логіки.
- Основою повинні бути: <form>, <label>, <input>, <textarea>, <button>.
- Для кожного поля необхідно забезпечити зв'язок:
<label for="email">Email</label> <input type="email" id="email" name="email">
- Не використовувати placeholder як заміну label.
- Також, для форми необхідно передбачити області для повідомлень про помилки.
- Наприклад, <p id="emailError" class="hidden">Введіть коректну електронну адресу.</p>
- Приклад промпту
Ти — Senior HTML5 Frontend Developer. Створи семантичну HTML-структуру адаптивної форми зворотного зв'язку. Стек: HTML5 + Tailwind CSS. Поля: - Ім’я; - Емейл; - Телефон; - Повідомлення; - Згода з політикою конфіденційності; - Кнопка "Надіслати". Вимоги: - використовувати form, label, input, textarea, button; - кожне поле повинно мати унікальний id; - label повинен бути пов'язаний з input через for; - використовувати правильні type; - передбачити окремий елемент для повідомлення про помилку; - додати name до кожного поля; - не використовувати placeholder замість label; - не додавати JavaScript. Покажи тільки HTML-код і коротко поясни його структуру.
Етап 4. Адаптивна верстка за допомогою Tailwind CSS
- перетворити HTML-каркас на повноцінний UI.
- На мобільному пристрої поля повинні розташовуватися переважно в одну колонку.
- На ширшому екрані можуть вишуковуватися в 2 колонки, наприклад:
Ім'я Емейл Телефон Тема Повідомлення [ ] [ ] Погоджуюсь... [Надіслати] - Для цього можна використати: grid grid-cols-1 md:grid-cols-2 або Flexbox.
- Необхідно використати Tailwind-класи для ширини форми, відступів між полями, типографіки, кольорів, меж полів, стани focus та hover, transition, адаптивність.
- Приклад промпту
Ти — Senior Tailwind CSS Developer. Маю готову HTML-структуру форми: [вставити HTML] Застосуй Tailwind CSS. Вимоги: 1. Mobile-first. 2. На мобільному екрані всі поля розташовані в одну колонку. 3. Від md два поля в ряд. 4. Форма має max-width та центроване розташування. 5. Поля мають зручну висоту для touch-введення. 6. Додай hover та focus-visible. 7. Створи чіткі стани normal/focus/error/success. 8. Кнопка повинна бути зручною для натискання на смартфоні. 9. Не використовуй додаткові CSS-бібліотеки. 10. Не змінюй HTML-структуру без необхідності. Поверни оновлений HTML з Tailwind-класами.
Етап 5. Проєктування UI-станів форми
- Для кожного поля передбачити стани:
- Форма це не лише HTML-елементи, а система станів інтерфейсу.
- Приклад промпту
1. Normal [ Email ] 2. Focus [ user@example.com ] 3. Error [ wrong-email ] ← червона рамка Введіть коректний email 4. Success [ user@gmail.com ] ✓
Ти — UI/UX Designer та Frontend Engineer. Для форми зворотного зв'язку потрібно спроєктувати 4 стани кожного поля: Normal Focus Error Success Опиши: - колір меж полів; - фон; - focus ring; - текст повідомлення; - іконка, якщо вона потрібна; - поведінку на клавіатурі та мобільному пристрої. Стиль повинен бути стриманим та професійним. Не використовуй надмірні анімації.
Етап 6. Визначення правил валідації
- Перед написанням JavaScript студент повинен створити таблицю правил. Наприклад:
| Поле | Правило |
| Ім’я | не порожнє, ≥2 символів |
| Емейл | коректний формат |
| Телефон | +380XXXXXXXXX |
| Повідомлення | ≥10 символів |
| Checkbox | обов'язково checked |
Етап 7. Валідація RegEx.
- RegEx не є універсальним валідатором всіх можливих телефонних номерів або емейлів. Він реалізує конкретне правило, яке задано. Наприклад, const REGEX_PHONE = /^\+380\d{9}$/;
- Генерація RegEx за допомогою ШІ. Не просто просити ШІ «Напиши RegEx для телефону», потрібно задати контекст.
- Приклад промпту
Ти — Senior JavaScript Developer. Мені потрібна регулярна перевірка номера телефону для навчальної вебформи. Умови: - номер повинен починатися з +380; - після +380 повинно бути рівно 9 цифр; - пробіли не допускаються; - дужки не допускаються; - дефіси не допускаються; - літери не допускаються. Приклади валідних: +380501234567 +380671112233 Приклади невалідних: 0501234567 +38050123456 +3805012345678 +380 50 123 45 67 +380abc123456 Створи RegEx та поясни значення кожного його елемента.
Етап 8. Валідація JavaScript
- Створити файл assets/js/validation.js
- Логіку доцільно розділити на невеликі функції:
validateName()
validateEmail()
validatePhone()
validateMessage()
validateAgreement() - І окремі функції для UI:
showError()
showSuccess()
clearError()
Це краще, ніж один великий блок if/else. - Приклад промпту
Ти — Senior Frontend JavaScript Engineer. В мене є HTML-форма з такими id: - username - email - phone - message - agreement - feedbackForm Створи файл validation.js на Vanilla JavaScript. Вимоги: 1. Перехопити submit через addEventListener. 2. Використати event.preventDefault(). 3. Перевіряти кожне поле окремою функцією. 4. Ім'я — мінімум 2 символи. 5. Емейл — перевірити формат. 6. Телефон — строго +380XXXXXXXXX. 7. Повідомлення — мінімум 10 символів. 8. Чекбокс згода — обов'язково checked. 9. Для помилки показувати текст під відповідним полем. 10. Для помилки додавати border-red-500. 11. Для успішного стану використовувати border-green-500. 12. Якщо хоча б одне поле невалідне, форму не надсилати. 13. Не використовувати сторонні бібліотеки. 14. Код розділити на невеликі функції. 15. Додати зрозумілі коментарі. Не створюй HTML. Поверни тільки файл validation.js.
Етап 9. Динамічна валідація
- Після базової валідації реалізувати перевірку під час взаємодії.
- Доцільно використовувати: input, blur, submit
- Не варто показувати червону помилку до того, як користувач почав взаємодіяти з полем. Наприклад:
Користувач відкрив форму → помилки немає. Почав вводити → відбувається перевірка. Залишив поле → показується результат.
- Приклад промпту
Проаналізуй мою JavaScript-валідацію форми. [вставити validation.js] Зміни UX так, щоб: - помилки не показувалися відразу після відкривання сторінки; - перевірка починалася після взаємодії з полем; - blur виконував фінальну перевірку поля; - input дозволяв оновлювати стан після початку введення; - submit перевіряв всі поля; - повідомлення про помилку були зрозумілими користувачу. Не змінюй правила валідації. Не змінюй HTML.
Етап 10. Обробка номеру телефону та Граничні випадки (Edge Cases)
- Для перевірки правильності введення номеру телефону, провести тестування:
- Можна реалізувати додаткову UX-функцію:
- Якщо користувач вводить номер в форматі 0501234567, система може запропонувати або автоматично перетворити його на правильний формат +380501234567
- Це є окремою UX-функцією, а не саме правило RegEx.
- Приклад промпту
+380501234567 ✓ 0501234567 ✗ +38050123456 ✗ +3805012345678 ✗ +380abc123456 ✗ +380 50 123 45 67 ✗
Проаналізуй логіку поля phone. Потрібно врахувати такі Edge Cases: 1. Користувач починає вводити 0. 2. Користувач вводить +380. 3. Користувач вставляє номер з пробілами. 4. Користувач вставляє номер з дужками. 5. Користувач вставляє більше 9 цифр після +380. 6. Користувач вводить літери. 7. Користувач видаляє частину номера. Запропонуй безпечну UX-логіку. Важливо: - не блокуй користувача агресивно; - не приховуй помилку; - не змінюй введення без зрозумілої причини; - поясни кожну запропоновану зміну.
Детальний розбір реалізації логіки з прикладами коду.
Потрібно чітко визначити правила валідації відповідно до критеріїв оцінювання:
- Ім'я: не пусте, мінімум 2 символи.
- Email: стандартна структура електронної пошти.
- Телефон: обов'язковий український формат, що починається з +380 і містить рівно 9 цифр після коду країни (разом 12 цифр після знака +).
JavaScript
// Константи з регулярними виразами
const REGEX_EMAIL = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// Перевірка формату +380 та наступних 9 цифр (наприклад, +380501234567)
const REGEX_PHONE = /^\+380\d{9}$/;
Замість написання громіздкого коду, логіка розділяється на мікро-функції. Кожне поле перевіряється окремо. Якщо є помилка — додається червона рамка (border-red-500), показується текст помилки. Якщо все добре — рамка стає зеленою (border-green-500).
JavaScript
// Допоміжна функція для відображення помилки
function showErr(inputElement, errorElement, message) {
inputElement.classList.remove('border-green-500', 'border-gray-300');
inputElement.classList.add('border-red-500'); // Червона рамка
errorElement.textContent = message;
errorElement.classList.remove('hidden'); // Показуємо текст під полем
}
// Допоміжна функція для успішного стану поля
function showSuccess(inputElement, errorElement) {
inputElement.classList.remove('border-red-500', 'border-gray-300');
inputElement.classList.add('border-green-500'); // Зелена рамка
errorElement.classList.add('hidden'); // Ховаємо помилку
errorElement.textContent = '';
}
// Функція валідації імені
function validateName() {
const nameInput = document.getElementById('username');
const nameError = document.getElementById('nameError');
if (nameInput.value.trim().length < 2) {
showErr(nameInput, nameError, "Ім'я повинно містити не менше 2 символів.");
return false;
}
showSuccess(nameInput, nameError);
return true;
}
// Функція валідації Email
function validateEmail() {
const emailInput = document.getElementById('email');
const emailError = document.getElementById('emailError');
if (!REGEX_EMAIL.test(emailInput.value.trim())) {
showErr(emailInput, emailError, "Введіть коректну електронну адресу (наприклад: user@mail.com).");
return false;
}
showSuccess(emailInput, emailError);
return true;
}
// Функція валідації телефону
function validatePhone() {
const phoneInput = document.getElementById('phone');
const phoneError = document.getElementById('phoneError');
// Очищаємо пробіли для точної перевірки
const phoneValue = phoneInput.value.trim();
if (!REGEX_PHONE.test(phoneValue)) {
showErr(phoneInput, phoneError, "Формат має бути строго українським: +380XXXXXXXXX.");
return false;
}
showSuccess(phoneInput, phoneError);
return true;
}
Користувачі дратуються, якщо бачать помилки ще до того, як закінчили писати. Тому найкраща практика — запускати перевірку під час події input (коли користувач надсилає текст) або blur (коли фокус залишає поле).
JavaScript
document.addEventListener('DOMContentLoaded', () => {
const nameInput = document.getElementById('username');
const emailInput = document.getElementById('email');
const phoneInput = document.getElementById('phone');
// Навішуємо слухачі подій для динамічного очищення помилок
nameInput.addEventListener('input', validateName);
emailInput.addEventListener('input', validateEmail);
phoneInput.addEventListener('input', validatePhone);
});
Коли користувач натискає кнопку «Надіслати», подію перехоплюється через e.preventDefault(), проводиться фінальна тотальна перевірка всіх полів, і якщо хоча б одне поле є невірним — блокується надсилання. Якщо все правильно — імітується успішне надсилання і відкривається модальне вікно.
JavaScript
const form = document.getElementById('feedbackForm');
const successModal = document.getElementById('successModal');
const closeModalBtn = document.getElementById('closeModalBtn');
form.addEventListener('submit', (e) => {
e.preventDefault(); // Запобігаємо перезавантаженню сторінки
// Запускаємо перевірку всіх полів одночасно
const isNameValid = validateName();
const isEmailValid = validateEmail();
const isPhoneValid = validatePhone();
// Якщо хоча б одне поле заповнене невірно — перериваємо виконання
if (!isNameValid || !isEmailValid || !isPhoneValid) {
return;
}
// Імітація успішного відправлення даних на сервер
// Показуємо модальне вікно успіху
successModal.classList.remove('hidden');
successModal.classList.add('flex'); // Стан відображення у Tailwind
// Очищуємо форму
form.reset();
// Скидаємо стилі зелених рамок до початкових
document.querySelectorAll('input').forEach(input => {
input.classList.remove('border-green-500');
input.classList.add('border-gray-300');
});
});
// Закриття модального вікна
closeModalBtn.addEventListener('click', () => {
successModal.classList.remove('flex');
successModal.classList.add('hidden');
});
Етап 11. Створення модального вікна успішного надсилання
- Після успішної валідації форма повинна показати повідомлення:
- В даній лабораторній роботі не відбувається реального надсилання даних на сервер, оскільки бекенд або сервіс обробки форми не підключено. Тому, правильніше назвати цей стан «Імітація успішного надсилання». Це важливо, щоб не створювати враження, що JavaScript надсилає дані на сервер.
- Приклад промпту
Дякуємо! Ваше повідомлення успішно надіслано.
Ти — Senior Frontend Developer. Створи доступне модальне вікно успішного завершення форми. Вимоги: - Tailwind CSS; - Фіксоване розташування по центру екрану; - затемнення фону; - повідомлення про успішне завершення; - кнопка "Закрити"; - можливість закривання вікна клавішею Escape; - focus-visible; - коректна клавіатурна навігація; - не використовувати сторонні бібліотеки. Модальне вікно повинно з'являтися тільки після успішної клієнтської валідації. Поясни, як реалізована його доступність.
Етап 12. Доступність форми
- Перевірити label, for, id, name, focus, aria-describedby, aria-invalid, клавіатурна навігація, контраст, повідомлення про помилки, доступність модального вікна.
- Наприклад: <input id="email" aria-describedby="emailError" aria-invalid="true">
- При відсутності помилки: aria-invalid="false"
- Приклад промпту
Ти — Accessibility Engineer. Проаналізуй мою HTML-форму: [вставити HTML] Перевір її на доступність. Особливу увагу приділи: - label/for; - input/id; - aria-describedby; - aria-invalid; - keyboard navigation; - focus-visible; - error messages; - checkbox; - modal dialog. Запропонуй тільки необхідні зміни. Для кожної зміни поясни: Проблема → Причина → Рішення.
Етап 13. Тестування форми
- Провести систематичне тестування Ідеального сценарію та Негативних випадків.
- Протестувати Граничні випадки (Edge Cases).
- Перевірити пробіли, дуже довгий текст, копіювання/вставлення, емоджі, кирилицю, латиницю, цифри, HTML-код, швидке повторне натискання Submit.
Happy Path Ім'я ✓ Email ✓ Телефон ✓ Повідомлення ✓ Згода ✓ Успіх
Negative Cases Тест Очікуваний результат Порожнє ім'я помилка 1 символ помилка неправильний емейл помилка неправильний телефон помилка коротке повідомлення помилка чекбокс не вибрано помилка всі поля правильні Успіх
Етап 14. Перевірка коду за допомогою ШІ
- Після написання коду студент повинен попросити ШІ не переписати код, а провести аудит.
- Приклад промпту
Ти — Senior Frontend Code Reviewer. Проаналізуй код форми: HTML: [код] JavaScript: [код] Tailwind: [код] Перевір: 1. правильність валідації; 2. RegEx; 3. Edge Cases; 4. DOM-операції; 5. слухачі подій; 6. доступність полів; 7. клавіатурну навігацію; 8. мобільний UX; 9. можливі JavaScript помилки; 10. безпеку даних. Не переписуй весь код. Сформуй таблицю: Проблема | Рівень | Причина | Рекомендоване виправлення.
Етап 15. Тестування в Інструментах розробника Chrome DevTools
- Відкрити: F12 → Console. Перевірити на відсутність JavaScript-помилок.
- Скористатися опцією F12 → Toggle device toolbar. Перевірити вигляд форми на мобільному, планшеті та десктопі.
- немає горизонтального скролу;
- всі поля є доступними;
- кнопка не виходить за межі форми;
- текст помилок не обрізається;
- модальне вікно коректно масштабується.
Етап 16. Тестування клавіатурної поведінки
- Не використовуючи мишу натискати клавіші Tab, Enter, Shift + Tab, Esc. Перевірити:
- всі поля є доступними;
- кнопка є доступною;
- чекбокс є доступним;
- помилки є зрозумілими;
- модальне вікно є доступним;
- focus не губиться.
Етап 17. Фіксація змін в Git та синхронізація з GitHub
- Відкрити вбудований термінал VS Code та перевірити статус репозиторію:
- git status
- Додати створені та оновлені файли до індексу:
- git add .
- Створити комміт з фіксацією нового функціоналу за правилами інженерної культури розробки:
- git commit -m "feat: додано форму зворотного зв'язку з ШІ-валідацією та модальним вікном"
- Надіслати оновлений код у віддалений репозиторій на GitHub:
- git push origin main
Етап 18. Автоматичний деплой (публікація) сайту у Vercel через GitHub
- Перейти на сайт Vercel. Зареєструватися або авторизуватися через свій профіль GitHub (натиснути Continue with GitHub). Це автоматично пов'яже ваші хмарні кабінети.
- На головній панелі Vercel (Dashboard) натиснути кнопку Add New... -> Project.
- В списку Import Git Repository буде перелік ваших репозиторіїв з GitHub. Знайти репозиторій вашого лендингу (який оновилено на Етапі 3) та натиснути кнопку Import.
- У вікні налаштувань проєкту (Configure Project):
- Поле Project Name можна залишити без змін або дати зрозумілу назву.
- Framework Preset залишити Other (оскільки це є статичний HTML/CSS/JS сайт).
- Root Directory залишити за замовченням (./).
- Натиснути кнопку Deploy.
- Зачекати 20–40 секунд, поки хмарні сервери Vercel збирають даний проєкт. Після завершення з’явиться святкова анімація конфетті та мініатюра даного сайту.
- Натиснути на прев'ю сайту або кнопку Continue to Dashboard, щоб отримати постійне живе посилання в інтернеті (воно матиме вигляд https://назва-проєкту.vercel.app).
- Перевірка CI/CD пайплайну. Зробити будь-яку дрібну текстову зміну в коді сайту через VS Code, виконати git add ., git commit -m "fix: дрібні виправлення контенту" та git push origin main.
- Перейти на вкладку Deployments у Vercel і переконатися, що платформа автоматично помітила пуш і сама оновила сайт в інтернеті без жодних додаткових дій.
Етап 19. Фінальне тестування продакшн-версії
- Обов'язково перевірити саме опубліковану версію, а не тільки localhost.
- Перевірити форму, валідацію, модальне вікно, вигляд на мобільному телефоні, клавіатурну поведінку, повідомлення в Console, завантаження ресурсів.
- Якщо реального бекенду/API немає, варто змінити фразу «Форму успішно надіслано» на «Форма успішно пройшла клієнтську валідацію. Демонстрація успішного надсилання». Зараз JavaScript фактично робить preventDefault(), перевіряє дані, показує модальне вікно і очищає форму. Реального надсилання даних на сервер в наведеній реалізації немає.
Зміст звіту та технічні фінальні артефакти
В результаті виконання роботи студент формує та завантажує на диск (у власну папку) звіт в форматі PDF.
- Титульний лист з назвою лабораторної роботи, даними студента та обраною бізнес-тематикою.
- У звіті повинні бути:
- Проєктування. Скріншот або схема структури форми.
- HTML. Фрагмент семантичної структури.
- Tailwind CSS. Приклади адаптивної верстки.
- Правила валідації
- JavaScript. Функції валідації.
- RegEx. Пояснення хоча б двох використаних регулярних виразів.
- UI-стани. Показати normal, focus, error, success.
- Доступність. Показати label, for, aria-*, клавіатурну поведінку.
- Тестування. Показати таблицю: Тестовий випадок → Вхідні дані → Очікуваний результат → Фактичний результат → Результат
Поле Правило Приклад Ім'я ≥2 символів Ірина Емейл valid format user@gmail.com Телефон +380 + 9 цифр +380501234567 Повідомлення ≥10 символів ... Згода checked ✓ - Посилання на публічний репозиторій проєкту на GitHub.
- Посилання на живий та адаптивний лендинг, розгорнутий у Vercel.
- Промпт-паспорт (Prompt Log). Для кожного ключового етапу: Завдання → Промпт → Відповідь ШІ → Що змінено → Результат.
Критерії оцінювання лабораторної роботи
- Якість верстки та адаптивність форми. Коректне використання семантичних тегів форми, ідеальне відображення інтерфейсу як на десктопних моніторах, так і на екранах смартфонів.
- Складність та надійність ШІ-валідації. Коректна робота регулярних виразів. Обов'язкова перевірка українського формату номера телефона (+380...) та структури email. Форма не повинна надсилатися, якщо хоча б одне поле заповнене невірно.
- Естетика UI/UX при обробці помилок. Візуалізація помилок (червоні рамки, підписи під полями). Наявність модального вікна, що повідомляє про успіх, та автоматичне очищення полів після валідації.
- Робота з контролем версій Git. Наявність чітко структурованого коміту фіксації форми зворотного зв'язку в історії репозиторію на GitHub.
- Розгортання на Vercel та налаштування CI/CD. Працююче посилання на домені .vercel.app. Успішна демонстрація автоматичного оновлення сайту при пуші коду в репозиторій.
Контрольні запитання
- Навіщо використовувати тег <label> з атрибутом for, якщо можна просто написати назву поля в звичайному <div> або скористатися плейсхолдером?
- Чому для поля введення номера телефону варто вказувати саме type="tel", а не type="text" або type="number"?
- Яка головна різниця між клієнтською (Client-side) та серверною (Server-side) валідацією? Чи можна обійтися тільки клієнтською?
- Що в регулярному виразі означають метасимволи ^ (карет) та $ (долар)? Що станеться, якщо їх забрати з виразу для валідації телефону?
- Як в регулярному виразі знайти звичайну граматичну крапку . і чому перед нею ставлять зворотний слеш \?
- Яку роль в регулярному виразі має квантифікатор +?
- Чому для обробки надсилання форми в JavaScript використовують метод event.preventDefault()?
- Як за допомогою Tailwind CSS реалізувати ефект, коли модальне вікно перекриває весь контент сайту і користувач не може клікнути на елементи під ним?
- В JS-скрипті модальне вікно закривається при кліку на затемнений оверлей (фон). Як ви запобігли тому, щоб вікно закривалося при кліку всередині самої білої картки з текстом?
- Навіщо при успішній валідації викликати метод form.reset() перед показом модального вікна?
- Які потенційні проблеми та винятки (edge cases) можуть виникнути, якщо згенерувати регулярний вираз для валідації імені за допомогою ШІ без чітких інструкцій?
- В чому небезпека сліпого копіювання коду валідації форми, згенерованого ШІ-інструментами v0.dev або ChatGPT?
Глосарій термінів. Адаптивні форми зворотного зв'язку та клієнтська валідація
Рекомендовано для вивчення перед захистом Лабораторної роботи №9
- Вебформа (<form>) — це спеціальний розділ HTML-документа, що містить інтерактивні елементи (поля введення, кнопки, списки) і призначений для збору та передачі даних від користувача на сервер.
- Тег <label> — семантичний елемент HTML, який використовується для створення текстового підпису (мітки) до конкретного поля введення.
- Атрибут for — спеціальний атрибут тегу <label>, значення якого має строго збігатися з атрибутом id пов'язаного поля введення (<input>). Забезпечує доступність та розширює клікабельну зону.
- Атрибут type — ключовий параметр тегу <input>, який визначає характер даних, що очікуються (наприклад, text, email, tel, number), та безпосередньо впливає на тип викликаної мобільної клавіатури на смартфонах.
- Плейсхолдер (placeholder) — атрибут поля введення, що задає короткий текст-підказку, який відображається всередині поля, доки користувач не почне вводити дані. Не заміняє собою тег <label>.
- Доступність (Accessibility/a11y) — практика проєктування веб-ресурсів, яка робить їх придатними та зручними для використання всіма людьми, включаючи осіб з порушеннями здоров'я та особливими потребами.
- Екранний диктор (Screen Reader/скрінрідер) — спеціальне допоміжне програмне забезпечення, яке зчитує вміст екрана (текст, структуру сайту, семантичні теги) і озвучує його для користувачів з порушеннями зору.
- Валідація (Validation) — процес перевірки введених користувачем даних на відповідність встановленим технічним правилам, бізнес-вимогам та маскам безпеки.
- Клієнтська валідація (Client-side) — перша лінія перевірки даних, яка відбувається безпосередньо в браузері користувача за допомогою мови JavaScript та атрибутів HTML5. Служить для покращення UX (миттєвий відгук інтерфейсу).
- Серверна валідація (Server-side) — обов'язкова та критично важлива лінія перевірки даних, що виконується на стороні бекенду (сервера) після надсилання форми. Відповідає за безпеку системи, оскільки клієнтську валідацію зловмисник може вимкнути.
- Регулярні вирази (Regular Expressions, RegEx) — формальна мова пошуку та маніпуляцій з підрядками в тексті, що заснована на використанні метасимволів (шаблонів/масок).
- Метасимвол (Metacharacter) — символ в мові RegEx, який має спеціальне керуюче значення замість свого звичайного граматичного змісту (наприклад, ^ — початок рядка, $ — кінець рядка, . — будь-який символ).
- Екранування (Escaping) — використання зворотного слешу (\) перед метасимволом в RegEx, щоб нейтралізувати спеціальну функцію і шукати його як звичайний символ (наприклад, \. шукає звичайну крапку).
- Квантифікатор (Quantifier) — спеціальний символ в регулярному виразі, який вказує, скільки разів має повторюватися попередній символ або група символів (наприклад, + — один або більше разів, {2,} — мінімум два рази).
- Обробник події (Event Listener) — функція в JavaScript, яка перебуває в режимі очікування певної дії користувача (наприклад, click, submit, input) і виконує заданий блок коду в момент її виникнення.
- Метод event.preventDefault() — команда JavaScript, яка скасовує стандартну поведінку браузера для поточної події. У вебформах використовується для зупинки негайного перезавантаження сторінки під час події submit.
- Модальне вікно (Modal Pop-up) — елемент інтерфейсу (діалогове або інформаційне вікно), який з'являється поверх основного контенту сайту, блокуючи взаємодію з іншою частиною сторінки, доки користувач його не закриє.
- Метод form.reset() — вбудована функція JavaScript, яка миттєво очищає всі поля форми, повертаючи їх до початкового (дефолтного) стану.
- Властивість event.target — об'єкт JavaScript, який вказує на конкретний елемент DOM-дерева, на якому безпосередньо відбулася подія (наприклад, елемент, по якому користувач клікнув мишкою).
- ШІ-робочий процес (AI-driven workflow) — сучасна методологія розробки програмного забезпечення, де написання, рефакторинг та оптимізація коду виконуються в синергії з інструментами штучного інтелекту.
- Рольове моделювання (Role-based Prompting) — техніка промпт-інжинірингу, за якої ШІ-моделі на початку діалогу явно привласнюється певна професійна роль (наприклад, Senior Frontend Engineer), що змушує ШІ генерувати якісніший, структурованіший код відповідно до стандартів індустрії.
- Заземлення контексту (Context Grounding) — процес передачі ШІ-моделі точних вхідних даних, специфічних технічних лімітів (наприклад, маска українського телефону +380) та технологічного стеку для запобігання абстрактним або недоречним відповідям (галюцинаціям).
- Виняток (Edge Case) — специфічна або гранична ситуація у використанні програми (наприклад, введення літер в поле телефону чи використання рідкісного домену другого рівня в email), яка виходить за рамки стандартного сценарію і потребує окремої обробки в коді валідації.
- Промпт-паспорт (Prompt Log) — структурована частина технічного звіту розробника, в якій фіксується історія діалогу з ШІ (промпти, відповіді, процес виправлення помилок) для аналізу та демонстрації свідомого керування нейромережею.