Форми та localStorage
JavaScript localStorage — картотека з організованими папками для збереження даних
У попередніх уроках ми навчилися знаходити елементи, маніпулювати DOM та обробляти події. Тепер з'єднаємо ці знання: будемо працювати з формами та зберігати дані у браузері через localStorage.
Події форм
HTML-форми генерують кілька важливих подій:
| Подія | Коли спрацьовує | На чому |
|---|---|---|
submit | Натиснуто кнопку submit або Enter | <form> |
input | Значення поля змінилося (кожен символ) | <input>, <textarea> |
change | Поле втратило фокус і значення змінилося | <input>, <select> |
focus | Поле отримало фокус (курсор) | Будь-який інтерактивний елемент |
blur | Поле втратило фокус | Будь-який інтерактивний елемент |
Обробка submit форми
За замовчуванням при submit браузер перезавантажує сторінку. Щоб цього не допустити, використовуємо event.preventDefault():
const form = document.querySelector("#registration-form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // зупиняємо перезавантаження
console.log("Форму відправлено!");
});
Якщо забути event.preventDefault(), сторінка перезавантажиться і весь JavaScript-стан буде втрачено. Це найчастіша помилка новачків при роботі з формами.
Отримання значень полів
Через event.target.elements
Кожне поле з атрибутом name доступне через form.elements:
<form id="login-form">
<input type="email" name="email" />
<input type="password" name="password" />
<button type="submit">Увійти</button>
</form>
const form = document.querySelector("#login-form");
form.addEventListener("submit", (event) => {
event.preventDefault();
const email = event.target.elements.email.value;
const password = event.target.elements.password.value;
console.log("Email:", email);
console.log("Password:", password);
});
Через querySelector
form.addEventListener("submit", (event) => {
event.preventDefault();
const email = form.querySelector('input[name="email"]').value;
console.log("Email:", email);
});
Подія input -- реакція в реальному часі
const searchInput = document.querySelector("#search");
searchInput.addEventListener("input", (event) => {
console.log("Шукаємо:", event.target.value);
});
input спрацьовує при кожному символі. change -- тільки коли поле втратить фокус. Для пошуку в реальному часі використовуй input, для фінального збереження -- change.
Валідація форм
HTML-валідація
HTML надає вбудовані атрибути для валідації:
<input type="email" required />
<input type="text" minlength="3" maxlength="50" />
<input type="text" pattern="[A-Za-z]+" title="Тільки літери" />
JavaScript-валідація
Для більш складної логіки перевіряємо у JS:
form.addEventListener("submit", (event) => {
event.preventDefault();
const name = event.target.elements.name.value.trim();
const email = event.target.elements.email.value.trim();
const errorDiv = document.querySelector(".error");
// Очищаємо попередні помилки
errorDiv.textContent = "";
if (name.length < 2) {
errorDiv.textContent = "Ім'я має містити мінімум 2 символи";
return;
}
if (!email.includes("@")) {
errorDiv.textContent = "Введіть коректний email";
return;
}
console.log("Все валідно! Дані:", { name, email });
});
Підсвітка полів при помилці
function showError(input, message) {
input.classList.add("error");
input.nextElementSibling.textContent = message;
}
function clearError(input) {
input.classList.remove("error");
input.nextElementSibling.textContent = "";
}
// Очищаємо помилку при фокусі
input.addEventListener("focus", () => {
clearError(input);
});
localStorage
localStorage дозволяє зберігати дані у браузері назавжди (поки користувач не очистить). Дані зберігаються навіть після закриття вкладки.
Основні методи
// Зберегти
localStorage.setItem("username", "Оля");
// Прочитати
const name = localStorage.getItem("username"); // "Оля"
// Видалити один ключ
localStorage.removeItem("username");
// Очистити все
localStorage.clear();
localStorage зберігає тільки рядки. Число 42 буде збережене як рядок "42". Для об'єктів та масивів потрібен JSON.
JSON.stringify та JSON.parse
Щоб зберегти об'єкт або масив у localStorage, конвертуємо його у рядок через JSON.stringify. Щоб прочитати назад -- через JSON.parse:
const user = { name: "Оля", age: 25, city: "Київ" };
// Зберегти об'єкт
localStorage.setItem("user", JSON.stringify(user));
// Прочитати об'єкт
const saved = localStorage.getItem("user");
const parsed = JSON.parse(saved);
console.log(parsed.name); // "Оля"
console.log(parsed.age); // 25 (число, не рядок!)
Масиви
const todos = ["Купити молоко", "Вивчити JS", "Погуляти"];
localStorage.setItem("todos", JSON.stringify(todos));
const loaded = JSON.parse(localStorage.getItem("todos"));
console.log(loaded); // ["Купити молоко", "Вивчити JS", "Погуляти"]
Корисний патерн -- перевірка чи є збережені дані:
const data = localStorage.getItem("todos");
const todos = data ? JSON.parse(data) : [];Якщо ключ не знайдено, getItem поверне null, а JSON.parse(null) поверне null. Тому завжди перевіряй перед парсингом.
sessionStorage
sessionStorage працює ідентично до localStorage, але дані видаляються при закритті вкладки:
sessionStorage.setItem("tempData", "тимчасове");
sessionStorage.getItem("tempData"); // "тимчасове"
// Після закриття вкладки -- дані зникнуть
| Характеристика | localStorage | sessionStorage |
|---|---|---|
| Зберігається | Назавжди | До закриття вкладки |
| Доступ між вкладками | Так | Ні |
| Максимальний розмір | ~5-10 МБ | ~5-10 МБ |
Практика: форма з localStorage
Створимо форму, яка зберігає введені дані та відновлює їх при перезавантаженні сторінки:
<form id="profile-form">
<label>
Ім'я: <input type="text" name="name" />
</label>
<label>
Email: <input type="email" name="email" />
</label>
<label>
Місто:
<select name="city">
<option value="">Оберіть місто</option>
<option value="kyiv">Київ</option>
<option value="lviv">Львів</option>
<option value="odesa">Одеса</option>
</select>
</label>
<button type="submit">Зберегти</button>
</form>
<p id="status"></p>
const form = document.querySelector("#profile-form");
const status = document.querySelector("#status");
// Відновлення даних при завантаженні сторінки
function loadSavedData() {
const saved = localStorage.getItem("profile");
if (!saved) return;
const data = JSON.parse(saved);
form.elements.name.value = data.name || "";
form.elements.email.value = data.email || "";
form.elements.city.value = data.city || "";
}
// Збереження при submit
form.addEventListener("submit", (event) => {
event.preventDefault();
const profile = {
name: form.elements.name.value.trim(),
email: form.elements.email.value.trim(),
city: form.elements.city.value,
};
localStorage.setItem("profile", JSON.stringify(profile));
status.textContent = "Дані збережено!";
setTimeout(() => {
status.textContent = "";
}, 2000);
});
// Завантажуємо дані при старті
loadSavedData();
Підсумок
submit-- головна подія форми, завжди використовуйevent.preventDefault()event.target.elements-- зручний доступ до полів за атрибутомnameinput-- реакція на кожен введений символ,change-- на втрату фокусаlocalStorage-- зберігає рядки назавжди, використовуйJSON.stringify/JSON.parseдля складних данихsessionStorage-- аналог localStorage, але тільки на час сесії
Що далі?
У наступному уроці -- практичний проєкт Todo List! Ми застосуємо всі знання з Block 5: DOM, події, форми та localStorage -- для створення повноцінного інтерактивного додатку.
Корисні посилання:
- javascript.info: Форми та елементи керування -- все про форми (українською)
- MDN: Web Storage API -- документація localStorage/sessionStorage
- Chrome DevTools: вкладка Application -> Local Storage -- тут можна переглядати та редагувати збережені дані