Входные атрибуты HTML уроки для начинающих академия
❮ Назад Дальше ❯
Атрибут value
Атрибут value
указывает начальное значение для поля ввода:
Пример
<form action=»»>
First name:<br>
<input type=»text» name=»firstname»
value=»John»>
</form>
Атрибут ReadOnly
Атрибут readonly
указывает, что поле ввода только для чтения (не может быть изменено):
Пример
<form action=»»>
First name:<br>
<input type=»text» name=»firstname»
value=»John» readonly>
</form>
Отключенный атрибут
Атрибут disabled
указывает, что поле ввода отключено.
Отключенное поле ввода непригодно для использования и не может быть нажато, и его значение не будет отправлено при отправке формы:
Пример
<form action=»»>
First name:<br>
<input type=»text» name=»firstname»
value=»John» disabled>
</form>
Атрибут size
Атрибут size
определяет размер (в символах) для поля ввода:
Пример
<form action=»»>
First name:<br>
<input type=»text» name=»firstname»
value=»John» size=»40″>
</form>
Атрибут MaxLength
Атрибут maxlength
указывает максимальную допустимую длину поля ввода:
Пример
<form action=»»>
First name:<br>
<input type=»text» name=»firstname»
maxlength=»10″>
</form>
С атрибутом maxlength
поле ввода не будет принимать больше допустимого числа символов.
Атрибут maxlength
не предоставляет никакой обратной связи. Если вы хотите предупредить пользователя, вы должны написать код JavaScript.
Примечание: Ограничения ввода не являются надежными, и JavaScript предоставляет множество способов добавить недопустимый ввод. Чтобы безопасно ограничить вход, он должен быть проверен получателем (сервером), а также!
Атрибуты HTML5
HTML5 добавил следующие атрибуты для <input>
:
- autocomplete
- autofocus
- form
- formaction
- formenctype
- formmethod
- formnovalidate
- formtarget
- height and width
- list
- min and max
- multiple
- pattern (regexp)
- placeholder
- required
- step
и следующие атрибуты для <form>
:
- autocomplete
- novalidate
Атрибут автозаполнения
Атрибут autocomplete
указывает, должна ли форма или поле ввода иметь Автозаполнение или выключить.
Когда Автозаполнение включен, браузер автоматически завершает входные значения, основываясь на значениях, введенных пользователем ранее.
Совет: Можно иметь Автозаполнение «on» для формы и «OFF» для определенных полей ввода или наоборот.
Атрибут autocomplete
работает с <form>
и следующими типами <input>
: текстом, поиском, URL, тел, электронной почтой, паролем, датепиккерс, диапазоном и цветом.
Пример
HTML-форма с автозаполнением on (и Off для одного поля ввода):
<form action=»/action_page.php» autocomplete=»on»>
Last name: <input type=»text» name=»lname»><br>
E-mail: <input type=»email» name=»email» autocomplete=»off»><br>
<input type=»submit»>
</form>
Совет: В некоторых браузерах вам может понадобиться активировать функцию автозаполнения, чтобы это работало.
Атрибут unvalidate
Атрибут novalidate
является атрибутом <form>
.
При наличии, unvalidate указывает, что данные формы не должны проверяться при отправке.
Пример
Указывает, что форма не проверяется при отправке:
<form action=»/action_page.php» novalidate>
E-mail: <input type=»email» name=»user_email»>
<input type=»submit»>
</form>
Атрибут автофокусировки
Атрибут autofocus
указывает, что поле ввода должно автоматически получать фокус при загрузке страницы.
Пример
Пусть поле ввода «имя» автоматически получает фокус при загрузке страницы:
First name:<input type=»text» name=»fname» autofocus>
Атрибут формы
Атрибут form
указывает одну или несколько форм, к которым принадлежит элемент <input>
.
Совет: Чтобы ссылаться на более чем одну форму, используйте разделенный пробелами список идентификаторов форм.
Пример
<form action=»/action_page.php»>
First name: <input type=»text» name=»fname»><br>
<input type=»submit» value=»Submit»>
</form>
Last name: <input type=»text» name=»lname» form=»form1″>
Атрибут формактион
Атрибут formaction
указывает URL-адрес файла, который будет обрабатывать элемент управления вводом при отправке формы.
Атрибут формактион переопределяет атрибут action элемента <form>
.
Атрибут формактион используется с type="submit"
и type="image"
.
Пример
HTML-форма с двумя кнопками отправки, с различными действиями:
<form action=»/action_page.php»>
First name: <input type=»text» name=»fname»><br>
Last name: <input type=»text» name=»lname»><br>
<input type=»submit» value=»Submit»><br>
<input type=»submit» formaction=»/action_page2. php»
value=»Submit as admin»>
</form>
Атрибут форменктипе
Атрибут formenctype
указывает, как данные формы должны кодироваться при отправке (только для форм с методом = «Post»).
Атрибут formenctype
переопределяет атрибут Enctype элемента <form>
.
Атрибут formenctype
используется с type="submit"
и type="image"
.
Пример
Отправьте форму-данные, закодированные по умолчанию (первая кнопка Submit), и закодированные как «составные/формы-данные» (вторая кнопка Submit):
<form action=»/action_page_binary.php» method=»post»>
First name: <input type=»text» name=»fname»><br>
<input type=»submit» value=»Submit»>
<input type=»submit» formenctype=»multipart/form-data»
value=»Submit as Multipart/form-data»>
</form>
Атрибут форммесод
Атрибут formmethod
определяет метод HTTP для отправки данных формы в URL-адрес действия.
Атрибут formmethod
переопределяет атрибут метода элемента <form>
.
Атрибут formmethod
можно использовать с type="submit"
и type="image"
.
Пример
Вторая кнопка Submit переопределяет метод HTTP формы:
<form action=»/action_page.php» method=»get»>
First name: <input type=»text» name=»fname»><br>
Last name: <input type=»text» name=»lname»><br>
<input type=»submit» value=»Submit»>
<input type=»submit» formmethod=»post» value=»Submit using POST»>
</form>
Атрибут formnovalidate
Атрибут formnovalidate
переопределяет атрибут unvalidate элемента <form>
.
Атрибут formnovalidate
можно использовать с type="submit"
.
Пример
Форма с двумя кнопками отправки (с проверкой и без проверки):
<form action=»/action_page.php»>
E-mail: <input type=»email» name=»userid»><br>
<input type=»submit» formnovalidate value=»Submit without validation»>
</form>
Атрибут формтаржет
Атрибут formtarget
указывает имя или ключевое слово, указывающее, где отображать ответ, полученный после отправки формы.
Атрибут formtarget
переопределяет целевой атрибут элемента <form>
.
Атрибут formtarget
можно использовать с type="submit"
и type="image"
.
Пример
Форма с двумя кнопками отправки, с различными целевыми окнами:
<form action=»/action_page.php»>
First name: <input type=»text» name=»fname»><br>
Last name: <input type=»text» name=»lname»><br>
<input type=»submit» value=»Submit as normal»>
<input type=»submit» formtarget=»_blank»
value=»Submit to a new window»>
</form>
Атрибуты Height и Width
Атрибуты height
и width
определяют высоту и ширину элемента <input
type="image">
.
Всегда указывайте размер изображений. Если браузер не знает размер, страница будет мигать во время загрузки изображений.
Пример
Определите изображение как кнопку Submit с атрибутами Height и Width:
<input type=»image» src=»img_submit. gif» alt=»Submit»>
Атрибут List
Атрибут list
ссылается на элемент <datalist>
, который содержит предварительно определенные параметры для элемента <input>.
Пример
Элемент <input> с заранее определенными значениями в <DataList>:
<input list=»browsers»><datalist>
<option value=»Internet Explorer»>
<option value=»Firefox»>
<option value=»Chrome»>
<option value=»Opera»>
<option value=»Safari»>
</datalist>
Атрибуты min и Max
Атрибуты min
и max
определяют минимальное и максимальное значения для элемента <input>
.
Атрибуты min
и max
работают со следующими типами ввода: число, диапазон, Дата, DateTime-Local, месяц, время и неделя.
Пример
<input> элементы с минимальными и максимальными значениями:
Enter a date before 1980-01-01:
<input type=»date» name=»bday» max=»1979-12-31″>
Enter a date after 2000-01-01:
<input type=»date» name=»bday» min=»2000-01-02″>
Quantity (between 1 and 5):
<input type=»number» name=»quantity» min=»1″ max=»5″>
Множественный атрибут
Атрибут multiple
указывает, что пользователю разрешено вводить более одного значения в элементе <input>
.
Атрибут multiple
работает со следующими типами ввода: Электронная почта и файл.
Пример
Поле загрузки файла, принимающее несколько значений:
Select images: <input type=»file» name=»img» multiple>
Атрибут pattern
Атрибут pattern
задает регулярное выражение, для которого проверяется значение элемента <input>
.
Атрибут pattern
работает со следующими типами ввода: текстом, поиском, URL-адресом, тел, электронной почтой и паролем.
Совет: Используйте атрибут Global Title для описания шаблона, чтобы помочь пользователю.
Совет: Узнайте больше о регулярных выражениях в нашем учебнике по JavaScript.
Пример
Поле ввода, которое может содержать только три буквы (без цифр или специальных символов):
Country code: <input type=»text» name=»country_code» pattern=»[A-Za-z]{3}» title=»Three letter country code»>
Атрибут заполнителя
Атрибут placeholder
указывает подсказку, описывающую ожидаемое значение поля ввода (примерное значение или краткое описание формата).
Подсказка отображается в поле ввода перед вводом пользователем значения.
Атрибут placeholder
работает со следующими типами ввода: текстом, поиском, URL-адресом, тел, электронной почтой и паролем.
Пример
Поле ввода с замещающим текстом:
<input type=»text» name=»fname» placeholder=»First name»>
Обязательный атрибут
Атрибут required
указывает, что поле ввода должно быть заполнено перед отправкой формы.
Атрибут required
работает со следующими типами ввода: текст, поиск, URL, тел, электронная почта, пароль, Дата выборки, номер, флажок, Радио и файл.
Пример
Требуемое поле ввода:
Username: <input type=»text» name=»usrname» required>
Атрибут step
Атрибут step
указывает интервалы юридических чисел для элемента <input>
.
Пример: Если шаг = «3», юридические номера могут быть-3, 0, 3, 6 и т.д.
Совет: Атрибут Step можно использовать вместе с атрибутами Max и min для создания диапазона юридических значений.
Атрибут step
работает со следующими типами ввода: число, диапазон, Дата, DateTime-Local, месяц, время и неделя.
Пример
Поле ввода с указанными интервалами юридического числа:
<input type=»number» name=»points» step=»3″>
HTML-формы и элементы ввода
Тег | Описание |
---|---|
<form> | Определяет HTML-форму для ввода данных пользователем |
<input> | Определяет элемент управления вводом |
❮ Назад Дальше ❯
Работа с формами — JavaScript — Дока
Кратко
Секция статьи «Кратко»Помимо стандартных средств работы с формами можно использовать JavaScript, чтобы проверять формы на валидность, получать доступ к значениям и отправлять информацию на сервер.
Трюки для работы с формами в JS проще всего показать на примере. В этой статье мы соберём форму заявки на участие в миссии по колонизации Марса. В этой форме мы немножко приправим стандартные HTML-атрибуты динамикой на JS.
Разметка и требования
Секция статьи «Разметка и требования»- Имя, чтобы знать, как обращаться в ответном письме.
- Почту, чтобы знать, куда это письмо слать.
- Возраст — нужны только молодые 🤷♂️
- Специализацию — инженеры и учёные пригодятся для основной работы, а психологи нужны, чтобы команда друг друга не перегрызла за десятилетнюю колонизаторскую миссию.
- Работал ли человек в NASA — это большой плюс.
- Фотография, чтобы использовать в печатных материалах.
<form action="/apply/" method="POST"> <label> Ваше имя: <input type="text" name="name" placeholder="Илон Маск" required autofocus> </label> <label> Почта: <input type="email" name="email" placeholder="elon@musk.com" required> </label> <label> Возраст: <input type="number" name="age" required> </label> <label> Профессия: <select name="specialization" required> <option value="engineer" selected>Инженер</option> <option value="scientist">Учёный</option> <option value="psychologist">Психолог</option> <option value="other">Другая</option> </select> </label> <label> Я работал в NASA <input type="checkbox" name="nasa-experience" value="1"> </label> <label> Фото: <input type="file" accept="image/jpeg" name="photo" required> </label> <button type="submit">Отправить заявку</button></form>
<form action="/apply/" method="POST">
<label>
Ваше имя:
<input type="text" name="name" placeholder="Илон Маск" required autofocus>
</label>
<label>
Почта:
<input type="email" name="email" placeholder="elon@musk.
com" required>
</label>
<label>
Возраст:
<input type="number" name="age" required>
</label>
<label>
Профессия:
<select name="specialization" required>
<option value="engineer" selected>Инженер</option>
<option value="scientist">Учёный</option>
<option value="psychologist">Психолог</option>
<option value="other">Другая</option>
</select>
</label>
<label>
Я работал в NASA
<input type="checkbox" name="nasa-experience" value="1">
</label>
<label>
Фото:
<input type="file" accept="image/jpeg" name="photo" required>
</label>
<button type="submit">Отправить заявку</button>
</form>
Открыть демо в новой вкладкеВ целом форма рабочая: обязательные поля не пропустят пустые значения, атрибут
type
проследит, чтобы вместо почты нам не прислали номер телефона, а по нажатию на кнопку валидная форма отправит все данные.
Но нам кроме всего этого хочется:
- чтобы страница при отправке не перезагружалась;
- чтобы во время запроса показывался лоадер, при успешной отправке — поздравление, а при ошибке — причина ошибки;
- чтобы кнопка была заблокирована до тех пор, пока форма не валидна.
Приступим.
Отправка без перезагрузки
Секция статьи «Отправка без перезагрузки»Первым делом настроим отправку формы без перезагрузки страницы.
Перезагрузка страницы — это поведение по умолчанию для отправки формы. Чтобы его предотвратить, нам нужно «перехватить» управление в момент отправки и сказать форме, что делать вместо этого.
Предотвращаем отправку данных
Секция статьи «Предотвращаем отправку данных»Для «предотвращения» срабатывания событий мы можем использовать метод prevent
на объекте события. В нашем случае событием будет отправка формы — submit
.
Если наше событие находится в переменной event
event.
preventDefault()
.Чтобы «соединить» форму с нашей будущей собственной отправкой данных, мы напишем функцию, которая будет «слушать» событие отправки и реагировать на него.
Найдём форму на странице, с помощью get
и подпишемся на событие submit
с помощью add
. Пока мы не будем отправлять форму, а просто напечатаем в консоль строку «Отправка!» и убедимся, что механизм работает:
function handleFormSubmit(event) { // Просим форму не отправлять данные самостоятельно event.preventDefault() console.log('Отправка!')}const applicantForm = document.getElementById('mars-once')applicantForm.addEventListener('submit', handleFormSubmit)
function handleFormSubmit(event) {
// Просим форму не отправлять данные самостоятельно
event.preventDefault()
console.log('Отправка!')
}
const applicantForm = document.
getElementById('mars-once')
applicantForm.addEventListener('submit', handleFormSubmit)
Мы можем просто передать функцию handle
как второй аргумент в add
, так как он автоматически передаст событие в качестве аргумента для handle
.
Получится, что при отправке формы сработает событие submit
, которое запустит наш обработчик handle
.
В этот обработчик как аргумент event
будет передано событие отправки. Мы вызовем event
, и форма не отправится самостоятельно.
Собираем данные из формы
Секция статьи «Собираем данные из формы»Следующий шаг — собрать всё, что необходимо отправить.
Нам не хочется собирать каждое значение отдельно.
- Это может быть долго: если форма состоит из 10 полей, это уже требует достаточно много кода.
- Это не масштабируется: если мы захотим добавить ещё пару полей, нам придётся писать код и для этих полей тоже.
Вместо этого мы будем использовать возможности языка, чтобы достать все поля и элементы управления из формы. Напишем функцию serialize
:
function serializeForm(formNode) { console.log(formNode.elements)}function handleFormSubmit(event) { event.preventDefault() serializeForm(applicantForm)}const applicantForm = document.getElementById('mars-once')applicantForm.addEventListener('submit', handleFormSubmit)
function serializeForm(formNode) {
console.log(formNode.elements)
}
function handleFormSubmit(event) {
event.preventDefault()
serializeForm(applicantForm)
}
const applicantForm = document.getElementById('mars-once')
applicantForm.addEventListener('submit', handleFormSubmit)
Аргумент функции serialize
— это элемент формы. Именно элемент — не селектор, а конкретный узел в DOM-дереве.
У форм есть свойство elements
, которое содержит в себе все элементы управления и поля этой формы. Именно этим свойством мы воспользуемся, чтобы получить все данные из формы.
Если сейчас мы вызовем эту функцию, передав туда нашу форму как аргумент, то в консоли появится список всех элементов:
HTMLFormControlsCollection 0 <input type="text" name="name" placeholder="Илон Маск" autofocus> 1 <input type="email" name="email" placeholder="elon@musk.com"> 2 <input type="number" name="age"> 3 <select name="specialization"> 4 <input type="checkbox" name="nasa-experience" value="1"> 5 <input type="file" accept="image/jpeg" name="photo"> 6 <button type="submit">Отправить заявку</button>
Обратите внимание, что тип этого набора элементов — HTML
. Это не массив и, чтобы пройтись циклом по списку элементов, нужно превратить его в массив с помощью вызова Array
.
Нам останется собрать имя и значение каждого из полей. Для начала, выведем имя и значение каждого элемента в консоль:
function serializeForm(formNode) { const { elements } = formNode Array.from(elements) .forEach((element) => { const { name, value } = element console.log({ name, value }) })}
function serializeForm(formNode) {
const { elements } = formNode
Array.from(elements)
.forEach((element) => {
const { name, value } = element
console.log({ name, value })
})
}
Мы получили список элементов, преобразовали его в массив и прошлись по каждому элементу. У каждого элемента получили поля name
и value
и вывели их в консоль.
В консоли после запуска получим вывод по каждому из полей:
1 {name: 'name', value: 'Alex'} 2 {name: 'email', value: 'some@mail.com'} 3 {name: 'age', value: '24'} 4 {name: 'specialization', value: 'engineer'} 5 {name: 'nasa-experience', value: '1'} 6 {name: 'photo', value: 'C:\\fakepath\\image.jpg'} 7 {name: '', value: ''}
Заметим, что последняя строчка не имеет ни названия, ни значения. Это потому, что последний элемент, который мы проверяли — это кнопка.
Чтобы элементы без названия нам не мешались, мы отфильтруем наш набор. Воспользуемся методом filter
, чтобы отбросить элементы с пустым именем. Также заменим метод for
на map
— он соберёт нам массив, который хранит объект с именем и значением каждого отфильтрованного элемента.
function serializeForm(formNode) { const { elements } = formNode const data = Array.from(elements) .filter((item) => !!item.name) .map((element) => { const { name, value } = element return { name, value } }) console.log(data)}
function serializeForm(formNode) {
const { elements } = formNode
const data = Array.from(elements)
.filter((item) => !!item.name)
.map((element) => {
const { name, value } = element
return { name, value }
})
console.
log(data)
}
На выходе в консоли получится массив из объектов с name
и value
:
[ {name: 'name', value: 'Alex'}, {name: 'email', value: 'some@mail.com'}, {name: 'age', value: '24'}, {name: 'specialization', value: 'engineer'}, {name: 'nasa-experience', value: '1'}, {name: 'photo', value: 'C:\\fakepath\\image.jpg'}]
[
{name: 'name', value: 'Alex'},
{name: 'email', value: 'some@mail.com'},
{name: 'age', value: '24'},
{name: 'specialization', value: 'engineer'},
{name: 'nasa-experience', value: '1'},
{name: 'photo', value: 'C:\\fakepath\\image.jpg'}
]
Значения чекбоксов
Секция статьи «Значения чекбоксов»Сейчас можно заметить, что nasa
имеет значение "1"
. Это неправильно:
- мы не отмечали чекбокс, а значение почему-то
"1"
; - в целом хотелось бы, чтобы значение этого поля было булевым.
Для этого мы можем использовать особое свойство checked
, которое есть у чекбоксов.
const isOn = someCheckboxInput.checked
const isOn = someCheckboxInput.checked
Значение этого поля как раз булево, и мы можем использовать это в нашей функции serialize
.
Но это свойство мы хотим использовать только на чекбоксе, а не на остальных полях. Это тоже можно сделать. Прочитаем тип элемента и, если он "checkbox"
, то возьмём в качестве значения поле checked
:
function serializeForm(formNode) { const { elements } = formNode const data = Array.from(elements) .map((element) => { const { name, type } = element const value = type === 'checkbox' ? element.checked : element.value return { name, value } }) .filter((item) => !!item.name) console.log(data)}
function serializeForm(formNode) {
const { elements } = formNode
const data = Array.from(elements)
.map((element) => {
const { name, type } = element
const value = type === 'checkbox' ? element.
checked : element.value
return { name, value }
})
.filter((item) => !!item.name)
console.log(data)
}
Теперь значение поля nasa
будет true
, если чекбокс отмечен, и false
, если пропущен. Увидим такой вывод:
[ {name: 'name', value: 'Alex'}, {name: 'email', value: 'some@mail.com'}, {name: 'age', value: '24'}, {name: 'specialization', value: 'engineer'}, {name: 'nasa-experience', value: false}, {name: 'photo', value: 'C:\\fakepath\\image.jpg'}]
[
{name: 'name', value: 'Alex'},
{name: 'email', value: 'some@mail.com'},
{name: 'age', value: '24'},
{name: 'specialization', value: 'engineer'},
{name: 'nasa-experience', value: false},
{name: 'photo', value: 'C:\\fakepath\\image.jpg'}
]
Формат данных
Секция статьи «Формат данных»В целом, нынешний формат данных в виде массива объектов нам может и подойти, но мы с вами используем кое-что лучше — Form
.
Form
— это особый тип данных, который можно использовать для отправки данных формы на сервер.
Мы воспользуемся им, чтобы сохранить данные из формы. Создадим экземпляр с помощью new
, откажемся от массива со значениями и будем добавлять имена полей и их значения в Form
с помощью вызова функции append
:
function serializeForm(formNode) { const { elements } = formNode const data = new FormData() Array.from(elements) .filter((item) => !!item.name) .forEach((element) => { const { name, type } = element const value = type === 'checkbox' ? element.checked : element.value data.append(name, value) }) return data}
function serializeForm(formNode) {
const { elements } = formNode
const data = new FormData()
Array.from(elements)
.filter((item) => !!item.name)
.forEach((element) => {
const { name, type } = element
const value = type === 'checkbox' ? element.
checked : element.value
data.append(name, value)
})
return data
}
Но так как тип Form
специально создан для работы с формами, можно сделать гораздо проще 🙂
function serializeForm(formNode) { return new FormData(formNode)}
function serializeForm(formNode) {
return new FormData(formNode)
}
Стоит отметить, что nasa
в таком случае попадёт в финальные данные, только если чекбокс отметили. Если его не отметить, то в финальных данных он не окажется.
Когда чекбокс nasa
выделен, получим такой вывод:
[ ['name', 'Alex'], ['email', 'example@test.com'], ['age', '24'], ['specialization', 'engineer'], ['nasa-experience', '1'], ['photo', File],]
[
['name', 'Alex'],
['email', 'example@test.com'],
['age', '24'],
['specialization', 'engineer'],
['nasa-experience', '1'],
['photo', File],
]
Когда чекбокс не выделен — такой:
[ ['name', 'Alex'], ['email', 'example@test.com'], ['age', '24'], ['specialization', 'engineer'], ['photo', File],]
[ ['name', 'Alex'], ['email', 'example@test.com'], ['age', '24'], ['specialization', 'engineer'], ['photo', File], ]
В первом случае чекбокс был отмечен, поэтому в списке есть элемент nasa
, во втором случае чекбокс был пропущен, поэтому такого элемента в списке данных нет.
Чтобы проверить, какие данные в себе содержит переменная типа Form
, можно использовать метод .entries
, он выведет список с данными, как в примере выше.
console.log(Array.from(data.entries()))
console.log(Array.from(data.entries()))
Отправка на сервер
Секция статьи «Отправка на сервер»Теперь нам надо данные из формы отправить на сервер. Представим, что наш бэкенд предоставляет API-эндпоинт для сохранения данных. Попробуем отправить их.
Функция будет асинхронной, потому что работает с сетевыми запросами. В качестве аргумента она принимает Form
и отправляет запрос с помощью вызова fetch
. Нам нужно указать правильный заголовок Content
у запроса, для формы он 'multipart
:
async function sendData(data) { return await fetch('/api/apply/', { method: 'POST', headers: { 'Content-Type': 'multipart/form-data' }, body: data, })}
async function sendData(data) {
return await fetch('/api/apply/', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
body: data,
})
}
Функция вернёт результат запроса к серверу, который мы сможем проверить на ошибки.
Теперь используем эту функцию в обработчике события отправки. Сериализуем форму и передадим её в функцию отправки. Вместо обращения напрямую к форме, будем читать её из объекта события. Форма в объекте события
submit
будет храниться в свойстве target
:
async function handleFormSubmit(event) { event.preventDefault() const data = serializeForm(event.target) const response = await sendData(data)}
async function handleFormSubmit(event) {
event.preventDefault()
const data = serializeForm(event.target)
const response = await sendData(data)
}
Обратите внимание, что функция handle
стала асинхронной, так как она вызывает другую асинхронную функцию и дожидается её результата. Внутри response
будет поле status
, по которому мы сможем определить, успешно ли прошёл запрос и вывести соответствующее сообщение пользователю.
Обработка загрузки и вывод сообщения о результате
Секция статьи «Обработка загрузки и вывод сообщения о результате»Теперь немножко улучшим UX нашей формы. Сейчас она просто отправляет данные и ничего не сообщает пользователям. Это не круто, потому что отправителю будет непонятно, получилось ли записаться в «Mars Once» или нет.
Мы хотим:
- при отправке формы показывать лоадер, пока идёт запрос;
- при успешной отправке показать сообщение, что форма отправлена, и спрятать форму;
- при ошибке указать пользователю, где именно была ошибка.
Начнём с лоадера.
Показываем лоадер во время отправки
Секция статьи «Показываем лоадер во время отправки»У нас вместо лоадера будет просто показываться строка «Sending…»
Добавим его после кнопки и спрячем:
<style> .hidden { display:none; }</style><form action="/apply/" method="POST"> <!-- Код остальной формы --> <button type="submit">Отправить заявку</button> <div>Отправляем...</div></form>
<style>
.hidden {
display:none;
}
</style>
<form action="/apply/" method="POST">
<!-- Код остальной формы -->
<button type="submit">Отправить заявку</button>
<div>Отправляем.
..</div>
</form>
Прячем мы его, потому что хотим показать только во время запроса. Для этого напишем функцию, которые будут управлять его состоянием — делать лоадер видимым, если он не виден сейчас, и скрывать, если он виден. Так как технически это добавление и удаление класса hidden
, то можно воспользоваться функцией toggle
из class
API:
function toggleLoader() { const loader = document.getElementById('loader') loader.classList.toggle('hidden')}
function toggleLoader() {
const loader = document.getElementById('loader')
loader.classList.toggle('hidden')
}
Вызовем эту функцию до отправки запроса, чтобы показать лоадер, и после запроса, чтобы скрыть. Лоадер будет виден до тех пор, пока запрос не завершится:
async function handleFormSubmit(event) { event.preventDefault() const data = serializeForm(event.target) toggleLoader() const response = await sendData(data) toggleLoader()}
async function handleFormSubmit(event) {
event.
preventDefault()
const data = serializeForm(event.target)
toggleLoader()
const response = await sendData(data)
toggleLoader()
}
Обрабатываем успешную отправку
Секция статьи «Обрабатываем успешную отправку»Давайте теперь проверять ответ сервера. Допустим, нам хочется, чтобы при успешной отправке мы показывали alert
с сообщением об успешной отправке и прятали форму:
function onSuccess(formNode) { alert('Ваша заявка отправлена!') formNode.classList.toggle('hidden')}
function onSuccess(formNode) {
alert('Ваша заявка отправлена!')
formNode.classList.toggle('hidden')
}
Мы должны вызвать on
, только если форма была отправлена успешна. Для этого добавим проверку на статус ответа сервера — он должен быть 200 в случае успеха (статусы ответа разобраны в статье про HTTP протокол):
// Вызовем её вот так:async function handleFormSubmit(event) { event.preventDefault() const data = serializeForm(event.target) toggleLoader() const { status } = await sendData(data) toggleLoader() if (status === 200) { onSuccess(event.target) }}
// Вызовем её вот так: async function handleFormSubmit(event) { event.preventDefault() const data = serializeForm(event.target) toggleLoader() const { status } = await sendData(data) toggleLoader() if (status === 200) { onSuccess(event.target) } }
При успешной отправке покажется это сообщение, а форма пропадёт.
Обрабатываем ошибки
Секция статьи «Обрабатываем ошибки»Если что-то пошло не так, то мы хотим сказать пользователям об этом. Напишем функцию, которая будет вызывать alert
с сообщением, которое пришлёт сервер в случае ошибки:
function onError(error) { alert(error.message)}
function onError(error) {
alert(error.message)
}
Мы могли бы вызвать alert
сразу на месте, но лучше вынести обработку ошибки в отдельную функцию. Так, если нам захочется добавить какие-то действия по обработке ошибок, нам будет проще ориентироваться в коде.
Вместе со статусом будем получать информацию об ошибке из поля error
. Если запрос был успешным, то error
будет пустым, но в случае ошибки там будет лежать сообщение:
async function handleFormSubmit(event) { event.preventDefault() const data = serializeForm(event.target) toggleLoader() const { status, error } = await sendData(data) toggleLoader() if (status === 200) { onSuccess(event.target) } else { onError(error) }}
async function handleFormSubmit(event) {
event.preventDefault()
const data = serializeForm(event.target)
toggleLoader()
const { status, error } = await sendData(data)
toggleLoader()
if (status === 200) {
onSuccess(event.target)
} else {
onError(error)
}
}
Если что-то пошло не так, мы увидим причину. Форма останется на месте.
Блокируем кнопку отправки на невалидной форме
Секция статьи «Блокируем кнопку отправки на невалидной форме»Сейчас кнопку отправки можно нажать в любой момент, даже если форма невалидна. И хоть пользователь не сможет отправить форму из-за HTML-валидации, было бы неплохо предупредить, что кнопку нажимать пока рано.
Давайте будем её блокировать до тех пор, пока не будут заполнены все поля, которые требуется заполнить.
Напишем функцию, которая будет проверять валидность формы и блокировать кнопку, если требуется. Аргументом она будет принимать событие ввода с клавиатуры на полях ввода.
Так как событие ввода будет происходить на полях, а не на самой форме, то значение event
— это поле. Чтобы получить форму, воспользуемся свойством form
, значением которого является ссылка на родительскую форму.
Проверять валидность формы будем с помощью метода check
формы. Он запускает стандартные проверки. Результат проверки будем использовать, для того чтобы установить свойство disabled
кнопки в значение true
, если нужно заблокировать, и false
, если кнопка должна быть доступна.
function checkValidity(event) { const formNode = event.target.form const isValid = formNode.checkValidity() formNode.querySelector('button').disabled = !isValid}applicantForm.addEventListener('input', checkValidity)
function checkValidity(event) {
const formNode = event.target.form
const isValid = formNode.checkValidity()
formNode.querySelector('button').disabled = !isValid
}
applicantForm.addEventListener('input', checkValidity)
Теперь, пока форма не будет заполнена, кнопка будет заблокирована.
Что у нас получилось
Секция статьи «Что у нас получилось»Мы сделали форму, которая отправляет данные без перезагрузки страницы, показывает сообщение об ошибке или успешной отправке и блокирует кнопку, пока не введены значения.
Для всего этого мы использовали методы HTML-элементов и элементов форм, которые нам предоставляет браузер и веб-платформа.
Конечно, этим работа с формами не заканчивается. Ещё можно сделать валидацию каждого поля в отдельности, загрузку картинок с возможностью их редактирования, добавить всякие комбо-боксы и нестандартные элементы.
Но для первой формы, с которой мы работали в JS, этого достаточно 🙂
Хелперы форм в Action View
Формы в веб-приложениях — это основной интерфейс для пользовательского ввода. Однако, разметка форм может быстро стать нудной в написании и поддержке из-за необходимости обрабатывать имена элементов управления формы и их бесчисленные атрибуты. Rails устраняет эту сложность, предоставляя хелперы вью для генерации разметки форм. Однако, поскольку эти хелперы имеют разные принципы использования, разработчикам нужно знать различия между похожими методами хелперов, прежде чем начать их использовать.
После прочтения этого руководства, вы узнаете:
- Как создавать формы поиска и подобного рода формы, не представляющие определенную модель вашего приложения
- Как сделать модельно-ориентированные формы для создания и редактирования определенных записей базы данных
- Как сгенерировать списки выбора (select box) с различными типами данных
- Какие хелперы даты и времени предоставляет Rails
- В чем особенность формы загрузки файлов
- Как отправлять формы на внешние ресурсы и указывать настройку
authenticity_token
. - Как создавать сложные формы
Это руководство не является подробной документацией по доступным хелперам форм и их аргументам. Для получения полной информации, обратитесь к документации по Rails API.
1. Разбираемся с простыми формами
Главный хелпер форм — это form_with
.
<%= form_with do |form| %> Содержимое формы <% end %>
При подобном вызове без аргументов, он создает тег формы, который при отправке сформирует POST-запрос на текущую страницу. Например, предположим текущая страница является домашней, тогда сгенерированный HTML будет выглядеть следующим образом (некоторые разрывы строчек добавлены для читаемости):
<form accept-charset="UTF-8" action="/" method="post"> <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" /> Содержимое формы </form>
Можно увидеть, что HTML содержит элемент input
с типом hidden
. Этот
input
важен, поскольку без него формы, у которых action не «GET», не могут быть успешно отправлены. Скрытый элемент input с именем authenticity_token
является особенностью безопасности Rails, называемой защитой от межсайтовой подделки запроса, и хелперы форм генерируют его для каждой формы, у которых action не «GET» (при условии, что эта особенность безопасности включена). Подробнее об этом можно прочитать в руководстве Безопасность приложений на Rails.
1.1. Характерная форма поиска
Одной из наиболее простых форм, встречающихся в вебе, является форма поиска. Эта форма содержит:
- элемент формы с методом «GET»,
- метку для поля ввода,
- элемент поля ввода текста и
- элемент отправки.
Чтобы создать эту форму, используем form_with
и объект построителя формы, который он вкладывает. Как тут:
<%= form_with url: "/search", method: :get do |form| %> <%= form.label :query, "Search for:" %> <%= form.text_field :query %> <%= form.submit "Search" %> <% end %>
Это сгенерирует следующий HTML:
<form action="/search" method="get" accept-charset="UTF-8" > <label for="query">Search for:</label> <input name="query" type="text" /> <input name="commit" type="submit" value="Search" data-disable-with="Search" /> </form>
Передача url: my_specified_path
в form_with
сообщает форме, куда осуществлять запрос. Однако, как объясняется ниже, в форму также можно передавать объекты ActiveRecord.
Для каждого поля ввода формы генерируется атрибут ID из его имени ("query"
в примере). Эти ID могут быть очень полезны для стилизации CSS или управления элементами форм с помощью JavaScript.
Используйте «GET» как метод для форм поиска. Это позволяет пользователям добавлять в закладки определенный поиск и потом возвращаться к нему. В более общем смысле Rails призывает вас использовать правильный метод HTTP для экшна.
1.2. Хелперы для генерации элементов формы
Объект построителя формы, вкладываемый form_with
, предоставляет ряд вспомогательных методов для генерации элементов формы, таких как чекбоксы, текстовые поля, радиокнопки и так далее. Первый параметр у них это всегда имя поля ввода. Когда форма будет отправлена, имя будет передано вместе с данными формы, и, в свою очередь, помещено в params
в контроллере со значением, введенным пользователем для этого поля. Например, если форма содержит <%= form.text_field :query %>
, то значение этого поля можно получить в контроллере с помощью params[:query]
.
При именовании полей ввода Rails использует определенные соглашения, делающие возможным отправлять параметры с нескалярными величинами, такими как массивы и хэши, которые также будут доступны в params
. Подробнее об этом можно прочесть в разделе про именование параметров. Для подробностей по точному использованию этих хелперов, обратитесь к документации по API.
1.2.1. Чекбоксы
Чекбоксы — это элементы управления формой, которые дают пользователю ряд опций, которые он может включить или выключить:
<%= form.check_box :pet_dog %> <%= form.label :pet_dog, "I own a dog" %> <%= form.check_box :pet_cat %> <%= form.label :pet_cat, "I own a cat" %>
Это сгенерирует следующее:
<input type="checkbox" name="pet_dog" value="1" /> <label for="pet_dog">I own a dog</label> <input type="checkbox" name="pet_cat" value="1" /> <label for="pet_cat">I own a cat</label>
Первый параметр у check_box
— это имя поля ввода. Значения чекбокса (значения, которые появятся params
) могут быть опционально указаны с помощью третьего и четвертого параметра. Подробности смотрите в документации API.
1.2.2. Радиокнопки
Радиокнопки, чем-то похожие на чекбоксы, являются элементами управления, которые определяют набор взаимоисключающих опций (т. е. пользователь может выбрать только одну):
<%= form.radio_button :age, "child" %> <%= form.label :age_child, "I am younger than 21" %> <%= form.radio_button :age, "adult" %> <%= form.label :age_adult, "I am over 21" %>
Результат:
<input type="radio" name="age" value="child" /> <label for="age_child">I am younger than 21</label> <input type="radio" name="age" value="adult" /> <label for="age_adult">I am over 21</label>
Второй параметр для radio_button
— это значение поля ввода. Так как эти две радиокнопки имеют одинаковое имя (age
), пользователь может выбрать одну, и params[:age]
будет содержать или "child"
, или "adult"
.
Всегда используйте метки (labels) для чекбоксов и радиокнопок. Они связывают текст с определенной опцией и, предоставляя большее пространство для клика, упрощают выбор пользователем нужного пункта радиокнопки.
1.3. Другие интересные хелперы
Среди других элементов управления формой стоит упомянуть текстовые области и следующие поля: паролей, числовые, даты и времени, и так далее:
<%= form.text_area :message, size: "70x5" %> <%= form.hidden_field :parent_id, value: "foo" %> <%= form.password_field :password %> <%= form.number_field :price, in: 1.0..20.0, step: 0.5 %> <%= form.range_field :discount, in: 1..100 %> <%= form.date_field :born_on %> <%= form.time_field :started_at %> <%= form.datetime_local_field :graduation_day %> <%= form.month_field :birthday_month %> <%= form.week_field :birthday_week %> <%= form.search_field :name %> <%= form.email_field :address %> <%= form.telephone_field :phone %> <%= form.url_field :homepage %> <%= form.color_field :favorite_color %>
Результат:
<textarea name="message" cols="70" rows="5"></textarea> <input type="hidden" name="parent_id" value="foo" /> <input type="password" name="password" /> <input type="number" name="price" step="0.5" min="1.0" max="20.0" /> <input type="range" name="discount" min="1" max="100" /> <input type="date" name="born_on" /> <input type="time" name="started_at" /> <input type="datetime-local" name="graduation_day" /> <input type="month" name="birthday_month" /> <input type="week" name="birthday_week" /> <input type="search" name="name" /> <input type="email" name="address" /> <input type="tel" name="phone" /> <input type="url" name="homepage" /> <input type="color" name="favorite_color" value="#000000" />
Скрытые поля не отображаются пользователю, вместо этого они содержат данные, как и любое текстовое поле. Их значения могут быть изменены с помощью JavaScript.
Поля поиска, ввода телефона, даты, времени, цвета, даты-времени, локальных даты-времени, месяца, недели, url, email, числовые и интервалов — это элементы управления HTML5. Если необходимо, чтобы у вашего приложения была совместимость со старыми браузерами, вам необходим HTML5 polyfill (предоставляемый с помощью CSS и/или JavaScript). Хотя в таких решениях нет недостатка, популярным инструментом на сегодняшний момент является Modernizr, предоставляющий простой способ добавить функциональность, основанной на обнаружении установленных особенностей HTML5.
Если используются поля для ввода пароля (для любых целей), вы можете настроить свое приложение для предотвращения появления их значений в логах приложения. Это можно изучить в руководстве Безопасность приложений на Rails.
2. Работаем с объектами модели
2.1. Привязывание формы к объекту
Аргумент :model
в form_with
позволяет связать объект построителя формы с объектом модели. Это означает, что эта форма будет будет ограничена этим объектом модели, и поля формы будут предзаполнены значениями из этого объекта модели.
К примеру, если у нас есть такой объект модели @article
:
@article = Article.find(42) # => #<Article id: 42, title: "My Title", body: "My Body">
Следующая форма:
<%= form_with model: @article do |form| %> <%= form.text_field :title %> <%= form.text_area :body, size: "60x10" %> <%= form.submit %> <% end %>
Выведет:
<form action="/articles/42" method="post" accept-charset="UTF-8" > <input name="authenticity_token" type="hidden" value="..." /> <input type="text" name="article[title]" value="My Title" /> <textarea name="article[body]" cols="60" rows="10"> My Body </textarea> <input type="submit" name="commit" value="Update Article" data-disable-with="Update Article"> </form>
Тут нужно отметить несколько вещей:
action
формы автоматически заполняется подходящим значением для@article
.- Поля формы автоматически заполняются соответствующими значениями из
@article
. - Имена полей формы ограничиваются с помощью
article[...]
. Это означает, чтоparams[:article]
будет хэшем, содержащим все значения этих полей. Подробнее о значении имен полей ввода можно прочитать в разделе про именование параметров этого руководства. - Кнопке отправки автоматически присвоено подходящее текстовое значение.
По соглашению, поля ввода будут отражать атрибуты модели. Однако, это необязательно! Если имеется иная необходимая информация, ее можно включить в форму, также как атрибут, и она будет доступна как params[:article][:my_nifty_non_attribute_input]
.
2.1.1. Хелпер
fields_for
Хелпер fields_for
создает подобное привязывание без фактического создания тега <form>
. Он может быть использован для рендера полей ввода для дополнительных объектов модели в той же форме. Например, если имеется модель Person
со связанной моделью ContactDetail
, можно создать форму для создания обеих моделей подобным образом:
<%= form_with model: @person do |person_form| %> <%= person_form.text_field :name %> <%= fields_for :contact_detail, @person.contact_detail do |contact_detail_form| %> <%= contact_detail_form.text_field :phone_number %> <% end %> <% end %>
Которая выдаст такой результат:
<form action="/people" accept-charset="UTF-8" method="post"> <input type="hidden" name="authenticity_token" value="bL13x72pldyDD8bgtkjKQakJCpd4A8JdXGbfksxBDHdf1uC0kCMqe2tvVdUYfidJt0fj3ihC4NxiVHv8GVYxJA==" /> <input type="text" name="person[name]" /> <input type="text" name="contact_detail[phone_number]" /> </form>
Объект, предоставляемый fields_for
— это form builder, подобный тому, который предоставляется form_with
.
2.2. Положитесь на идентификацию записи
Модель Article непосредственно доступна пользователям приложения, и таким образом, следуя лучшим рекомендациям разработки на Rails, вы должны объявить ее как ресурс.
resources :articles
Объявление ресурса имеет несколько побочных эффектов. Смотрите руководство Роутинг в Rails для получения более подробной информации по настройке и использованию ресурсов.
Когда работаем с ресурсами RESTful, вызовы form_with
становятся значительно проще, если они основываются на идентификации записи. Вкратце, вы должны всего лишь передать экземпляр модели и позволить Rails выяснить имя модели и остальное. В обоих примерах, длинный и короткий стили приведет к тому же результату:
## Создание новой статьи # длинный стиль: form_with(model: @article, url: articles_path) # короткий стиль: form_with(model: @article) ## Редактирование существующей статьи # длинный стиль: form_with(model: @article, url: article_path(@article), method: "patch") # короткий стиль: form_with(model: @article)
Отметьте, что вызов короткого стиля form_with
является идентичным, независимо от того, запись новая или уже существует. Идентификация записи достаточно сообразительная, чтобы выяснить, новая ли запись, запрашивая record.persisted?
. Она также выбирает правильный путь для подтверждения и имя, основанное на классе объекта.
Если у вас одиночный ресурс, нужно вызвать resource
и resolve
для работы с form_with
:
resource :geocoder resolve('Geocoder') { [:geocoder] }
Когда используется STI (наследование с единой таблицей) с вашими моделями, нельзя полагаться на идентификацию записей подкласса, если только их родительский класс определен ресурсом. Необходимо явно указывать :url
и :scope
(имя модели).
2.2.1. Работаем с пространствами имен
Если создать пространство имен для маршрутов, form_with
также можно изящно сократить. Если в приложении есть пространство имен admin, то
form_with model: [:admin, @article]
создаст форму, которая передается ArticlesController
в пространстве имен admin (передача в admin_article_path(@article)
в случае с обновлением). Если у вас несколько уровней пространства имен, тогда синтаксис подобный:
form_with model: [:admin, :management, @article]
Более подробно о системе маршрутизации Rails и связанным соглашениям смотрите руководство Роутинг в Rails.
2.3. Как формы работают с методами PATCH, PUT или DELETE?
Фреймворк Rails поддерживает стиль RESTful в ваших приложениях, что подразумевает частое использование запросов «PATCH», «PUT» и «DELETE» (помимо «GET» и «POST»). Однако, большинство браузеров не поддерживают методы, отличные от «GET» и «POST», когда дело доходит до подтверждения форм.
Rails работает с этой проблемой, эмулируя другие методы с помощью POST со скрытым полем, названным "_method"
, который установлен для отображения желаемого метода:
form_with(url: search_path, method: "patch")
Результат:
<form accept-charset="UTF-8" action="/search" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" /> <!-- ... --> </form>
При парсинге данных, отправленных с помощью POST, Rails принимает во внимание специальный параметр _method
и ведет себя так, как будто бы в нем был определен этот метод HTTP («PATCH» в этом примере).
При рендере формы кнопки отправки могут переопределять атрибут method
с помощью ключевого слова formmethod:
:
<%= form_with url: "/posts/1", method: :patch do |form| %> <%= form.button "Delete", formmethod: :delete, data: { confirm: "Are you sure?" } %> <%= form.button "Update" %> <% end %>
Как и для элементов <form>
, многие браузеры не поддерживают переопределение методов формы, объявленные с помощью formmethod, отличные от «GET» и «POST».
Rails обходит эту проблему, эмулируя остальные методы на основе POST с помощью комбинации атрибутов formmethod, value и name:
<form accept-charset="UTF-8" action="/posts/1" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" /> <!-- ... --> <button type="submit" formmethod="post" name="_method" value="delete" data-confirm="Are you sure?">Delete</button> <button type="submit" name="button">Update</button> </form>
В Rails 6. 0 and 5.2 все формы с использованием
form_with
по умолчанию реализуют remote: true
. Эти формы будут отправлять данные с помощью запроса XHR (Ajax). Чтобы это отключить, добавьте local: true
. Подробности смотрите в руководстве Работа с JavaScript в Rails.
3. Легкое создание списков выбора
Списки выбора в HTML требуют значительного количества разметки — один элемент OPTION
для каждого пункта списка. Поэтому Rails предоставляет вспомогательные методы для облегчения этого бремени.
Например, скажем у нас есть список городов для выбора пользователем. Можно использовать хелпер select
таким образом:
<%= form.select :city, ["Berlin", "Lisbon", "Madrid"] %>
Результат:
<select name="city"> <option value="Berlin">Berlin</option> <option value="Chicago">Chicago</option> <option value="Madrid">Madrid</option> </select>
Можно назначить значения <option>
отличные от их надписи:
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %>
Результат:
<select name="city"> <option value="BE">Berlin</option> <option value="CHI">Chicago</option> <option value="MD">Madrid</option> </select>
Таким образом, пользователь увидит полные имена городов, но params[:city]
будет одним из "BE"
, "CHI"
или "MD"
.
Наконец, можно указать выбор по умолчанию для списка выбора с помощью аргумента :selected
:
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]], selected: "CHI" %>
Результат:
<select name="city"> <option value="BE">Berlin</option> <option value="CHI" selected="selected">Chicago</option> <option value="MD">Madrid</option> </select>
3.1. Группы опций
Иногда нужно улучшить пользовательский опыт, сгруппировав вместе схожие опции. Это можно сделать, передав
Hash
(ли совместимый Array
) в select
:
<%= form.select :city, { "Europe" => [ ["Berlin", "BE"], ["Madrid", "MD"] ], "North America" => [ ["Chicago", "CHI"] ], }, selected: "CHI" %>
Результат:
<select name="city"> <optgroup label="Europe"> <option value="BE">Berlin</option> <option value="MD">Madrid</option> </optgroup> <optgroup label="North America"> <option value="CHI" selected="selected">Chicago</option> </optgroup> </select>
3.2. Списки выбора и объекты модели
Подобно другим элементам формы, список выбора может быть связан с атрибутом модели. Например, если имеется такой объект модели @person
:
@person = Person.new(city: "MD")
Следующая форма:
<%= form_with model: @person do |form| %> <%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %> <% end %>
Выведет подобный список выбора:
<select name="person[city]"> <option value="BE">Berlin</option> <option value="CHI">Chicago</option> <option value="MD" selected="selected">Madrid</option> </select> <% end %>
Отметьте, что подходящая опция была автоматически отмечена selected="selected"
. Так как этот список выбора был привязан к модели, не нужно указывать аргумент :selected
!
3.3. Выбор часового пояса и страны
Для управления поддержкой часовых поясов в Rails, можно спрашивать своих пользователей, в какой зоне они находятся. Это потребует сгенерировать пункты списка из списка предопределенных объектов ActiveSupport::TimeZone
, но можно просто использовать хелпер time_zone_select
, который уже все это содержит:
<%= form.time_zone_select :time_zone %>
В Rails раньше был хелпер country_select
для выбора стран, но сейчас он вынесен во внешний плагин country_select.
4. Использование хелперов даты и времени
Если не хотите использовать поля ввода даты и времени HTML5, Rails предоставляет альтернативные хелперы формы для даты и времени, выводящие обычные списки выбора. Эти хелперы рендерят список выбора на каждый компонент (год, месяц, день и т.д.). Например, если у нас есть такой объект модели @person
:
@person = Person.new(birth_date: Date.new(1995, 12, 21))
Следующая форма:
<%= form_with model: @person do |form| %> <%= form.date_select :birth_date %> <% end %>
Выведет списки выбора наподобие:
<select name="person[birth_date(1i)]"> <option value="1990">1990</option> <option value="1991">1991</option> <option value="1992">1992</option> <option value="1993">1993</option> <option value="1994">1994</option> <option value="1995" selected="selected">1995</option> <option value="1996">1996</option> <option value="1997">1997</option> <option value="1998">1998</option> <option value="1999">1999</option> <option value="2000">2000</option> </select> <select name="person[birth_date(2i)]"> <option value="1">January</option> <option value="2">February</option> <option value="3">March</option> <option value="4">April</option> <option value="5">May</option> <option value="6">June</option> <option value="7">July</option> <option value="8">August</option> <option value="9">September</option> <option value="10">October</option> <option value="11">November</option> <option value="12" selected="selected">December</option> </select> <select name="person[birth_date(3i)]"> <option value="1">1</option> ... <option value="21" selected="selected">21</option> ... <option value="31">31</option> </select>
Отметьте, что при отправке формы не будет одиночного значения в хэше params
. содержащего полную дату. Вместо этого будет несколько значений со специальными именами наподобие "birth_date(1i)"
. Active Record знает, как собрать эти особенно названные значения в полную дату или время, основываясь на объявленном типе атрибута модели. Таким образом, можно просто передать params[:person]
в Person.new
или Person#update
, как будто бы форма использовала единственное поле, представляющее полную дату.
В дополнение к хелперу date_select
, Rails предоставляет time_select
и datetime_select
.
4.1. Списки выбора с отдельными элементами времени
Rails также предоставляет хелперы для рендера списков выбора для отдельных компонентов времени: select_year
, select_month
, select_day
, select_hour
, select_minute
и select_second
. Эти хелперы являются «чистыми» методами, что означает, что они не вызываются на экземпляре построителя формы. Например:
<%= select_year 1999, prefix: "party" %>
Выведет подобный список выбора
<select name="party[year]"> <option value="1994">1994</option> <option value="1995">1995</option> <option value="1996">1996</option> <option value="1997">1997</option> <option value="1998">1998</option> <option value="1999" selected="selected">1999</option> <option value="2000">2000</option> <option value="2001">2001</option> <option value="2002">2002</option> <option value="2003">2003</option> <option value="2004">2004</option> </select>
Для каждого из этих хелперов можно указать объект даты или времени вместо числа в качестве значения по умолчанию, тогда будет извлечен и использован подходящий компонент времени.
5. Выбор из коллекции произвольных объектов
Часто нам нужно создать набор вариантов в форме из коллекции объектов. Например, когда мы хотим, чтобы пользователь выбрал город из нашей базы данных, и у нас есть такая модель City
:
City.order(:name).to_a # => [ # #<City id: 3, name: "Berlin">, # #<City id: 1, name: "Chicago">, # #<City id: 2, name: "Madrid"> # ]
Rails предоставляет хелперы для создания вариантов из коллекции без ее явного перебора. Эти хелперы определяют значение и текстовую надпись для каждого варианта, вызывая определенные методы на каждом объекте коллекции.
5.1. Хелпер
collection_select
Чтобы создать список выбора для наших городов, можно использовать collection_select
:
<%= form.collection_select :city_id, City.order(:name), :id, :name %>
Выведет:
<select name="city_id"> <option value="3">Berlin</option> <option value="1">Chicago</option> <option value="2">Madrid</option> </select>
С помощью collection_select
мы определяем сначала метод значения (:id
в вышеуказанном примере), а затем метод текстовой надписи (:name
в вышеуказанном примере). Это отличается от порядка, используемого при указании вариантов для хелпера
select
, когда сначала идет текстовая надпись, а потом значение.
5.2. Хелпер
collection_radio_buttons
Чтобы создать набор радиокнопок для наших городов, можно использовать collection_radio_buttons
:
<%= form.collection_radio_buttons :city_id, City.order(:name), :id, :name %>
Выведет:
<input type="radio" name="city_id" value="3"> <label for="city_id_3">Berlin</label> <input type="radio" name="city_id" value="1"> <label for="city_id_1">Chicago</label> <input type="radio" name="city_id" value="2"> <label for="city_id_2">Madrid</label>
5.3. Хелпер
collection_check_boxes
Чтобы создать набор чекбоксов для наших городов (который позволяет выбрать более одного), можно использовать collection_check_boxes
:
<%= form.collection_check_boxes :city_id, City.order(:name), :id, :name %>
Выведет:
<input type="checkbox" name="city_id[]" value="3"> <label for="city_id_3">Berlin</label> <input type="checkbox" name="city_id[]" value="1"> <label for="city_id_1">Chicago</label> <input type="checkbox" name="city_id[]" value="2"> <label for="city_id_2">Madrid</label>
6. Загрузка файлов
Частой задачей является загрузка некоторого файла, аватарки или файла CSV, содержащего информацию для обработки. Поля загрузки файлов могут быть отрендерены с помощью хелпера file_field
.
<%= form_with model: @person do |form| %> <%= form.file_field :picture %> <% end %>
Самое важное, это помнить при загрузке файла, что атрибут enctype
формы должен быть установлен как «multipart/form-data». Это будет выполнено автоматически, если используете file_field
внутри form_with
. Также можно установить этот атрибут самому:
<%= form_with url: "/uploads", multipart: true do |form| %> <%= file_field_tag :picture %> <% end %>
Отметьте, что в соответствии с соглашениями form_with
, имена поля в вышеуказанных формах также будут отличаться. То есть, именем поля в первой форме будет
person[picture]
(доступное как params[:person][:picture]
), а именем поля во второй форме будет просто picture
(доступное как params[:picture]
).
6.1. Что имеем загруженным
Объект в хэше params
— это экземпляр ActionDispatch::Http::UploadedFile
. Следующий образец кода сохраняет загруженное содержимое в #{Rails.root}/public/uploads
под тем же именем, что и исходный файл.
def upload uploaded_file = params[:picture] File.open(Rails.root.join('public', 'uploads', uploaded_file.original_filename), 'wb') do |file| file.write(uploaded_file.read) end end
Как только файл был загружен, появляется множество потенциальных задач, начиная от того, где хранить файлы (на диске, Amazon S3 и т.д.), как связать их с моделями, изменить размер файлов изображений и сгенерировать миниатюры. Для помощи с такими задачами разработан Active Storage.
7. Настройка Form Builder
Объект, который передается от form_with
и fields_for
, — это экземпляр ActionView::Helpers::FormBuilder
. Form builder инкапсулирует представление элементов формы для отдельного объекта. Хотя, конечно, можно писать хелперы для своих форм обычным способом, так же как можно объявить подкласс ActionView::Helpers::FormBuilder
и добавить хелперы туда. Например:
<%= form_with model: @person do |form| %> <%= text_field_with_label form, :first_name %> <% end %>
может быть заменено этим
<%= form_with model: @person, builder: LabellingFormBuilder do |form| %> <%= form.text_field :first_name %> <% end %>
через определение класса LabellingFormBuilder
подобным образом:
class LabellingFormBuilder < ActionView::Helpers::FormBuilder def text_field(attribute, options={}) label(attribute) + super end end
Если это используется часто, можно определить хелпер labeled_form_with
который автоматически определяет опцию builder: LabellingFormBuilder
:
def labeled_form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) options.merge! builder: LabellingFormBuilder form_with model: model, scope: scope, url: url, format: format, **options, &block end
Form builder также определяет, что произойдет, если вы сделаете:
<%= render partial: f %>
Если f
— это экземпляр ActionView::Helpers::FormBuilder
, тогда это отрендерит партиал form
, установив объект партиала как form builder. Если у form builder есть класс LabellingFormBuilder
, тогда вместо него будет отрендерен партиал labelling_form
.
8. Понимание соглашений по именованию параметров
Значения из форм могут быть на верхнем уровне хэша params
или вложены в другой хэш. Например, в стандартном экшне create
для модели Person, params[:person]
будет обычно хэшем всех атрибутов для создания персоны. Хэш params
может также содержать массивы, массивы хэшей и тому подобное.
В основном формы HTML не знают о каких-либо структурировании данных, все, что они генерируют — это пары имя-значение, где пары являются обычными строками. Массивы и хэши, которые можно увидеть в своем приложении, — это результат некоторых соглашений по именованию параметров, которые использует Rails.
8.1. Базовые структуры
Две базовые структуры — это массивы и хэши. Хэши отражают синтаксис, используемый для доступа к значению в params
. Например, если форма содержит
<input name="person[name]" type="text" value="Henry"/>
хэш params
будет содержать
{'person' => {'name' => 'Henry'}}
и params[:person][:name]
получит отправленное значение в контроллере.
Хэши могут быть вложены на столько уровней, сколько требуется, например:
<input name="person[address][city]" type="text" value="New York"/>
вернет такой хэш params
{'person' => {'address' => {'city' => 'New York'}}}
Обычно Rails игнорирует дублирующиеся имена параметра. Если имя параметра заканчивается пустым набором квадратных скобок []
, то они будут накоплены в массиве. Если нужно, чтобы пользователи могли оставить несколько телефонных номеров, можно поместить это в форму:
<input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/>
Что приведет к тому, что params[:person][:phone_number]
будет массивом, содержащим введенные телефонные номера.
8.2. Комбинируем их
Можно смешивать и сочетать эти две концепции. Один из элементов хэша может быть массивом, как в предыдущем примере, или вы можете иметь массив хэшей. Например, форма может позволить вам создать любое количество адресов, повторяя следующий фрагмент кода
<input name="person[addresses][][line1]" type="text"/> <input name="person[addresses][][line2]" type="text"/> <input name="person[addresses][][city]" type="text"/> <input name="person[addresses][][line1]" type="text"/> <input name="person[addresses][][line2]" type="text"/> <input name="person[addresses][][city]" type="text"/>
Это приведет к тому, что params[:person][:addresses]
будет массивом хэшей с ключами line1
, line2
и city
.
Однако, имеется ограничение, в то время как хэши могут быть вложены произвольно, является допустимым только один уровень «массивности». Массивы обычно могут быть заменены хэшами; например, вместо массива объектов модели можно иметь хэш объектов модели с ключами, равными их id, индексу массива или любому другому параметру.
Параметры массива не очень хорошо работают с хелпером check_box
. В соответствии со спецификацией HTML, невыбранные чекбоксы не возвращают значения. Хелпер check_box
обходит это, создавая вспомогательное скрытое поле с тем же именем. Если чекбокс не нажат, подтверждается только скрытое поле, а если он нажат, то они оба подтверждаются, но значение от чекбокса получает приоритет.
8.3. Опция
:index
хелпера fields_for
Скажем, нам нужно рендерить форму с набором полей ввода для каждого адреса человека. Тут может помочь хелпер fields_for
и его аргумент :index
:
<%= form_with model: @person do |person_form| %> <%= person_form.text_field :name %> <% @person.addresses.each do |address| %> <%= person_form.fields_for address, index: address.id do |address_form| %> <%= address_form.text_field :city %> <% end %> <% end %> <% end %>
Предположим, у кого-то есть два адреса с ID 23 и 45, вышеприведенная форма отрендерит что-то подобное:
<form accept-charset="UTF-8" action="/people/1" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="person[name]" type="text" /> <input name="person[address][23][city]" type="text" /> <input name="person[address][45][city]" type="text" /> </form>
Что приведет к тому, что хэш params
будет выглядеть так
{ "person" => { "name" => "Bob", "address" => { "23" => { "city" => "Paris" }, "45" => { "city" => "London" } } } }
Все поля ввода формы связаны с хэшем "person"
, так как мы вызывали fields_for
на построителе формы person_form
. Указывая опцию
:index
, мы связываем поля ввода адреса с person[address][#{address.id}][city]
вместо person[address][city]
. Таким образом можно определить, какие записи Address должны быть изменены при обработке хэша params
.
Можно передать другие числа или строки с помощью опции :index
. Можно даже передать nil
, что создаст параметр массив.
Чтобы создать более замысловатые вложения, можно явно указать первую часть имени поля ввода (person[address]
в предыдущем примере):
<%= fields_for 'person[address][primary]', address, index: address.id do |address_form| %> <%= address_form.text_field :city %> <% end %>
создаст такие поля ввода:
<input name="person[address][primary][23][city]" type="text" value="Paris" />
Можно также передать опцию :index
прямо в хелперы, такие как text_field
, но обычно будет меньше повторов, если определить это на уровне form builder, а не для отдельных элементах управления input.
Говоря более широко, конечным именем поля ввода будет сцепление имени, переданного в fields_for
/form_with
, значения опции :index
и имени атрибута.
Наконец, как ярлык, вместо указания ID для :index
(например, index: address.id
), можно добавить "[]"
к заданному имени. Например:
<%= fields_for 'person[address][primary][]', address do |address_form| %> <%= address_form.text_field :city %> <% end %>
создаст абсолютно тот же результат, что и наш оригинальный пример.
9. Формы к внешним ресурсам
Хелперы форм Rails можно использовать и для создания форм для передачи данных внешнему ресурсу. Однако, иногда необходимо установить authenticity_token
для ресурса; это можно осуществить, передав параметр authenticity_token: 'your_external_token'
в опциях form_with
:
<%= form_with url: 'http://farfar.away/form', authenticity_token: 'external_token' do %> Form contents <% end %>
Иногда при отправке данных внешнему ресурсу, такому как платежный шлюз, поля, которые можно использовать в форме, ограничены внешним API, и генерация authenticity_token
нежелательна. Чтобы не посылать токен, просто передайте
false
в опцию :authenticity_token
:
<%= form_with url: 'http://farfar.away/form', authenticity_token: false do %> Form contents <% end %>
10. Создание сложных форм
Многие приложения выходят за рамки простых форм, редактирующих одиночные объекты. Например, при создании Person
можно позволить пользователю (в той же самой форме) создать несколько записей адресов (домашний, рабочий и т.д.). При последующем редактировании этого person, пользователю должно быть доступно добавление, удаление или правка адреса, если это необходимо.
10.1. Настройка модели
Active Record предоставляет поддержку на уровне модели с помощью метода accepts_nested_attributes_for
:
class Person < ApplicationRecord has_many :addresses, inverse_of: :person accepts_nested_attributes_for :addresses end class Address < ApplicationRecord belongs_to :person end
Это создаст метод addresses_attributes=
в Person
, позволяющий создавать, обновлять и (опционально) уничтожать адреса.
10.2. Вложенные формы
Следующая форма позволяет пользователю создать Person
и связанные с ним адреса.
<%= form_with model: @person do |form| %> Addresses: <ul> <%= form.fields_for :addresses do |addresses_form| %> <li> <%= addresses_form.label :kind %> <%= addresses_form.text_field :kind %> <%= addresses_form.label :street %> <%= addresses_form.text_field :street %> ... </li> <% end %> </ul> <% end %>
Когда связь принимает вложенные атрибуты, fields_for
рендерит свой блок для каждого элемента связи. В частности, если у person нет адресов, он ничего не рендерит. Обычным паттерном для контроллера является построение одного или более пустых дочерних элементов, чтобы как минимум один набор полей был показан пользователю. Следующий пример покажет 2 набора полей адресов в форме нового person.
def new @person = Person.new 2.times { @person.addresses.build } end
fields_for
вкладывает form builder. Имя параметра будет таким, какое ожидает accepts_nested_attributes_for
. К примеру, при создании пользователя с 2 адресами, отправленные параметры будут выглядеть так
{ 'person' => { 'name' => 'John Doe', 'addresses_attributes' => { '0' => { 'kind' => 'Home', 'street' => '221b Baker Street' }, '1' => { 'kind' => 'Office', 'street' => '31 Spooner Street' } } } }
Фактические значения ключей хэша :addresses_attributes
не важны; однако, они должны быть числовыми строками и различаться для каждого адреса.
Если связанный объект уже сохранен, fields_for
автоматически генерирует скрытое поле с id
сохраненной записи. Это можно отключить, передав include_id: false
в fields_for
.
10.3. Контроллер
Как обычно, в контроллере необходимо объявить разрешенные параметры, перед их передачей в модель:
def create @person = Person.new(person_params) # ... end private def person_params params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street]) end
10.4. Удаление объектов
Можно позволить пользователям удалять связанные объекты, передав allow_destroy: true
в accepts_nested_attributes_for
class Person < ApplicationRecord has_many :addresses accepts_nested_attributes_for :addresses, allow_destroy: true end
Если хэш атрибутов для объекта содержит ключ _destroy
со значением, вычисляющимся как ‘true’ (например, 1, ‘1’, true или ‘true’), тогда объект будет уничтожен. Эта форма позволяет пользователям удалять адреса:
<%= form_with model: @person do |form| %> Addresses: <ul> <%= form.fields_for :addresses do |addresses_form| %> <li> <%= addresses_form.check_box :_destroy %> <%= addresses_form.label :kind %> <%= addresses_form.text_field :kind %> ... </li> <% end %> </ul> <% end %>
Не забудьте обновить список разрешенных параметров в вашем контроллере, а также включить туда поле _destroy
:
def person_params params.require(:person). permit(:name, addresses_attributes: [:id, :kind, :street, :_destroy]) end
10.5. Предотвращение пустых записей
Часто полезно игнорировать наборы полей, которые пользователь не заполнял. Этим можно управлять, передав :reject_if
proc в accepts_nested_attributes_for
. Этот proc будет вызван для каждого хэша атрибутов, отправляемого формой. Если proc возвращает true
, тогда Active Record не создаст связанный объект для этого хэша. Следующий пример пытается создать адрес, если установлен атрибут kind
.
class Person < ApplicationRecord has_many :addresses accepts_nested_attributes_for :addresses, reject_if: lambda {|attributes| attributes['kind'].blank?} end
Вместо этого для удобства можно передать символ :all_blank
, который создаст proc, который отвергнет записи, когда все атрибуты пустые, за исключением любого значения для _destroy
.
10.6. Добавление полей на лету
Вместо того, чтобы рендерить несколько наборов полей раньше времени, можно добавить их только тогда, когда пользователь нажимает на кнопку ‘Добавить новый адрес’. Rails не предоставляет какой-либо встроенной поддержки для этого. При генерации новых наборов полей следует убедиться, что ключ связанного массива уникальный — наиболее распространенным выбором является текущий JavaScript date (миллисекунды после epoch).
11. Использование хелперов тега без построителя форм
Если нужно отрендерить поля формы вне контекста построителя формы, Rails предоставляет хелперы тега для обычных элементов формы. Например, check_box_tag
:
<%= check_box_tag "accept" %>
Выведет:
<input type="checkbox" name="accept" value="1" />
Обычно у этих хелперов те же имена, что и у их аналогов в построителе форм плюс суффикс _tag
. Полный список смотрите в документации FormTagHelper
API.
12. Использование
form_tag
и form_for
До того, как form_with
был представлен в Rails 5.1, его функционал был разделен между form_tag
и form_for
. Последние сейчас мягко устаревшие. Документация по их использованию находится в старых версиях этого руководства.
Атрибут действия HTML-формы: практическое руководство
Атрибут действия HTML-формы определяет, что должно происходить с данными при отправке формы на веб-страницу. Значение атрибута action должно быть URL-адресом веб-ресурса, который будет обрабатывать содержимое формы.
При создании форм и запросе данных на вашем сайте или веб-приложении вам часто нужно что-то сделать с вашими данными, верно? Здесь в игру вступает атрибут действия формы.
Найдите подходящий учебный лагерь
- Career Karma подберет для вас лучшие технологические учебные курсы
- Доступ к эксклюзивным стипендиям и подготовительным курсам
Выберите свой интерес
Разработка программного обеспеченияДизайнОбработка и анализ данныхАналитика данныхПродажиUX-дизайнКибербезопасностьЦифровой маркетингИмя
Фамилия
Электронная почта
Номер телефона
Продолжая, вы соглашаетесь с нашими Условиями обслуживания и Политикой конфиденциальности, а также соглашаетесь получать предложения и возможности от Career Karma по телефону, текстовым сообщениям и электронной почте.
Вы должны знать основы создания формы в HTML. Вы в основном оборачиваете содержимое формы в элемент
Атрибут действия появляется между нашим открывающим тегом
Ниже приведены атрибуты тега формы:
action=»Ссылка на скрипт обработчика форм» Атрибут action указывает на скрипт на стороне сервера («внутренняя часть»), который обрабатывает отправку формы. Обычно это скрипт (PHP, ASP, Perl). ) или программа CGI.
Дополнительные сведения см. в разделе: Динамическое переключение поля действия HTML-формы
method =get|post (либо GET, либо POST) Проще говоря, если вы используете метод GET, значения отправки формы передаются как часть URL-адреса. Если это POST, информация отправляется на сервер как часть тела данных и не будет отображаться в поле URL-адреса в браузере пользователя. Если вы не укажете метод, по умолчанию будет использоваться GET.
Предположим, что ваша страница обработчика формы представляет собой Perl-скрипт с именем 9.0003 formmail.pl . код формы HTML будет:
Узнайте больше о теге HTML Form здесь и о методах GET и Post здесь.
Элементы ввода формы
В форме могут быть различные типы элементов ввода. Примеры: флажки, переключатели, простые текстовые поля и т. д.
Давайте посмотрим, как создавать элементы ввода для формы.
Однострочное текстовое поле
Однострочное текстовое поле может использоваться для сбора имени, электронной почты, номера телефона и т. д. от посетителей вашего веб-сайта.
Вот код для создания простого текстового поля:
type=»text» атрибут type сообщает браузеру, что должно быть создано однострочное поле ввода текста.
name=»FirstName» дает имя полю. Имя используется для идентификации поля на стороне сервера.
Есть еще несколько атрибутов, которые можно использовать с текстовым полем
value=»значение по умолчанию» Текст, указанный вами в качестве значения, будет отображаться в текстовом поле по умолчанию. Пример:
maxlength=»maxChars» Задает максимальное количество символов, которое пользователь может ввести в это текстовое поле.
Давайте расширим нашу предыдущую HTML-форму несколькими текстовыми полями.
pl" method="post">Имя:
Электронная почта:
В этой форме есть два поля для сбора имени и адреса электронной почты посетителя.
9Теги 0002 предназначены для разбиения входных элементов на две строки.Кнопка отправки
После ввода данных пользователь нажимает кнопку отправки, которая запускает браузер для отправки данных на сервер. Вы можете добавить кнопку отправки в форму, используя тип ввода «отправить».
name =»submit» В форме может быть несколько кнопок отправки. На стороне сервера кнопка отправки, которая была нажата, может быть идентифицирована с помощью атрибута «имя».
value=»Submit» Строка, указанная в атрибуте value, отображается как метка кнопки Submit.
Давайте соберем это вместе, чтобы сделать полную страницу формы:
<голова>Страница формы: образец формы <тело>Пример страницы формы
<метод формы='post' action='' >Имя:
Электронная почта:
Скопируйте этот код в файл HTML и откройте его в своем любимом браузере.
Посмотреть форму в действии: пример учебника HTML-формы
Следующая часть: Учебное пособие по HTML-формам, часть II: Дополнительные элементы ввода
См. также: Как создать форму: Руководство по HTML-форме
См.

- Учебное пособие по HTML-форме, часть II: Дополнительные элементы ввода
- Учебное пособие по HTML-форме, часть III: еще больше элементов ввода
- Учебное пособие по HTML-формам, часть IV: обработка форм на стороне сервера
- Современное повторное введение в AJAX
- Как создать веб-форму и быстро разместить ее в Интернете
- Кнопка JavaScript
- Всплывающее окно JavaScript
- Использование метода window.close
- Использование метода window.open
- Может ли JavaScript отправить форму по электронной почте?
Forms 101: узнайте, как работают HTML-формы
Формы — неотъемлемая часть любого современного веб-сайта. В этой статье мы узнаем, что такое HTML-формы, как они работают и как их можно использовать.
Что такое HTML-формы?
HTML-формы, обычно называемые веб-формами, являются неотъемлемой частью любого современного веб-сайта. Когда вы публикуете сообщения в Twitter, выполняете поиск на Amazon или входите в Facebook, вы видите веб-форму в действии.
Они обеспечивают необходимый уровень взаимодействия между пользователем и веб-сайтом или приложением, с которым он взаимодействует. Это взаимодействие происходит, когда пользователь или клиент отправляет информацию веб-приложению или серверу. Это взаимодействие является примером цикла «запрос-ответ».
Как работают HTML-формы?
Давайте посмотрим, как этот цикл запроса-ответа работает на реальном примере. Форма, которую мы рассмотрим, — это логин Twitter.
Когда мы вводим свое имя пользователя и пароль и нажимаем «Войти», на сервер Twitter отправляется запрос.
Если мы ввели что-то неправильно, сервер вернет ответ, сообщающий нам, что адрес электронной почты или пароль неверны.
Теперь, если мы повторим попытку с правильным именем пользователя и паролем, мы увидим другой ответ от сервера Twitter. Это подписывает нас.
Части HTML-формы
Теперь, когда мы увидели рабочую форму, как мы можем создать свою собственную?
Формы состоят из разных частей, работающих вместе. Думайте о каждой части как о кирпичике Lego. По отдельности они просты, но комбинируя их, можно создавать уникальные проекты.
Эти части называются элементами HTML, и для того, чтобы любая форма работала так, как мы хотим, эти элементы должны использоваться вместе. Чтобы понять, как работают эти части, давайте определим простую форму, а затем посмотрим, что делает каждая строка формы.
Этот пример формы предназначен для подписки по электронной почте, которую вы можете использовать на веб-сайте для увеличения числа подписчиков на рассылку новостей.
Посмотрим на первую и последнюю строчки.
...
HTML-элемент
определяет начало формы. Все между ним и
является частью нашей формы. Затем у нас есть атрибут action
, который указывает, куда на сервере будут отправлены данные нашей формы. Если бы это была рабочая форма, наше действие могло бы содержать логику для сохранения электронной почты в нашей базе данных.
Затем есть атрибут method
, для которого мы установили значение POST
.
... ...
Это элемент HTML
. Он используется для описания ввода, рядом с которым он находится. Мы устанавливаем атрибут для
,
со значением "email-input"
. Затем текст, который отображается пользователю
Электронная почта:
.
Значение атрибута для
должно совпадать с идентификатором id
входного HTML-кода, которому он соответствует.
Давайте посмотрим на это сейчас.
... ...
HTML 9Элемент 0141 используется для создания области, где пользователи могут вводить данные.
Атрибут
type
, который мы здесь используем, — это «email»
. Существует множество различных значений для атрибута типа
.
Мы используем "email"
, потому что это ввод для адресов электронной почты.
Когда форма отправляется, данные в ней отправляются на сервер в формате имя/значение.
Имя
9Атрибут 0141 определяет «имя», под которым введенное значение отправляется на сервер.
Имя для этого ввода —
«адрес электронной почты»
, т. е. адрес электронной почты = «hello@formjelly.com».
Возвращаясь к атрибуту
для
в элементе
, идентификатор
использует то же значение "email-input"
, чтобы связать их.
Ввод с id
из "адрес электронной почты"
связан с <метка>
с атрибутом "для"
"адрес электронной почты"
.
...
...
Нашей форме нужен способ, чтобы пользователи могли отправить ее. Это именно то, что делает этот ввод. Мы используем другой элемент HTML
.
На этот раз атрибут типа
имеет значение «отправить» 9.