Формы в JavaScript

HTML-форма позволяет получить данные от пользователя: имя, адрес электронной почты, выбранный вариант или согласие с условиями. JavaScript нужен, чтобы прочитать эти данные, изменить состояние полей, проверить введённые значения и выполнить действие при отправке формы.

В DOM форма и каждое её поле представлены отдельными объектами. Поэтому с ними можно работать так же, как с другими элементами страницы: находить, получать свойства и изменять их.

Форма и её поля

Форму создают элементом form. Внутри располагают элементы управления: input, textarea, select, кнопки и другие поля.

Будем работать с формой профиля:

<form class="profile-form" name="profile">
  <label>
    Имя
    <input name="username" type="text" required>
  </label>

  <label>
    Возраст
    <input name="age" type="number" min="14" required>
  </label>

  <label>
    Город
    <select name="city" required>
      <option value="">Выберите город</option>
      <option value="Москва">Москва</option>
      <option value="Казань">Казань</option>
      <option value="Самара">Самара</option>
    </select>
  </label>

  <fieldset>
    <legend>Формат занятий</legend>

    <label>
      <input name="studyFormat" type="radio" value="Онлайн" checked>
      Онлайн
    </label>

    <label>
      <input name="studyFormat" type="radio" value="Очно">
      Очно
    </label>
  </fieldset>

  <label>
    <input name="newsletter" type="checkbox" checked>
    Получать новости
  </label>

  <button type="submit">Сохранить</button>
  <button type="reset">Вернуть исходные значения</button>
</form>

<p class="profile-result" aria-live="polite"></p>

Атрибут type определяет назначение поля или кнопки. Например, type=“number” создаёт поле для числа, type=“checkbox” - флажок, а type=“submit” - кнопку отправки формы.

У элемента button внутри формы типом по умолчанию является submit. Если кнопка должна открывать подсказку, добавлять поле или выполнять другое действие без отправки формы, укажите type=“button”.

Как получить форму

Форму можно найти обычным DOM-методом querySelector():

const profileForm = document.querySelector('.profile-form');

Переменная profileForm содержит объект формы. Через него можно обращаться к полям, свойствам и методам этой формы.

Все формы документа также доступны в коллекции document.forms. Если у формы есть атрибут name=“profile”, её можно получить по этому имени:

const sameProfileForm = document.forms.profile;

console.log(profileForm === sameProfileForm); // true

К одной форме ведут оба способа. querySelector() подходит для любого CSS-селектора, а document.forms удобно использовать, когда формы имеют понятные имена.

Обратиться к форме можно и по индексу, например document.forms[0]. Но такой код зависит от порядка элементов на странице. Если выше появится ещё одна форма, индекс изменится, поэтому имя или селектор обычно надёжнее.

Как получить элементы формы

Свойство elements содержит элементы управления, связанные с формой. Поле можно получить по его атрибуту name:

const usernameInput = profileForm.elements.username;
const ageInput = profileForm.elements.age;
const citySelect = profileForm.elements.city;
const newsletterCheckbox = profileForm.elements.newsletter;
const studyFormatRadios = profileForm.elements.studyFormat;

Для username, age, city и newsletter возвращается соответствующий элемент. У двух radio-кнопок одинаковое имя studyFormat, поэтому они объединяются в одну группу.

Если имя содержит дефис или другой символ, который неудобно использовать после точки, применяют квадратные скобки:

const phoneInput = profileForm.elements['phone-number'];

Искать поле можно и через querySelector(), ограничив поиск самой формой:

const sameUsernameInput = profileForm.querySelector('[name="username"]');

console.log(usernameInput === sameUsernameInput); // true

Оба варианта работают. form.elements подчёркивает, что мы обращаемся именно к элементу управления этой формы, а querySelector() позволяет использовать любой подходящий CSS-селектор.

Зачем полям нужны name и id

Атрибуты name и id решают разные задачи.

  • name задаёт имя поля в данных формы и позволяет получить его через form.elements;
  • id уникально обозначает элемент на странице и связывает поле с подписью через label for.

Если данные формы будут отправляться или собираться целиком, полю нужен name. Без него значение не получит имени и не попадёт в набор отправляемых данных.

<label for="user-email">Электронная почта</label>
<input id="user-email" name="email" type="email">

Здесь id=“user-email” связывает поле с подписью, а name=“email” задаёт имя его значения в форме. Часто элементу нужны оба атрибута.

Чтение значений

Способ получения данных зависит от типа элемента. У текстового поля, textarea и select текущее значение хранится в свойстве value.

const username = profileForm.elements.username.value;
const ageValue = profileForm.elements.age.value;
const city = profileForm.elements.city.value;

Даже у поля type=“number” свойство value возвращает строку. Если возраст нужен для вычислений, его необходимо преобразовать в число:

const age = Number(ageValue);

У checkbox значение value не показывает, установлен ли флажок. Для проверки состояния используют булево свойство checked:

const getsNewsletter = profileForm.elements.newsletter.checked;

console.log(getsNewsletter); // true или false

У radio-кнопок с одинаковым name значение группы содержит value выбранного варианта:

const studyFormat = profileForm.elements.studyFormat.value;

console.log(studyFormat); // Онлайн или Очно

Если в группе не выбрана ни одна radio-кнопка, результатом будет пустая строка.

Изменение значений

Значения формы можно не только читать, но и задавать из JavaScript. Для текстовых полей, select и группы radio используют value, а для checkbox - checked.

profileForm.elements.username.value = 'Анна';
profileForm.elements.age.value = '24';
profileForm.elements.city.value = 'Казань';
profileForm.elements.studyFormat.value = 'Очно';
profileForm.elements.newsletter.checked = false;

После выполнения кода пользователь увидит новые значения в полях. Значение для select или radio-группы должно совпадать с value существующего варианта.

Присваивание через JavaScript само по себе не вызывает события input и change. Если после программного изменения нужно обновить другую часть интерфейса, вызовите отвечающую за это функцию отдельно.

Обработка отправки формы

Когда пользователь нажимает кнопку type=“submit”, форма отправляется. JavaScript может обработать событие submit, прочитать текущие значения и выполнить нужное действие.

Добавим обработчик к форме из примера:

const profileResult = document.querySelector('.profile-result');

profileForm.addEventListener('submit', function (event) {
  event.preventDefault();

  const profile = {
    username: profileForm.elements.username.value.trim(),
    age: Number(profileForm.elements.age.value),
    city: profileForm.elements.city.value,
    studyFormat: profileForm.elements.studyFormat.value,
    newsletter: profileForm.elements.newsletter.checked,
  };

  console.log(profile);
  profileResult.textContent = `Данные пользователя ${profile.username} сохранены`;
});

Метод event.preventDefault() отменяет стандартную отправку, поэтому страница не перезагрузится. После этого код собирает значения в объект profile, выводит его в консоль и показывает сообщение на странице.

В примере у полей есть ограничения required и min. Браузер проверит их до запуска submit. Если обязательное поле пустое или возраст меньше допустимого, форма не перейдёт к обработчику отправки.

preventDefault() только отменяет стандартное действие браузера. Он не сохраняет и не отправляет данные самостоятельно - дальнейшее действие должен выполнить ваш код.

Сброс формы

Кнопка type=“reset” возвращает полям исходные значения из HTML. То же действие можно выполнить методом reset():

profileForm.reset();

Сброс не всегда означает полную очистку. В исходной разметке radio-кнопка Онлайн и checkbox отмечены через checked, поэтому после сброса они снова будут выбраны. Поля без начального значения станут пустыми.

Итого

Форма в JavaScript представлена объектом, который можно получить через querySelector() или коллекцию document.forms. Свойство form.elements даёт доступ к элементам управления по их имени.

Текстовые поля и списки хранят текущее значение в value, состояние checkbox находится в checked, а у radio-группы через value можно получить выбранный вариант. Событие submit позволяет обработать отправку формы, а метод reset() возвращает полям исходное состояние.