Вивчай
Домашнє завдання #13 · Події, валідація форм, localStorage
100 балів+15 бонусintermediate

Домашнє завдання #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"Введіть коректний 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+ символів, цифра + спецсимвол + велика літераЗелений

Візуально: прогрес-бар (ширина залежить від рівня) + текстовий лейбл рівня.


Як здати

  1. Робота — у репозиторії my-web-course, у папці hw-13/
  2. У папці — код, README.md (2-3 речення що зроблено + як відкрити) та скріншоти:
    • screenshots/desktop.png — загальний вигляд сторінки
    • screenshots/interaction.png — форма з видимими станами валідації: хоча б одне поле червоне з текстом помилки та хоча б одне зелене
  3. Мінімум 3 коміти з осмисленими повідомленнями — наприклад, окремо валідація, localStorage, рендер списку
  4. Здай посиланням на папку 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 поруч з формою з'явиться найголовніше — каталог твоєї колекції з додаванням, видаленням і фільтрацією. Це серце майбутнього застосунку. Не видаляй цей код!