Если вы являетесь веб-разработчиком, то, вероятно, уже создавали HTML-форму. По сути, вы могли создавать их куда чаще, чтобы помнить, сколько раз это было. Наверняка вы знакомы с классическими типами элемента input вроде text, password, file, hidden, checkbox, radio, submit и button и, наверное, использовали их все или большую часть.
Если бы я спросил вас, какой тип элемента input (далее input-тип для краткости) из предыдущего списка вы использовали чаще, чем остальные, то, по-видимому, вы сказали бы «text», как и большинство из нас. Input-тип text — многофункциональный инструмент в классической разработке с применением HTML Forms. С одной стороны, его можно адаптировать почти под любую задачу, но с другой, он семантически нейтрален, поэтому браузер не предлагает никакой помощи в превращении этого элемента в нечто практичное. Для компенсации этого недостатка разработчики и дизайнеры добавляли свою семантику к этим элементам (через идентификаторы и имена классов) и полагались на серверные инфраструктуры и JavaScript в обработке проверок и поддержке различных взаимодействий.
Яркий пример — получение дат в текстовых полях. Обычно вы хотите расширить поле даты каким-либо элементом управления для выбора дат. Это часто делается с помощью JavaScript или инфраструктуры наподобие jQuery UI, которая добавляет поведение взаимодействия, позволяющую пользователю выбирать дату из виджета и вставлять ее в исходное поле.
Как бы ни был полезен этот шаблон (а мы весьма привыкли к шаблонам такого рода), он повторяется столь часто, что трудно удержаться от вопроса: «Ну почему сам браузер не может этого делать?».
Хорошая новость в том, что с помощью HTML5 Forms браузер сможет и будет делать это. В дополнение к text и набору существующих типов, с которыми мы имели дело годами, в HTML5 введено 13 новых значений для атрибута входного типа и ряд других атрибутов, ускоряющих разработку ваших форм. В этой статье я поделюсь информацией о некоторых новых input-типах и атрибутах в HTML5 Forms, а также о состоянии их реализации в различных браузерах. Затем я дам краткий обзор новых клиентских средств проверки для HTML5 Forms. В заключение мы рассмотрим, как недавние обновления в Visual Studio 2010 и Microsoft .NET Framework 4 поддерживают корректное взаимодействие HTML5 Forms и ASP.NET Web Forms. Попутно мы обсудим, как можно уже сейчас использовать HTML5 Forms в ваших приложениях, в то же время предусматривая возможности переключения на другую функциональность для более старых браузеров. Все примеры в этой статье (они доступны в онлайновой форме) были созданы с применением WebMatrix — бесплатного, облегченного инструмента веб-разработки от Microsoft. Вы можете сами опробовать WebMatrix на сайте aka.ms/webm.
Новые input-типы в HTML5
То, что сегодня известно под названием HTML5 Forms или HTML5 Web Forms, начиналось как Web Forms 2.0 — спецификация до определения HTML5, созданная группой Web Hypertext Applications Technology Working Group, или WHATWG. Многое из начальной работы WHATWG послужило отправной точкой для HTML5, и определение Web Forms 2.0 теперь является частью официальной спецификации HTML5, которую можно прочитать по ссылке bit.ly/njrWvZ. Значительная часть спецификации отведена новым типам и атрибутам контента для элемента input (bit.ly/pEdWFs).
Как я упоминал, спецификация вводит 13 новых input-типов для использования в формах: search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range, color.
Использовать эти новые типы легко. Скажем, мне нужно разместить новое поле e-mail на форме заказов. Как видно на рис. 1, я модифицировал страницу Order веб-сайта WebMatrix Bakery Template, введя в нее несколько дополнительных полей, в том числе e-mail.
Рис. 1. Пример формы заказа
Для этой формы поле e-mail размечается так:
<input type="email" id="orderEmail" />
Заметьте, что атрибут типа равен «email», а не «text». Самое ценное в новых HTML-типах input в том, что вы можете использовать их сейчас и они будут работать на том или ином уровне в любом браузере. Когда браузер встречает один из этих типов, происходит одно из двух.
Если браузер не поддерживает новые input-типы, объявление типа не распознается. В таком случае браузер корректно сокращает функциональность и интерпретирует элемент как type="text". Вы можете проверить это, поместив данный элемент на форму и введя «document.getElementById('orderEmail').type» в Internet Explorer 9 F12 Tools Console. Таким образом, вы можете применять эти новые типы уже сегодня, а если браузер не поддерживает данное поле, он будет работать так, будто это обычное текстовое поле.
Однако, если браузер распознает тип, вы немедленно получите выигрыш. Для распознаваемых типов браузер добавляет встроенное поведение, специфичное для конкретных типов. В примере с типом email браузер Internet Explorer 10 Platform Preview 2 (PP2) и более поздние версии автоматически проверяет любой ввод и выводит пользователю сообщение об ошибке, если набранное им значение не соответствует формату адреса электронной почты, как показано на рис. 2.
Рис. 2. Автоматическая проверка браузером input-типа email
О смысле и поведении каждого элемента легко догадаться по его типу, поэтому мы без труда выходим на другой уровень семантического богатства в наших формах. Более того, некоторые из новых input-типов позволяют браузеру изначально обеспечивать более широкое взаимодействие с пользователями. Например, если я размещу на форме следующий элемент, а затем открою эту форму в браузере, который полностью поддерживает input-тип date, то по умолчанию получу гораздо большую функциональность, чем при использовании старого чисто текстового поля:
<input type="date" id="deliveryDate" />
На рис. 3 показано, что может дать тип date в Opera 11.5. Самое главное, что для обеспечения функциональности такого уровня мне достаточно было указать type="date" и браузер автоматически взял на себя все, что раньше приходилось делать самостоятельно на JavaScript.
Рис. 3. Input-тип date в Opera 11.5
Спецификация HTML5 не диктует браузерам, как они должны представлять эти новые input-типы. |
Важно отметить, что спецификация HTML5 не диктует браузерам, как они должны представлять эти новые input-типы или ошибки проверки, поэтому следует ожидать различий в поведении между браузерами. Например, Chrome 13 предоставляет для ввода дат элемент управления «наборный счетчик» (spinner control) вместо элемента управления выбора даты, как показано на рис. 4 (что, конечно, могло измениться к тому моменту, когда вы читаете эту статью). Вы также должны знать о продолжающейся дискуссии в W3C по поводу стилизации и локализации в браузерах элементов вроде datetime, date и color. В настоящее время не все поставщики браузеров согласны на предмет того, как реализовать эти типы, и в существующих реализациях сейчас нет механизма адаптации, аналогичного тому, что есть в jQuery UI. Что бы вы ни выбрали — реализацию или экспериментирование с этими новыми типами, всегда помните о необходимости предоставлять полноценное решение для переключения функциональности. Кроме того, если для ваших пользователей важна согласованность презентационного уровня и поведения, вам, возможно, понадобится применять собственные стили, переопределять поведение по умолчанию этих элементов управления или использовать решение на основе скриптов.
Рис. 4. Input-тип date в Chrome 13
Ранее я говорил: эти поля по-прежнему умеют вести себя как обычные текстовые благодаря тому, что браузеры обеспечивают за нас корректное сокращение функциональности (graceful degradation). Но поле даты, реализованное как простое текстовое поле, — решение корявое, и многими считается неудачным UI-элементом. Однако с помощью Modernizr и jQuery UI можно предоставить решение, совмещающее в себе лучшие качества HTML5 Forms с поддержкой корректного переключения на другую функциональность.
Вспомните из моей прошлой статьи (msdn.microsoft.com/magazine/hh394148), что Modernizr (modernizr.com) — это библиотека JavaScript, которая помогает распознавать поддержку HTML5-средств в браузере. В этом примере я хочу задействовать Modernizr для распознавания поддержки input-типа date HTML5 и, если он не поддерживается, использовать виджет datepicker из jQuery UI (jqueryui.com) для создания UI-элемента с той же функциональностью. Скачав Modernizr, jQuery и jQuery UI и установив на них ссылки, я могу добавить поддержку переключения функциональности для своих элементов date всего несколькими строками кода:
if (!Modernizr.inputtypes.date) {
$("input[type=date]").datepicker();
}
Результат в Internet Explorer 10 PP2 показан на рис. 5.
Рис. 5. Поддержка поля даты с помощью jQuery UI
Новые атрибуты контента input в HTML5
В дополнение к новым input-типам HTML5 предоставляет новые удобные атрибуты контента, которые можно использовать в полях ввода для поддержки проверки и для расширения их функциональности. Один из этих атрибутов — placeholder, который, согласно спецификации, «…предоставляет краткую подсказку (слово или короткую фразу), помогающую пользователю при вводе данных». Например, можно взять пару полей из нашей формы заказа и добавить в каждое поле placeholder="some text" (результат см. на рис. 6):
<input type="email" id="orderEmail"
placeholder="ex. name@domain.com" />
<input type="url" id="orderWebsite"
placeholder="ex. http://www.domain.com" />
Рис. 6. Применение атрибута placeholder с полями ввода
Текст в placeholder по цвету немного светлее, чем обычный текст, и, если фокус ввода устанавливается на поле, он исчезает, позволяя ввести собственное значение.
Как и новые input-типы, атрибут placeholder не поддерживается в более старых браузерах. Однако ничего страшного не случится, когда пользователь такого браузера зайдет на страницу с новыми атрибутами, поэтому подумайте насчет их использования уже сегодня, даже если вы не планируете добавлять поддержку для старых браузеров. Если же вы хотите обеспечить поддержку placeholder через «поли-заполнение» (polyfill), вам поможет Modernizr. Как я упоминал в прошлой статье, добрые дяди в Modernizr пытаются поддерживать рабочий список всех поли-заполнений и переключений функциональности, которые могут понадобиться вам для данной функции HTML5. Этот список можно проверить по ссылке bit.ly/nZW85d.
В нашем примере воспользуемся jQuery HTML5 Placeholder, созданным Майком Тейлором (Mike Taylor); его можно скачать по ссылке bit.ly/pp9V4s. После этого добавьте в скриптовый блок, на который ссылается ваша страница, следующее:
Modernizr.load({
test: Modernizr.input.placeholder,
nope: "../js/html5placeholder.jquery.min.js",
callback: function() {
$('input[placeholder]').placeholder();
}
});
Здесь Modernizr проверяет, поддерживается ли атрибут placeholder, и, если нет, загружает html5placeholder.jquery.min.js. Затем jQuery выбирает каждый элемент с атрибутом placeholder и добавляет для каждого поддержку плагинов. Если вы опробуете это в Internet Explorer 9, то заметите, что итоговый результат выглядит очень похоже на таковой при встроенной поддержке браузером (Internet Explorer 10 PP2).
Еще один интересный новый атрибут — autofocus, который позволяет указывать одно поле на форме, автоматически получающее фокус ввода при загрузке страницы. Этот атрибут должен быть только у одного поля на каждую страницу; если этим атрибутом помечено несколько элементов, то при загрузке страницы фокус ввода получит первый из них. В своей форме заказа я хочу, чтобы фокус автоматически получало поле Name, поэтому добавляю к нему этот атрибут:
<input type="text" class="field" id="orderName" autofocus />
Атрибут autofocus можно использовать применительно к любому элементу управления на форме и это превосходная альтернатива скриптовому варианту, с которым мучились многие веб-разработчики в прошлом.
Проверка HTML5-формы
В статье мало места, чтобы охватить все интересные новые атрибуты, относящиеся к формам, но я все же коротко расскажу об атрибутах required, pattern, novalidate и formnovalidate, каждый из которых предельно упрощает проверку формы на клиентской стороне.
Атрибут required сообщает браузеру, который его поддерживает, о том, что данную форму нельзя передавать на сервер, пока в ней отсутствует определенное значение. Например, я добавляю required к полю Name на форме заказа:
<input type="text" class="field" id="orderName" required />
Когда я открою эту страницу в Internet Explorer 10 PP2 и попытаюсь передать форму на сервер, я увижу нечто вроде того, что показано на рис. 7. Благодаря единственному атрибуту браузер знает достаточно, чтобы применить к этому элементу стиль с красной рамкой и вывести сообщение о том, что это поле является обязательным для заполнения.
Рис. 7. Применение атрибута required к полю на форме
Ранее на рис. 2 было показано, как браузер может автоматически проверять определенные типы, такие как email и url, без дополнительного ввода от пользователя. С помощью атрибута pattern вы можете предоставить свою проверку input-типов. Согласно спецификации HTML5, pattern ожидает наличия регулярного выражения, которое браузер использует для проверки.
Моя форма заказа содержит поле ввода телефона (type="tel"), и я могу указать такой шаблон проверки:
<input type="tel" id="orderTelephone" pattern=
"\(\d\d\d\) \d\d\d\-\d\d\d\d" title="(xxx) xxx-xxxx" />
Это (не особо сложное) регулярное выражение сообщает браузеру, что в поле должно быть семизначное число с круглыми скобками вокруг кода региона и дефисом в местном номере. Ввод любых других данных в другом формате приведет к появлению сообщения, как показано на рис. 8. Заметьте, что это сообщение подсказывает пользователю правильный формат ввода: «(xxx) xxx-xxxx». Эта часть сообщения берется из атрибута title того же элемента, поэтому можно управлять, по крайней мере, частью сообщения проверки через разметку. Однако при использовании title стоит обратить внимание на один момент. Согласно спецификации, браузер может выводить содержимое title в других ситуациях, не связанных с ошибками, поэтому не полагайтесь на этот атрибут как на место хранения текста, используемого в сообщении об ошибке.
Рис. 8. Использование атрибута pattern для определения выражения проверки
Автоматизация проверки браузером — это прекрасно, но здесь сразу же возникает два вопроса. Во-первых, что будет со скриптами проверки на серверной или клиентской стороне, генерируемыми моей серверной инфраструктурой (например, ASP.NET MVC)? А во-вторых, как быть в тех ситуациях, где я хочу, чтобы пользователь мог сохранять не до конца заполненную форму без проверки? Ответ на первый вопрос, увы, выходит далеко за рамки моей статьи, но на эту тему (применительно к ASP.NET MVC) я написал статью в блоге, которую вы найдете по ссылке bit.ly/HTML5FormsAndMVC.
Добавление поддержки Web Forms к браузерам с HTML5 — хорошая новость для всех веб-разработчиков. |
С другой стороны, ответить на второй вопрос легко. Допустим, у вас есть форма, на заполнение которой пользователи тратят приличное время, возможно, даже не раз сохраняя ее перед окончательной отправкой на сервер. На такой случай, когда нужно разрешить пользователю передачу формы без проверки, существуют два атрибута: formnovalidate (помещается в поля ввода типа submit) и novalidate (помещается в открывающий тег формы). Здесь я разместил на форме два поля submit:
<input type="submit" value="Place Order" />
<input type="submit" formnovalidate value=
"Save for Later" id="saveForLater" />
Атрибут formnovalidate во второй кнопке отключит проверку и отправит ее на сервер, что обеспечивает промежуточное сохранение незаконченной работы пользователя в моей базе данных или даже на клиентской стороне, если задействовать новую технологию хранения HTML5 вроде localStorage или IndexedDB.
HTML5 Forms и ASP.NET Web Forms
Прежде чем закончить эту статью, я хочу поделиться еще несколькими битами информации, относящейся к HTML5 Forms, которая будет интересна разработчикам, использующим ASP.NET Web Forms. Если вы планируете вести разработку HTML5 Forms с применением ASP.NET Web Forms, у меня есть хорошие новости: для .NET и Visual Studio внепланово выпускается много обновлений, связанных с HTML5, поэтому вам не придется ждать следующей версии инфраструктуры, чтобы использовать эти средства уже сейчас.
Чтобы приступить к работе с HTML5 Forms и ASP.NET Web Forms, вам нужно получить пару обновлений. Прежде всего убедитесь, что у вас имеется Visual Studio 2010 SP1 (bit.ly/nQzsld). Помимо добавления поддержки новых input-типов и атрибутов HTML5, этот пакет также включает обновления, позволяющие использовать новые input-типы HTML5 в серверном элементе управления TextBox. Без этого обновления использование новых типов приведет к ошибкам при компиляции.
Вам также понадобится Microsoft .NET Framework 4 Reliability Update 1 (bit.ly/qOG7Ni). Это обновление устраняет целый ряд проблем, относящихся к использованию новых input-типов HTML5 с ASP.NET Web Forms. Скотт Хантер (Scott Hunter) рассмотрел некоторые из них — UpdatePanel, Validation Controls и Callbacks — в статье по ссылке bit.ly/qE7jLz.
Добавление поддержки Web Forms к браузерам с HTML5 — хорошая новость для всех веб-разработчиков. Мы не только получаем набор семантических input-типов для применения в наших приложениях (в новых браузерах это обеспечивает расширенную функциональность, включая автоматическую проверку на клиентской стороне), но и можем использовать их сегодня безо всякого ущерба для старых браузеров. Использование новых полей прямо сейчас дает выигрыш и в пространстве мобильных приложений, где такие типы, как url и email, будут заставлять мобильные устройства будут предлагать пользователю различные варианты, запрограммированные для конкретного input-типа. Объединяя новые средства с Modernizr и одним из средств поли-заполнений, вы получаете все инструменты, необходимые для внедрения HTML5 Forms в ваших приложения в настоящее время.
Подробнее о поддержке HTML5 Forms в Internet Explorer 10 PP2 см. по ссылке ietestdrive.com, а также изучите руководство разработчика в Internet Explorer Developer Center (bit.ly/r5xKhN). Более глубокое описание HTML5 Forms в целом советую почитать «A Form of Madness» из книги Марка Пилгрима (Mark Pilgrim) «HTML5: Up and Running» (O’Reilly Media, 2010), а также раздел Forms в W3C-спецификации HTML5 (bit.ly/nIKxfE).