Элементы формы и их значения

формы≈ 7 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

Поле формы — коробка, в которую пишет пользователь, а не вы. Поэтому у него всегда два значения: value в разметке — то, с чего всё началось, и свойство value в JavaScript — то, что там прямо сейчас.

Разделы темы:·

У форм есть свой короткий путь: document.forms — коллекция всех форм страницы, и обращаться к ней можно по name или id. Внутри формы такая же коллекция полей — form.elements: по имени, по индексу, с обычным length.

Это удобнее, чем querySelector: имена полей вы всё равно пишете в разметке ради отправки на сервер, так что второго набора селекторов не требуется.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

В form.elements лежат все управляющие элементы формы. А в отправку попадают только те, у которых есть name и которые не выключены через disabled. Проверить состав отправки можно объектом FormData.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

У input и textarea текущее содержимое читается одинаково — через value. Для textarea это важно отдельно: текст между тегами — только начальное значение, и innerHTML после правок пользователя покажет старое. Начальное значение доступно как defaultValue.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Атрибут в разметке — стартовое значение, свойство — текущее. Пользователь печатает в свойство, поэтому getAttribute("value") останется прежним, а input.value скажет правду. Обратное тоже верно: setAttribute("value", ...) после первого ввода уже ничего не изменит на экране.

И главная ловушка: value — строка. Даже у type="number". Числовой вид лежит рядом, в valueAsNumber (для type="date" есть valueAsDate).

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

У флажка и переключателя value тоже есть, но оно отвечает на другой вопрос: «какую строку отправить, если элемент отмечен». Само состояние — булево свойство checked, а начальное состояние из разметки — defaultChecked.

Радиокнопки с одинаковым name внутри формы собираются в RadioNodeList. У неё есть своё value — значение отмеченного элемента; записав туда строку, вы отметите нужный переключатель.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Если атрибут value не задан, браузер подставляет строку on — историческое значение по умолчанию. Оно ничего не говорит о состоянии: у снятого флажка value тоже on.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

У select три способа спросить об одном и том же: value — значение выбранной опции, selectedIndex — её номер, options — коллекция всех option. Запись в value выбирает опцию с таким значением, запись в selectedIndex — по номеру.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Со списком, где разрешено несколько значений (multiple), value становится бесполезным: оно вернёт только первую выбранную опцию. Все отмеченные лежат в selectedOptions. Новую опцию удобно создавать конструктором new Option(текст, значение) и добавлять обычным append.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера
ЭлементЧто читатьЗаметка
input type="text"valueвсегда строка
textareavalueне innerHTML
input type="checkbox"checkedvalue — строка для отправки
группа radioform.elements.name.valueзначение отмеченного
selectvalue, selectedIndexдля multiple — selectedOptions

Связь двусторонняя: из формы видны поля, а у каждого поля есть свойство form — ссылка на его форму. Причём элемент необязательно лежит внутри тега form: атрибут form="id-формы" присоединяет к ней поле из любого места страницы.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Практическая польза — обработчики. Из события известен элемент, из элемента — форма, из формы — все соседние поля. Не нужно ни глобальных переменных, ни поиска по документу.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

  • К форме и её полям есть короткий путь по именам: document.forms.имя, затем form.elements.имя. Работает и по id, и по индексу.
  • value — всегда строка и всегда текущее значение. Начальное значение из разметки лежит отдельно, в defaultValue; для чисел есть valueAsNumber.
  • У чекбокса и радио состояние — это checked, а value лишь строка для отправки (по умолчанию on). Значение отмеченного переключателя даёт form.elements.имя.value.
  • У select читают value, selectedIndex и options; для multiple единственный честный источник — selectedOptions.
  • Свойство element.form ведёт от поля обратно к форме — даже если поле лежит вне тега form и присоединено атрибутом form="id".

1/3В разметке было <input id="nick" value="rico">. Выполнили input.value = "neo". Что вернёт input.getAttribute("value")?

2/3В форме два радио с name="plan" и значениями free и pro, отмечен pro. Что вернёт form.elements.plan.value?

3/3У <select multiple> три опции, выбраны первая и третья. Что даст select.value?

Сводка по форме

Напишите функцию summary(form), которая собирает строку вида nick=rico;subscribe=true;level=pro: имя поля, знак равенства, значение. Для чекбокса значением считается true или false, для остальных — value. Порядок — как в разметке.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Коллекция form.elements перебирается как массив, а тип элемента подсказывает свойство type: у чекбокса это checkbox, у выпадающего списка — select-one.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Обратите внимание: у чекбокса намеренно берётся checked, а не value — иначе для снятого флажка вышло бы subscribe=on. Если бы в форме встретились поля без name, их стоило бы отфильтровать: .filter((el) => el.name).

Переключатель «выбрать все»

В форме четыре чекбокса: master и три обычных. Сделайте так, чтобы переключение master выставляло всем остальным то же состояние. Сам master в цикле пропускают: остальным присваивают его состояние, а ему самому присваивать уже нечего.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
страница примера

Событие change у чекбокса срабатывает и при программном click(), так что проверить решение можно без участия пользователя.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Второй клик снимает всё, включая ранее отмеченный b: обработчик копирует состояние мастера, а не переключает каждый флажок по отдельности.