Домашнє завдання #13: Жива форма — валідація та localStorage
Форма підписки на твоєму лендінгу досі декоративна: натискаєш кнопку — і нічого. Сьогодні вона стане справжньою: перевірятиме дані в реальному часі, підсвічуватиме помилки та зберігатиме підписників.
Що ти вже маєш
Стилізований лендінг свого продукту з ДЗ #5 та ДЗ #6 — з формою підписки. Скопіюй index.html і style.css з hw-06/ у папку hw-13/ та додай script.js.
hw-13/
├── index.html
├── style.css
├── script.js ← вся логіка тут
├── screenshots/
│ ├── desktop.png
│ └── interaction.png
└── README.md
Частина 1: онови форму
Щоб підписка стала «реєстрацією акаунта», форма має містити щонайменше ці поля (додай ті, яких бракує; поля з ДЗ #5, як-от select тарифу — залишай, вони не заважають):
- Ім'я (text)
- Email (email)
- Пароль (password)
- Підтвердження пароля (password)
- Вік (number)
- Згода з умовами (checkbox)
- Кнопка відправки
Технічні вимоги:
- На тегу форми — атрибут
novalidate: він вимикає браузерну валідацію, бо ми пишемо свою - Біля кожного поля — місце під текст помилки (порожній
spanз класом), щоб макет не стрибав, коли помилка з'являється
Частина 2: правила валідації
Це специфікація — чекер перевірятиме поведінку саме за нею, включно з текстами повідомлень:
| Поле | Правило | Повідомлення при помилці |
|---|---|---|
| Ім'я | Мінімум 2 символи | "Ім'я має містити мінімум 2 символи" |
| Відповідає патерну email | "Введіть коректний email" | |
| Пароль | Мінімум 8 символів + хоча б 1 цифра | "Пароль: мінімум 8 символів та 1 цифра" |
| Підтвердження | Збігається з паролем | "Паролі не збігаються" |
| Вік | Число від 16 до 100 | "Вік має бути від 16 до 100" |
| Умови | Чекбокс обов'язково відмічений | "Необхідно погодитись з умовами" |
Частина 3: валідація в реальному часі
blur(поле втратило фокус): перевірити поле; якщо значення некоректне — показати помилкуinput(користувач набирає): якщо поле вже позначене як помилкове — перевіряти на кожен символ і прибирати помилку, щойно значення стане коректним- Візуальні стани: поле з помилкою — червона рамка + текст помилки під ним; коректне поле — зелена рамка. Стани перемикаються через CSS-класи, не через прямі зміни стилів у JS
Частина 4: відправка та localStorage
- На
submit: скасувати перезавантаження сторінки, провалідувати всі поля разом - Якщо все коректно — зберегти підписника в localStorage: масив об'єктів виду
{ name, email, age, registeredAt } - Пароль не зберігаємо ніде — навіть у навчальному проєкті це погана практика
- Показати повідомлення «Реєстрація успішна!», яке зникає через ~3 секунди
- Очистити форму та скинути візуальні стани полів
Частина 5: список підписників
Під формою — блок «Наші підписники»:
- При завантаженні сторінки рендериться список з localStorage (ім'я, email, вік, дата реєстрації)
- Після кожної успішної реєстрації список оновлюється без перезавантаження
- Якщо підписників немає — текст «Поки що нікого немає — будь першим!»
Бонус: індикатор сили пароля
Під полем пароля — індикатор, який оновлюється на кожен input:
| Рівень | Умова | Колір |
|---|---|---|
| Слабкий | Менше 8 символів | Червоний |
| Середній | 8+ символів, є цифра | Жовтий |
| Сильний | 8+ символів, цифра + спецсимвол + велика літера | Зелений |
Візуально: прогрес-бар (ширина залежить від рівня) + текстовий лейбл рівня.
Як здати
- Робота — у репозиторії
my-web-course, у папціhw-13/ - У папці — код,
README.md(2-3 речення що зроблено + як відкрити) та скріншоти:screenshots/desktop.png— загальний вигляд сторінкиscreenshots/interaction.png— форма з видимими станами валідації: хоча б одне поле червоне з текстом помилки та хоча б одне зелене
- Мінімум 3 коміти з осмисленими повідомленнями — наприклад, окремо валідація, localStorage, рендер списку
- Здай посиланням на папку
hw-13у репозиторії
Критерії оцінювання
| Критерій | Тип | Бали |
|---|---|---|
| Форма має всі поля з частини 1, novalidate, місця під помилки | [код] | 10 |
| Валідація кожного поля точно за таблицею правил (умови та тексти) | [код] | 25 |
| Real-time: blur показує помилку, input прибирає її після виправлення | [поведінка] | 15 |
| Червона/зелена рамки полів і тексти помилок видно на interaction.png | [скрін] | 10 |
| Submit: валідація всіх полів, збереження в localStorage без пароля | [поведінка] | 15 |
| Список підписників рендериться при завантаженні та після реєстрації | [поведінка] | 10 |
| Повідомлення про успіх з'являється і зникає через ~3 секунди | [поведінка] | 5 |
| Якість коду | [код] | 10 |
| Разом | 100 | |
| Бонус: індикатор сили пароля (3 рівні, прогрес-бар + лейбл, оновлення на input) | [поведінка] | +15 |
Підказки
Рівень 1: напрямок
Розбий задачу на незалежні шматки і роби по черзі: спочатку одна функція, яка приймає назву поля та значення і повертає текст помилки (або порожній рядок, якщо все добре). Потім — дві маленькі функції «показати помилку» та «показати успіх», які лише перемикають класи та текст. Далі повісь обробники подій на поля. localStorage і рендер списку — окремий етап, берись за нього, коли валідація вже працює.
Рівень 2: методи та API
- Події:
addEventListenerз типамиblur,input,submit; у обробнику submit —event.preventDefault() - Пошук елементів:
querySelector, а від поля до його обгортки —closest - Стани:
classList.add/classList.removeдля класів error та success,textContentдля тексту помилки - Перевірка email та цифри в паролі — метод
testрегулярного виразу; простий патерн email є в уроці про форми - localStorage:
getItem+JSON.parse(з запасним значенням порожнього масиву),setItem+JSON.stringify - Рендер списку:
mapпо масиву +join, абоcreateElement+appendу циклі - Зникнення повідомлення —
setTimeoutна ~3000 мс - Дата реєстрації —
new Date().toLocaleString("uk-UA")
Рівень 3: псевдокод
функція validateField(назваПоля, значення):
залежно від назвиПоля:
перевір правило з таблиці
якщо порушено → поверни текст помилки
поверни порожній рядок
для кожного поля форми:
на blur:
помилка = validateField(поле)
якщо помилка → показатиПомилку(поле, текст)
інакше → показатиУспіх(поле)
на input:
якщо поле зараз у стані помилки:
переперевір і, якщо все ок, → показатиУспіх(поле)
на submit форми:
скасувати стандартну відправку
провалідувати всі поля, запам'ятати чи всі коректні
якщо всі коректні:
прочитати масив підписників з localStorage
додати об'єкт (ім'я, email, вік, дата) — БЕЗ пароля
записати масив назад
перерендерити список підписників
показати повідомлення успіху, прибрати його через 3 с
скинути форму і стани полів
при завантаженні сторінки:
відрендерити список підписників з localStorage
Що далі
Твій продукт вже вміє «реєструвати» користувачів. У ДЗ #14 поруч з формою з'явиться найголовніше — каталог твоєї колекції з додаванням, видаленням і фільтрацією. Це серце майбутнього застосунку. Не видаляй цей код!