Работа с формами через JS

JavaScript предоставляет DOM API для чтения и записи значений полей формы, обработки событий submit/input/change и валидации данных на стороне клиента перед отправкой.

Зачем нужно

Нативная отправка формы перезагружает страницу. JavaScript позволяет перехватить отправку, провести клиентскую валидацию, отправить данные через fetch (AJAX) и обновить UI без перезагрузки. Это основа современных SPA и интерактивных форм.

Где используется

  • Форма регистрации / авторизации
  • Многошаговые формы (wizards)
  • Форма поиска с автодополнением
  • Загрузка файлов
  • Редактирование профиля пользователя

Доступ к элементам формы

const form = document.querySelector('#registration-form');

// По имени через form.elements
const nameInput = form.elements['name'];    // HTMLInputElement
const emailInput = form.elements['email'];

// Или напрямую
const password = document.querySelector('#password');

// Чтение значения
console.log(nameInput.value);  // текущий текст в поле
console.log(nameInput.type);   // 'text', 'email', 'password'...

// Запись значения
nameInput.value = 'Иван';

Обработка submit

const form = document.querySelector('#contact-form');

form.addEventListener('submit', async (event) => {
  event.preventDefault(); // отменяем стандартную отправку

  // Сбор данных
  const formData = new FormData(form);
  const data = Object.fromEntries(formData);
  // { name: 'Иван', email: 'ivan@mail.ru', message: '...' }

  // Валидация
  if (!data.name.trim()) {
    showError('name', 'Имя обязательно');
    return;
  }

  // Отправка
  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
    if (!response.ok) throw new Error('Ошибка сервера');
    showSuccess('Сообщение отправлено!');
    form.reset();
  } catch (err) {
    showError('global', err.message);
  }
});

Типы полей и их значения

// Text, email, password — .value
const text = input.value;

// Checkbox — .checked
const agree = document.querySelector('#agree').checked; // true/false

// Radio — ищем checked
const gender = document.querySelector('input[name="gender"]:checked');
const genderValue = gender ? gender.value : null;

// Select — .value или .selectedOptions
const select = document.querySelector('#country');
const country = select.value;

// Множественный select
const multiSelect = document.querySelector('#languages');
const selected = [...multiSelect.selectedOptions].map(o => o.value);
// ['js', 'python', 'rust']

// Number input
const age = +document.querySelector('#age').value; // строка → число

// Date input
const birthDate = document.querySelector('#birth').value; // 'YYYY-MM-DD'

Динамическая валидация

const emailInput = document.querySelector('#email');

emailInput.addEventListener('input', () => {
  const value = emailInput.value;
  const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);

  emailInput.classList.toggle('invalid', !isValid && value.length > 0);
  emailInput.classList.toggle('valid', isValid);

  const hint = document.querySelector('#email-hint');
  hint.textContent = isValid ? '' : 'Введите корректный email';
});

// Constraint Validation API (встроенная валидация браузера)
emailInput.addEventListener('invalid', (e) => {
  e.preventDefault(); // подавляем стандартный tooltip
  showCustomError(emailInput.validationMessage);
});

FormData для файлов и multipart

const form = document.querySelector('#upload-form');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const formData = new FormData(form); // автоматически собирает файлы

  // Добавить поле вручную
  formData.append('userId', '42');

  const response = await fetch('/api/upload', {
    method: 'POST',
    body: formData // Content-Type: multipart/form-data устанавливается автоматически
  });
});

Частые ошибки

1. Забытый preventDefault

form.addEventListener('submit', (e) => {
  // Без e.preventDefault() — форма отправится и страница перезагрузится
  sendData; // не выполнится до перезагрузки
});

2. Значения всегда строки

const ageValue = document.querySelector('#age').value;
console.log(typeof ageValue); // 'string', не number
const age = Number(ageValue); // явное приведение

3. Чтение чекбокса через .value

const checkbox = document.querySelector('#agree');
checkbox.value;   // всегда 'on' (или HTML-атрибут value)
checkbox.checked; // true/false — правильное свойство

Связанные темы

Ресурсы