Работа с формами — JavaScript — Дока
Кратко
Секция статьи «Кратко»Помимо стандартных средств работы с формами можно использовать JavaScript, чтобы проверять формы на валидность, получать доступ к значениям и отправлять информацию на сервер.
Трюки для работы с формами в JS проще всего показать на примере. В этой статье мы соберём форму заявки на участие в миссии по колонизации Марса. В этой форме мы немножко приправим стандартные HTML-атрибуты динамикой на JS.
Разметка и требования
Секция статьи «Разметка и требования»Наша форма заявки на участие в миссии «Mars Once» будет состоять из шести полей. В форме мы собираем следующие данные:
- Имя, чтобы знать, как обращаться в ответном письме.
- Почту, чтобы знать, куда это письмо слать.
- Возраст — нужны только молодые 🤷♂️
- Специализацию — инженеры и учёные пригодятся для основной работы, а психологи нужны, чтобы команда друг друга не перегрызла за десятилетнюю колонизаторскую миссию.
- Работал ли человек в NASA — это большой плюс.
- Фотография, чтобы использовать в печатных материалах.
<form action="/apply/" method="POST"> <label> Ваше имя: <input type="text" name="name" placeholder="Илон Маск" required autofocus> </label> <label> Почта: <input type="email" name="email" placeholder="[email protected]" 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
на объекте события. В нашем случае событием будет отправка формы —
.
Если наше событие находится в переменной event
, то для предотвращения поведения по умолчанию мы можем вызвать event
.
Чтобы «соединить» форму с нашей будущей собственной отправкой данных, мы напишем функцию, которая будет «слушать» событие отправки и реагировать на него.
Найдём форму на странице, с помощью get
и подпишемся на событие submit
с помощью
. Пока мы не будем отправлять форму, а просто напечатаем в консоль строку «Отправка!» и убедимся, что механизм работает:
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
, и форма не отправится самостоятельно.
Собираем данные из формы
Секция статьи «Собираем данные из формы»Следующий шаг — собрать всё, что необходимо отправить.
Нам не хочется собирать каждое значение отдельно.
- Это может быть долго: если форма состоит из 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="[email protected]"> 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 })
})
}
Мы получили список элементов, преобразовали его в массив и прошлись по каждому элементу. У каждого элемента получили поля
и value
и вывели их в консоль.
В консоли после запуска получим вывод по каждому из полей:
1 {name: 'name', value: 'Alex'} 2 {name: 'email', value: '[email protected]'} 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: '[email protected]'}, {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: '[email protected]'},
{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: '[email protected]'}, {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: '[email protected]'},
{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', '[email protected]'], ['age', '24'], ['specialization', 'engineer'], ['nasa-experience', '1'], ['photo', File],]
[
['name', 'Alex'],
['email', '[email protected]'],
['age', '24'],
['specialization', 'engineer'],
['nasa-experience', '1'],
['photo', File],
]
Когда чекбокс не выделен — такой:
[ ['name', 'Alex'], ['email', 'example@test. com'], ['age', '24'], ['specialization', 'engineer'], ['photo', File],]
[
['name', 'Alex'],
['email', '[email protected]'],
['age', '24'],
['specialization', 'engineer'],
['photo', File],
]
В первом случае чекбокс был отмечен, поэтому в списке есть элемент nasa
, во втором случае чекбокс был пропущен, поэтому такого элемента в списке данных нет.
Чтобы проверить, какие данные в себе содержит переменная типа Form
, можно использовать метод
, он выведет список с данными, как в примере выше.
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, этого достаточно 🙂
HTML формы
Элементы формы такие как: текстовые поля, флажки, переключатели, кнопки и т.д., прописываются в контейнере <form>...</form>
. Чаще всего элементы формы создаются при помощи тега <input>
. При помощи атрибута type
указывается тип элемента.
Рассмотрим следующий код:
<form> <p><label>Введите логин:</label> <input type="text"></p> <p><label>Введите пароль:</label> <input type="password"></p> <p><button>Войти</button></p> </form>
В браузере получим примерно такую форму:
Здесь:
- тег
<form>
– является контейнером для элементов формы, в нем также можно использовать теги для разметки страницы; - тег
<label>
– создает метку для элемента формы; - тег
<input>
– создает элемент формы, при помощи атрибутаtype
указывается какой именно элемент нужно отобразить:<input type="text">
– создает текстовое поле;<input type="password">
– создает поле для ввода пароля. Данный тег не требует закрывающего тега;
- тег
<button>
– создает кнопку.
Текстовая область
При помощи тега <textarea>
мы можем создать текстовую область, в которой пользователь сможет вводить длинные сообщения:
<form> <p><label>Введите ваше сообщение:</label></p> <p><textarea></textarea></p> <p><button>Отправить</button></p> </form>
В браузере получим:
Выпадающий список
Тег <select>
создает на странице список, каждое значение из списка прописывается между тегами <option>...<option>
:
<select> <option>Значение 1</option> <option>Значение 2</option> <option>Значение 3</option> </select>
В данном примере вы можете выбрать только одно значение из списка:
Чтобы была возможность выбрать несколько значений из списка, то используйте атрибут multiple
с таким же значением: <select multiple="multiple">
:
Флажки и переключатели
Чтобы создать на странице флажки, необходимо создать поле с типом checkbox
: <input type="checkbox">
:
<form> <p><label><input type="checkbox">Значение один</label></p> <p><label><input type="checkbox">Значение два</label></p> <p><label><input type="checkbox">Значение три</label></p> </form>
Необязательно эти поля прописывать между тегами <label>. ..</label>
.
Чтобы создать на странице переключатели, необходимо создать поле с типом radio
, и указать атрибут name
с каким-нибудь значением: <input type="radio" name="rad">
.
<form> <p><label><input type="radio" name="rad">Значение один</label></p> <p><label><input type="radio" name="rad">Значение два</label></p> <p><label><input type="radio" name="rad">Значение три</label></p> </form>
Обратите внимание, что значение атрибута name
в группе переключателей должно быть одинаковым, иначе переключатели будут работать как флажки, т.е. можно будет выбрать сразу все.
Если вы хотите по умолчанию сделать выбранным один из пунктов, то используйте атрибут checked
с таким же значением: <input type="radio" name="rad" checked="checked">
. Для флажков соответственно можно указать этот атрибут у нескольких пунктов сразу.
Поле для выбора файла
Используйте тип поля file
, для возможности выбора файла с компьютера: <input type="file">
:
<form> <p><input type="file"></p> <p><button>Отправить</button></p> </form>
Вид в окне браузера:
Другие варианты кнопок
<input type="button" value="Название для кнопки">
– обычная кнопка.<input type="image" src="Путь к картинке">
– кнопка в виде картинки. Через атрибут src указываем путь к картинке.<input type="submit" value="Название для кнопки">
– кнопка для отправки данных формы.<input type="reset" value="Название для кнопки">
– кнопка для очистки формы от введенный в нее данных.
Эти же значения атрибута type
, кроме значения image
, можно применить к кнопке, созданной при помощи тега <button></button>
. В отличие от кнопок, созданных через тег <input>
, эту кнопку можно размещать вне контейнера <form>...</form>
, это не будет считаться ошибкой. Также внутри этой кнопки можно размещать другие строчные теги.
Видео к уроку
Поделиться с друзьями:
Формы и их составляющие (form, input) в HTML
Для создания интерактивного сайта необходим способ передачи данных от пользователя. Самый простой способ передать данные на сайт — это использовать форму (тег <form>).
Материал в этой статье только описывает теги, которые могут содержаться в <form>. Но для программирования функционала необходимо знание языка, к примеру, PHP. Пожалуйста, посмотрите курс PHP, если хотите полноценно понять способ передачи данных на сайт.
Одним из простейших примеров формы может быть форма авторизации:
<form action="/index. php" method="POST"> Пожалуйста, введите мэйл и пароль:<br> <input type="text" name="email" value="" placeholder="Ваш мэйл" required><br> <input type="password" name="password" value="" placeholder="Ваш пароль"><br> <input type="submit" value="Войти на сайт"> </form>
Если создать html файл и вставить в него код из примера выше, то в браузере такой файл отобразится как html страница со следующим содержанием: — в этой форме есть два поля для ввода и одна кнопка. Все эти элементы строятся самим браузером.
Браузер использует свой стандартный стиль для полей ввода и кнопок, если не задан особый стиль. У каждого браузера стили для элементов форм отличаются. Поэтому чтобы сделать единый дизайн формы для вех браузеров, необходимо переопределить стандартные стили. Читайте об этом в курсе по CSS.
Рассмотрим построчно теги из примера.
<form> … </form> — этот тег формы. Внутри него могут находиться различные элементы: текстовые поля, поля для ввода пароля и т.п. Во время отправки формы все поля внутри формы передадут свои значения на страницу, адрес которой указан в атрибуте action=»…». Способ передачи данных указывается в атрибуте method=»…». Подробнее о передаче данных из формы на сайт можно прочитать в разделе по программированию, к примеру, на языке PHP. В этой статье рассмотрим только виды полей для вода информации.
<input> — этот тег может отображать различные элемены в зависимости от значения атрибута type=»…». На третьей строке он используется как поле для ввода текста type=»text». А на четвёртой стройке он используется для ввода пароляtype=»password». Отличие типов «text» от «password» в том, что в поле для ввода пароля все символы скрываются, заменяясь на звёздочки или точки.
В конце стретьей строки есть атрибут required. В переводе означает «обязательный». Если попытаться отправить форму (в нашем случае нажать на кнопку «Войти на сайт») без заполнения этого поля, то форма не отправится и выдаст предупреждение: На пятой строке <input> используется с атрибутом type=»submit». В результате чего браузер рисует кликабельную кнопку, которая запускает процесс отправки содержимого формы.
В атрибуте value=»…» задаётся значение, которое принимает элемент формы. К примеру, если в поле с атрибутом type=»text» задать value=»Это текст в форме», то после загрузки html страницы в этом текстовом поле будет стоять текст «Это текст в форме». В случае с полем type=»submit» значение в атрибуте value=»…» устанавливает надпись на кнопку отправки формы.
В примере все текстовые поля имеют атрибут value=»» (value равно пустоте, между двойными кавычками «» ничего нет). Поэтому на заднем фоне поля для ввода отображается текст-заглушка, которая сразу прячется, как только начинается ввод в поле. Текст этой заглушки можно задать через атрибут placeholder=»…».
Далее разберём подробнее какие ещё типы полей могут быть в формах. Рассмотрим самые востребованные.
input type=»radio»
Поле для ввода с атрибутом type=»radio» помогает сделать переключатель вариантов. К примеру, если пользователь должен выбрать только один вариант из списка, то код формы будет таким:
<form action="/index.php" method="POST">
Выберите сыр:<br>
<input name="cheese" type="radio" value="v1">Чеддер<br>
<input name="cheese" type="radio" value="v2" checked>Блю<br>
<input name="cheese" type="radio" value="v3">Камбоцола<br>
<input name="cheese" type="radio" value="v4">Морбье<br>
<input name="cheese" type="radio" value="v5">Смоленский<br>
<input name="cheese" type="radio" value="v6">Чечил<br>
</form>
На экране негобраузера форма будет выглядеть так: Обратите внимание, что все поля имеют атрибут name=»cheese» с одинаковым значением. Это необходимо, потому что на одной странице могут находится несколько форм с радиокнопками. Но переключатель будет работать только внутри группы радиокнопок с одинаковым значением атрибута name. А значение value=»…» должно быть разным. именно value у выбранного пункта будет передано во время отправки формы.
В примере выше можно заметить, что на втором варианте ответа стоит атрибут checked. Он указывает на то, что во время загрузки страницы второй пункт будет отмечен как выбранный.
input type=»checkbox»
Если есть необходимость выбрать несколько пунктов из предложенных, то необходимо использовать type=»checkbox»:
<form action="/index.php" method="POST">
Выберите сыр:<br>
<input name="cheese" type="checkbox" value="v1">Чеддер<br>
<input name="cheese" type="checkbox" value="v2" checked>Блю<br>
<input name="cheese" type="checkbox" value="v3">Камбоцола<br>
<input name="cheese" type="checkbox" value="v4" checked>Морбье<br>
<input name="cheese" type="checkbox" value="v5" checked>Смоленский<br>
<input name="cheese" type="checkbox" value="v6">Чечил<br>
</form>
Браузер отрисует такие элементы как поля, в которых можно поставить галочку. Как и в случае с type=»radio» можно задать checked для тех пунктов, которые должны быть отмечены по умолчанию после загрузки страницы.
input type=»file»
Одним из самых востребованных типов вода полей является поле для выбора файла type=»file». HTML формы с кнопкой загрузки файла выглядит так:
<form action="/index.php" method="POST">
Загрузите фото сыра:<br><br>
<input type="file"><br><br>
<input type="submit" value="Загрузить">
</form>
В браузере форма из этого примера будет выглядеть так: При клике на кнопку выбора файла откроется окно, где пользователь сможет указать файл для загрузки. Кнопка «Загрузить» (она же <input type=»submit»>) начинает процесс отправки формы вместе с выбранным файлом.
<textarea>
Если необходимо получить от пользователя очень длинный текст, то записывать его через текстовое поле <input type=»text»> будет проблематично, потому что это поле вмещает только одну строку. К счастью, есть более удобное многострочное поле с возможностью изменения его размера. Такое поле создаётся с помощью тега <textarea>. Этот тег парный — он имеет открывающую и закрывающую часть. HTML код формы с этим полем выглядит так:
<form action="/index.php" method="POST">
Напишите стих про мышей:<br><br>
<textarea></textarea>
</form>
Браузер отобрасит поле для ввода текста в несколько строк с возможностью изменения размера за правый-нижний угол: В отличии от других input полей, у textarea нет атрибута value. Значение textarea находится непосредственно между тегами <textarea>…</textarea>. И если необходимо задать текст, который будет в этом поле после загрузки страницы, то нужно писать его именно между открывающимся и закрывающимся тегом <textarea>…</textarea>
— HTML: Язык гипертекстовой разметки
элементы типа submit
отображаются как кнопки. Когда происходит событие click
(обычно из-за того, что пользователь нажал кнопку), пользовательский агент пытается отправить форму на сервер.
Атрибут
элемента value
содержит строку, которая отображается как метка кнопки. В противном случае кнопки не имеют истинного значения.
Установка значения атрибута
Пропуск атрибута значения
Если вы не укажете значение
, кнопка будет иметь метку по умолчанию, выбранную пользовательским агентом. Этот ярлык, скорее всего, будет чем-то вроде «Отправить» или «Отправить запрос». Вот пример кнопки отправки с меткой по умолчанию в вашем браузере:
В дополнение к атрибутам, общим для всех
элемента, кнопки отправки
ввода поддерживают следующие атрибуты.
formaction
Строка, указывающая URL-адрес для отправки данных. Это имеет приоритет над атрибутом action
в элементе , которому принадлежит
.
Этот атрибут также доступен для элементов
и
.
формаcтип
Строка, определяющая метод кодирования, используемый при отправке данных формы на сервер. Есть три допустимых значения:
-
application/x-www-form-urlencoded
Это значение по умолчанию отправляет данные формы в виде строки после URL-адреса, кодирующего текст с использованием такого алгоритма, как
encodeURI()
.-
multipart/form-data
Использует API
FormData
для управления данными, что позволяет отправлять файлы на сервер. Вы должен использовать этот тип кодировки, если ваша форма включает какие-либоfile
(-
текстовый/обычный
Простой текст; в основном полезен только для отладки, поэтому вы можете легко увидеть данные, которые должны быть отправлены.
Если указано, значение атрибута formenctype
переопределяет действие формы-владельца
атрибут.
Этот атрибут также доступен для элементов
и
.
formmethod
Строка, указывающая метод HTTP, используемый при отправке данных формы; это значение переопределяет любой атрибут метода
, указанный в форме владения. Допустимые значения:
-
get
URL-адрес строится, начиная с URL-адреса, заданного формой
действие
атрибут, добавление символа вопросительного знака («?»), затем добавление данных формы, закодированных, как описаноformenctype
или атрибутом формыenctype
. Затем этот URL-адрес отправляется на сервер с помощью запроса HTTPget
. Этот метод хорошо работает для простых форм, содержащих только символы ASCII и не имеющих побочных эффектов. Это значение по умолчанию.-
пост
Данные формы включаются в тело запроса, который отправляется по URL-адресу, заданному
formaction
илиaction
атрибут с использованием метода HTTPpost
. Этот метод поддерживает сложные данные и вложения файлов.-
диалоговое окно
Этот метод используется для указания того, что кнопка закрывает диалог, с которым связан ввод, и вообще не передает данные формы.
Этот атрибут также доступен на
и
элемента.
formnovalidate
Логический атрибут, который, если он присутствует, указывает, что форму не следует проверять перед отправкой на сервер. Это переопределяет значение атрибута novalidate
в форме владения элементом.
Этот атрибут также доступен для элементов
и
.
formtarget
Строка, определяющая имя или ключевое слово, указывающее, где отображать ответ, полученный после отправки формы. Строка должна быть именем контекст просмотра (то есть вкладка, окно или
. Значение, указанное здесь, переопределяет любую цель, заданную атрибутом target
в , которому принадлежит этот ввод.
Кроме того к фактическим именам вкладок, окон или встроенных фреймов можно использовать несколько специальных ключевых слов:
-
_self
Загружает ответ в тот же контекст просмотра, что и тот, который содержит форму. Это заменит текущий документ полученными данными. Это значение по умолчанию, используемое, если оно не указано.
-
_пусто
Загружает ответ в новый безымянный контекст просмотра. Обычно это новая вкладка в том же окне, что и текущий документ, но она может отличаться в зависимости от конфигурации пользовательского агента.
-
_родительский
Загружает ответ в родительский контекст просмотра текущего. Если нет родительского контекста, это ведет себя так же, как
_self
.-
_верх
Загружает ответ в контекст просмотра верхнего уровня; это контекст просмотра, который является самым верхним предком текущего контекста. Если текущий контекст является самым верхним контекстом, это ведет себя так же, как
_self
.
Этот атрибут также доступен для элементов
и
.
кнопки используются для отправки форм. Если вы хотите создать пользовательскую кнопку, а затем настроить ее поведение с помощью JavaScript, вам нужно использовать
или, что еще лучше, элемент
.
Если вы решите использовать элементы
для создания кнопок в форме, имейте в виду: если внутри есть только одна
, эта кнопка будет рассматриваться как кнопка «отправить». Таким образом, вы должны иметь привычку четко указывать, какая кнопка является кнопкой отправки.
Простая кнопка отправки
Начнем с создания формы с простой кнопкой отправки:
<форма> <дел> <тип ввода="текст" имя="текст" />