Към съдържанието
wannacode

Формуляри

Накратко: HTML формулярът събира данни в полета с етикети и атрибут name и ги праща с бутон, а required, type, min, max и pattern ги проверяват още в браузъра.

Проблем

Поръчка без данни

Магазинът получава поръчки без име и без телефон. Купувачите се кълнат, че са попълнили всичко. Ето формуляра на поръчката. Попълни го и натисни „Поръчай“.

HTML, CSS, JS
index.html

Пясъчникът не праща нищо по мрежата. Вместо това конзолата казва какво щеше да замине: „Формулярът е изпратен: (без полета)“. Всичко написано е останало в страницата. Има и втори знак: клик върху думата „Име“ не слага курсора в полето. На екрана текстът и полето са един до друг, но в дървото нищо не ги свързва.

Идеята

Формулярът, името и етикетът

Формулярът (<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.

Виж го

Цялата поръчка

Формулярът на поръчката с всички видове полета. Попълни го, смени града и доставката и натисни „Поръчай“. Отметни „Опаковай като подарък“ и натисни пак.

HTML, CSS, JS
index.html

Виж реда в конзолата. Двойките са в реда на полетата в кода. Градът е plovdiv: заминава value, а не надписът „Пловдив“. От доставката е само избраният бутон. Отметката я няма, докато не е отметната. Празната бележка заминава като note=: празно поле с име пак е поле.

Пробвай

Поправи поръчката

Поправи формуляра от началото така, че поръчката да стига цяла. Текстовете „Име“, „Телефон“ и „Адрес“ стават етикети на полетата си, а полетата получават имена name, phone и address.

HTML, CSS, JS
index.html

Пробвай

Намери грешката

Купувачът пише код за отстъпка и натиска „Приложи кода“. Поръчката заминава, преди да е написал имейла си. Кой ред е виновен?

Избери реда с грешката.

Пробвай

Попълни

Кой атрибут на етикета сочи id на полето?

<label ="email">Имейл</label>
<input id="email" name="email" type="email">

Идеята

Проверките на браузъра

Поръчка с имейл 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>
Стъпка по стъпка, с думи
  1. Купувачът натиска „Поръчай“. <button> е без type, затова във формуляр е бутон за изпращане. Браузърът още не праща нищо.
  2. Първо проверява всяко поле в реда на кода спрямо правилата му. „iva“ не е имейл, а „12345“ не е по образеца.
  3. Има невалидни полета, затова събитието submit не се случва. Браузърът фокусира първото невалидно поле и показва съобщение само за него.
  4. Купувачът поправя имейла и телефона и натиска пак.
  5. Същата проверка отгоре. Този път всяко поле минава.
  6. Чак сега идва събитието submit. Ако кодът не го спре, браузърът праща формуляра на адреса от action с метода от method.
  7. Събира двойка name=value от всяко поле с име. Неотметнатата отметка изобщо не заминава.
  8. С method="post" двойките заминават в тялото на заявката, свързани с &. Ключът е атрибутът name, а не текстът на етикета.

Браузърът проверява всички полета, но показва съобщение само за първото невалидно. Затова купувачът понякога поправя едно поле и веднага вижда съобщение за следващото. А gift не заминава изобщо: за сървъра неотметнатата отметка и липсващото поле са едно и също.

Пробвай

Сложи проверките

Бързата поръчка на хляба пропуска всичко. Добави проверки: количеството е от 1 до 10, имейлът е задължителен и трябва да е имейл, телефонът е задължителен и е 0 и още девет цифри. Проверката пише 12, празен имейл, „iva“, празен и грешен телефон и очаква браузърът да спре на правилното поле.

HTML, CSS, JS
index.html
По-точно, за любопитните

Сървърът проверява пак. Проверката в браузъра е за удобството на купувача: той вижда грешката веднага. Тя не пази магазина. 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. Бутон „Поръчай“.

HTML, CSS, JS
index.html

Тест

Провери се

1. Купувачът е написал „Ива“ в поле <input id="name"> без name. Какво заминава с формуляра?
2. Два радио бутона за доставка имат name="courier" и name="office". Какво става?
3. Полето е <input name="email" type="email" required>, а купувачът е написал iva. Какво прави браузърът при „Поръчай“?
4. Защо сървърът проверява поръчката, щом браузърът вече я е проверил?
5. Във формуляр има <button>Приложи кода</button> без type. Какво прави клик върху него?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·