Формуляри
Накратко: HTML формулярът събира данни в полета с етикети и атрибут name и ги праща с бутон, а required, type, min, max и pattern ги проверяват още в браузъра.
Проблем
Поръчка без данни
Магазинът получава поръчки без име и без телефон. Купувачите се кълнат, че са попълнили всичко. Ето формуляра на поръчката. Попълни го и натисни „Поръчай“.
Конзола
Пясъчникът не праща нищо по мрежата. Вместо това конзолата казва какво щеше да замине: „Формулярът е изпратен: (без полета)“. Всичко написано е останало в страницата. Има и втори знак: клик върху думата „Име“ не слага курсора в полето. На екрана текстът и полето са един до друг, но в дървото нищо не ги свързва.
Идеята
Формулярът, името и етикетът
Формулярът (<form>) събира полета и ги изпраща заедно. action казва накъде (/order), а method казва как (post).
<form action="/order" method="post"> <label for="phone">Телефон</label> <input id="phone" name="phone" type="tel"> <button type="submit">Поръчай</button></form>nameе това, което заминава. При изпращане браузърът прави двойкаname=valueза всяко поле с име:phone=0888123456. Поле безnameне заминава, колкото и да е попълнено. Затова поръчката беше празна.<label>е етикетът на полето. Свързва се сfor, който сочиidна полето. Може и полето да е вътре в етикета:<label>Телефон <input name="phone"></label>. Тогаваforне трябва.
Етикетът дава на полето име в дървото на достъпността. Екранният четец казва „Телефон, поле за редактиране“, а не само „поле за редактиране“. Клик върху етикета фокусира полето, а отметка с етикет се цъка и от текста си. Проверките в задачите намират полето по етикета, както го намира и човек.
id и name често са еднакви, но вършат различна работа. id е за етикета и за CSS, а name е ключът в заявката.
Идеята
Видовете полета
<input> е едно поле, а type казва какво е:
text(по подразбиране),email,tel: текст. На телефонemailиtelотварят клавиатура с@или с цифри.number: число, със стрелки.min="1",max="10"иstep="1"казват границите и стъпката.checkbox: отметка „да или не“. Заминава само ако е отметната:gift=yesотvalue="yes". Безvalueзаминаваgift=on.radio: един избор от няколко. Радио бутоните са група по общоname:name="delivery"и на двата, аvalueказва кой е избран. Заминава само избраният.
Други полета:
<select>с<option>: падащо меню. Заминаваvalueна избраната опция, а безvalueи текстът ѝ.<textarea>: текст на няколко реда, например бележка за куриера.<fieldset>с<legend>: група полета със заглавие. Радио бутоните за доставка са вfieldset, аlegend„Доставка“ е името на групата. Без него екранният четец казва „До офис“, но не и до офис за какво.
Бутонът. <button type="submit"> изпраща формуляра. <button type="button"> не прави нищо сам, а действието му е в JavaScript. Във формуляр <button> без type е submit. Затова винаги пиши type.
Виж го
Цялата поръчка
Формулярът на поръчката с всички видове полета. Попълни го, смени града и доставката и натисни „Поръчай“. Отметни „Опаковай като подарък“ и натисни пак.
Конзола
Виж реда в конзолата. Двойките са в реда на полетата в кода. Градът е plovdiv: заминава value, а не надписът „Пловдив“. От доставката е само избраният бутон. Отметката я няма, докато не е отметната. Празната бележка заминава като note=: празно поле с име пак е поле.
Пробвай
Поправи поръчката
Поправи формуляра от началото така, че поръчката да стига цяла. Текстовете „Име“, „Телефон“ и „Адрес“ стават етикети на полетата си, а полетата получават имена name, phone и address.
Конзола
Решение
index.html<!doctype html>
<html lang="bg">
<head>
<meta charset="utf-8">
<title>Поръчка · Магазинът</title>
</head>
<body>
<h1>Поръчка</h1>
<form action="/order" method="post">
<label for="name">Име</label>
<input id="name" name="name">
<label for="phone">Телефон</label>
<input id="phone" name="phone" type="tel">
<label for="address">Адрес</label>
<input id="address" name="address">
<button type="submit">Поръчай</button>
</form>
</body>
</html>
Всеки <p> става <label for="…">, който сочи id на полето си, а всяко поле получава name. Проверката намира полетата по етикет, пише в тях и чете реда в конзолата: name=Ива Петрова, phone=0888123456, address=ул. Шипка 7. Ако for сочи id, което го няма, етикетът е само текст и полето не се намира.
Пробвай
Намери грешката
Купувачът пише код за отстъпка и натиска „Приложи кода“. Поръчката заминава, преди да е написал имейла си. Кой ред е виновен?
Избери реда с грешката.
<button> на ред 3 е без type, а във формуляр това значи submit. Клик върху него изпраща целия формуляр. Трябва <button type="button">, а кодът за отстъпка се прилага с JavaScript.
Пробвай
Попълни
Кой атрибут на етикета сочи id на полето?
<label ="email">Имейл</label>
<input id="email" name="email" type="email">for: етикетът е „за“ полето с това id. Без него (и без полето вътре в етикета) двете не са свързани.
Идеята
Проверките на браузъра
Поръчка с имейл iva или с количество 0 не трябва да заминава. Браузърът може да провери много неща сам, без ред JavaScript. Правилата са атрибути на полето:
required: полето не може да е празно. При отметка: трябва да е отметната. При радио група: нещо трябва да е избрано.type="email": текстът трябва да прилича на имейл (име@домейн). Празно поле минава, ако нямаrequired.minиmax: границите на число.stepе стъпката: приstep="1"2,5 не минава.minlengthиmaxlength: колко знака най-малко и най-много.pattern: образец за целия текст, като регулярен израз.pattern="0[0-9]{9}"е 0 и още девет цифри.
При натискане на „Поръчай“ браузърът проверява всяко поле. Ако някое не минава, формулярът не се изпраща и събитието submit изобщо не се случва. Браузърът фокусира първото невалидно поле и показва до него съобщение на езика на браузъра. Купувачът поправя, натиска пак, и браузърът проверява отначало.
novalidate на <form> изключва тези проверки. Ползва се, когато страницата проверява и показва грешките със свой код. За това е урокът за формулярите в компонентите.
Виж го
Виж какво става при „Поръчай“
Кодът е кратък формуляр на поръчката. Гледай реда: първо проверката, после събитието, после събирането.
<form action="/order" method="post"> <label>Име <input name="name" required></label> <label>Имейл <input name="email" type="email" required></label> <label>Телефон <input name="phone" pattern="0[0-9]{9}"></label> <label>Брой <input name="qty" type="number" min="1" max="10"></label> <label><input name="gift" type="checkbox"> Подарък</label> <button>Поръчай</button></form>Стъпка по стъпка, с думи
- Купувачът натиска „Поръчай“. <button> е без type, затова във формуляр е бутон за изпращане. Браузърът още не праща нищо.
- Първо проверява всяко поле в реда на кода спрямо правилата му. „iva“ не е имейл, а „12345“ не е по образеца.
- Има невалидни полета, затова събитието submit не се случва. Браузърът фокусира първото невалидно поле и показва съобщение само за него.
- Купувачът поправя имейла и телефона и натиска пак.
- Същата проверка отгоре. Този път всяко поле минава.
- Чак сега идва събитието submit. Ако кодът не го спре, браузърът праща формуляра на адреса от action с метода от method.
- Събира двойка name=value от всяко поле с име. Неотметнатата отметка изобщо не заминава.
- С method="post" двойките заминават в тялото на заявката, свързани с &. Ключът е атрибутът name, а не текстът на етикета.
Браузърът проверява всички полета, но показва съобщение само за първото невалидно. Затова купувачът понякога поправя едно поле и веднага вижда съобщение за следващото. А gift не заминава изобщо: за сървъра неотметнатата отметка и липсващото поле са едно и също.
Пробвай
Сложи проверките
Бързата поръчка на хляба пропуска всичко. Добави проверки: количеството е от 1 до 10, имейлът е задължителен и трябва да е имейл, телефонът е задължителен и е 0 и още девет цифри. Проверката пише 12, празен имейл, „iva“, празен и грешен телефон и очаква браузърът да спре на правилното поле.
Конзола
Решение
index.html<!doctype html>
<html lang="bg">
<head>
<meta charset="utf-8">
<title>Количество · Магазинът</title>
</head>
<body>
<h1>Бърза поръчка: Хляб „Добруджа“, 1,80 €</h1>
<form action="/order" method="post">
<p><label>Количество <input name="qty" type="number" value="1" min="1" max="10"></label></p>
<p><label>Имейл <input name="email" type="email" required></label></p>
<p><label>Телефон <input name="phone" type="tel" required pattern="0[0-9]{9}"></label></p>
<button type="submit">Поръчай</button>
</form>
</body>
</html>
Количеството получава min="1" max="10", имейлът type="email" required, а телефонът required pattern="0[0-9]{9}". Проверката натиска „Поръчай“ след всяка грешка и гледа къде е фокусът: там, където браузърът е спрял. Ако някое правило липсва, формулярът заминава и фокусът не е на полето. Накрая, с верните стойности, конзолата казва qty=2, email=iva@example.com, phone=0888123456.
По-точно, за любопитните
Сървърът проверява пак. Проверката в браузъра е за удобството на купувача: той вижда грешката веднага. Тя не пази магазина. novalidate, панелът Elements или заявка без браузър я заобикалят, затова сървърът проверява всяко поле отново. Защо е така има в урока „Недоверен вход“.
Какво не заминава. Поле без name, неотметната отметка, неизбран радио бутон и поле с disabled. Полето с readonly заминава: то само не се променя. Файловете (type="file") искат method="post" и enctype="multipart/form-data".
Как заминава. С method="get" (по подразбиране) двойките отиват в адреса: /order?name=…&phone=…. С method="post" са в тялото на заявката. И в двата случая са кодирани: @ става %40, а интервалът става +.
Enter. Enter в текстово поле изпраща формуляра, както клик на бутона за изпращане, със същите проверки.
minlength и стойността от кода. minlength проверява само текст, който човек е написал. Стойност от атрибута value или от JavaScript минава, дори да е къса.
Без проверки. formnovalidate на един бутон изпраща без проверка (например „Запази чернова“). form.submit() от JavaScript също не проверява и не пуска събитието submit, а form.requestSubmit() прави всичко като клик.
Стил на грешките. CSS вижда невалидните полета с :invalid, а :user-invalid ги хваща само след като човек ги е пипнал. Така полето не е червено, преди купувачът да е написал нещо. За CSS е следващият модул.
autocomplete. autocomplete="email", "tel", "name", "street-address" казват на браузъра какво да предложи от запомненото. Купувачът попълва поръчката с два клика.
Упражнение
Формулярът на поръчката
Направи формуляра на поръчката от празно, с полетата в този ред. „Име“ (name), задължително. „Имейл“ (email), задължителен имейл. „Телефон“ (phone), задължителен, 0 и още девет цифри. „Град“ (city): падащо меню София, Пловдив, Варна със стойности sofia, plovdiv, varna. Група „Доставка“ с два радио бутона (delivery): „До адреса“ (address), избран отначало, и „До офис“ (office). „Бележка за куриера“ (note), на няколко реда. Отметка „Опаковай като подарък“ (gift) със стойност yes. Бутон „Поръчай“.
Конзола
Решение
index.html<!doctype html>
<html lang="bg">
<head>
<meta charset="utf-8">
<title>Поръчка · Магазинът</title>
</head>
<body>
<h1>Поръчка</h1>
<form action="/order" method="post">
<p><label>Име <input name="name" required></label></p>
<p><label>Имейл <input name="email" type="email" required></label></p>
<p><label>Телефон <input name="phone" type="tel" required pattern="0[0-9]{9}"></label></p>
<p>
<label for="city">Град</label>
<select id="city" name="city">
<option value="sofia">София</option>
<option value="plovdiv">Пловдив</option>
<option value="varna">Варна</option>
</select>
</p>
<fieldset>
<legend>Доставка</legend>
<label><input type="radio" name="delivery" value="address" checked> До адреса</label>
<label><input type="radio" name="delivery" value="office"> До офис</label>
</fieldset>
<p><label>Бележка за куриера <textarea name="note"></textarea></label></p>
<p><label><input type="checkbox" name="gift" value="yes"> Опаковай като подарък</label></p>
<button type="submit">Поръчай</button>
</form>
</body>
</html>
Всяко поле е в свой <label>, затова проверката го намира по текста. Телефонът е type="tel" с required и pattern, а празното име спира първото „Поръчай“. Градът е <select> с value на всяка опция: иначе заминава „Пловдив“, а не plovdiv. Радио бутоните са в <fieldset> с <legend>Доставка</legend>, имат общо name="delivery", а checked избира първия. Бележката е <textarea>. Проверката попълва всичко, избира „До офис“, отмята подаръка и чете реда в конзолата.
Тест
Провери се
Свързани уроци
Раздел „Свързани уроци“- Нужно отпреди: HTML документът · Текст, връзки, картинки, таблици
- Продължава в: Достъпност · Селектори и каскада · Flexbox: ред и колона · DOM: страницата от JavaScript
- Задачи по темата: HTML: структурата на страницата