Вивчай

Форми та localStorage

JavaScript 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"); // "тимчасове"
// Після закриття вкладки -- дані зникнуть
ХарактеристикаlocalStoragesessionStorage
ЗберігаєтьсяНазавждиДо закриття вкладки
Доступ між вкладкамиТакНі
Максимальний розмір~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 -- зручний доступ до полів за атрибутом name
  • input -- реакція на кожен введений символ, change -- на втрату фокуса
  • localStorage -- зберігає рядки назавжди, використовуй JSON.stringify/JSON.parse для складних даних
  • sessionStorage -- аналог localStorage, але тільки на час сесії

Що далі?

У наступному уроці -- практичний проєкт Todo List! Ми застосуємо всі знання з Block 5: DOM, події, форми та localStorage -- для створення повноцінного інтерактивного додатку.

Інфо

Корисні посилання: