Статьи

Простые трюки для более удобных форм

Веб-разработчики ненавидят задачу создания форм почти так же, как пользователи не хотят заполнять их. Оба эти факта печальны в Интернете, но некоторые умные JavaScript и интеллектуальные CSS могут значительно улучшить ситуацию. В этой статье я познакомлю вас с несколькими простыми приемами по улучшению удобства использования форм и, надеюсь, вдохновлю вас на улучшение их и создание своих собственных.

Я собираюсь начать с некоторых простых трюков, а потом представлю интересный материал. Если материал кажется вам слишком простым, не стесняйтесь пропустить.

Это мелочи, которые рассчитывают

Вы наверняка сталкивались с нашей первой уловкой раньше; он используется Google, самой популярной поисковой системой в мире. Всякий раз, когда вы загружаете www.google.com , курсор переходит прямо в окно поиска, готовый для ввода запроса. Это происходит так быстро, что вы, возможно, даже не задумывались об этом, но, на самом деле, это работает одинаково хорошо в любой ситуации, в которой основная цель страницы — заполнить форму. Это можно сделать несколькими различными способами, каждый из которых предполагает, что элемент формы, на котором вы хотите сосредоточиться, имеет атрибут id, установленный в «myfield»:

<body onload="document.getElementById('myfield').focus()">

Это более или менее метод, используемый Google. Это коротко и по существу. Это, однако, требует добавления нагрузки к элементу вашего тела, что некоторые люди считают неприглядным.

 <script type="text/javascript"> 
window.onload = document.getElementById('myfield').focus;
</script>

Это может быть добавлено к любой точке вашего HTML-файла или скрыто во внешнем скрипте. Если вы собираетесь использовать много JavaScript на странице, имеет смысл переместить все это во внешний файл скрипта, чтобы отделить код JavaScript от вашего HTML. Недостатком этого метода является то, что вы можете назначить только одну вещь событию window.onload

 <script type="text/javascript"> 
addEvent(window, 'load', function() {
 document.getElementById('myfield').focus()
});

function addEvent(obj, evType, fn){
 if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
 } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
 } else {
    return false;
 }
}
</script>

При этом используется функция addEventпредыдущей статье . Это, вероятно, лучший подход, если вы храните свой код в отдельном файле, так как он позволяет также присоединять другие функции к событию onload.

 <script type="text/javascript"> 
document.getElementById('myfield').focus();
</script>

Вышеуказанное будет работать только в том случае, если оно помещено в исходный код HTML в какой-то точке после поля ввода. Это может быть полезно, если вы работаете с системой шаблонов на стороне сервера, которая затрудняет добавление кода непосредственно в верхнюю часть документа — например, если вы включаете верхнюю часть страницы с помощью включения на стороне сервера.

Выше четыре опции доступны для большинства трюков, которые я продемонстрирую в этой статье. В следующих уловках я продемонстрирую метод с использованием встроенных атрибутов, таких как только onload и onclick, но вы должны знать, что существует несколько способов обшить эту конкретную кошку.

Этикетки

Самый быстрый способ повысить удобство использования форм — добавить ярлыки, если вы их еще не используете. Элемент <label> Это позволяет логически связать текст, описывающий поле формы, с самим полем формы. Когда пользователь нажимает на ярлык, браузер перемещает фокус в соответствующее поле формы или переключает его состояние в случае переключателей и кнопок-флажков. Перед добавлением метки в поле формы должен быть установлен атрибут ID. Фактически, подсказки в этой статье почти все требуют, чтобы атрибут ID был установлен в поле формы, так как это обеспечивает полезный способ нацеливания этого поля из JavaScript.

Вот самый простой пример метки в действии:

 <label for="username">Username:</label>  
<input type="text" name="username" id="username" size="10">

При нажатии на слово «Имя пользователя» курсор будет находиться в текстовом поле. Это может показаться не очень полезным эффектом, но дает нам полезную возможность для стилизации и, возможно, добавления дополнительного поведения JavaScript. Это также значительно улучшает доступность формы для пользователей вспомогательного программного обеспечения.

На самом деле лейблы приходят сами по себе с флажками и переключателями. Оба этих виджета страдают от крошечной активной области, иногда называемой «горячей точкой», в которую нужно застрять мышкой, чтобы заставить их переключаться. Добавление метки увеличивает горячую точку, чтобы покрыть текст, связанный с виджетом:

 <input type="checkbox" name="accepted" id="accepted">  
<label for="accepted">I agree to the terms and conditions</label>

Конечно, лейблы не очень хороши, если люди не знают, что они там. Один простой, но эффективный способ увеличить видимость меток — использовать CSS для изменения курсора на них:

 <style type="text/css">  
label {  
 cursor: pointer;  
 cursor: hand;  
}  
</style>

Почему два объявления курсора? Стандарт CSS определяет «указатель» в качестве значения «указатель, который указывает на ссылку». К сожалению, IE 5 и IE 5.5 для Windows не понимают этого значения, используя «hand» для обозначения одного и того же. Помещая указатель в первую очередь неправильно, браузеры Microsoft игнорируют его и используют значение руки, тогда как браузеры с лучшим поведением берут указатель и игнорируют руку.

Визуальные подсказки

В большой форме может быть легко потерять отслеживание поля формы, которое вы в настоящее время заполняете. Отличный трюк для помощи заключается в следующем:

 <style type="text/css">  
input {  
 border: 2px solid #ccc;  
}  
input:focus {  
 border: 2px solid #000;  
}  
</style>

Это приводит к тому, что все поля ввода имеют серую рамку шириной 2 пикселя, в то время как поле ввода, на которое в данный момент сфокусирован пользователь, получает черную рамку, чтобы выделить ее среди других. Есть одно предостережение: IE в Windows не поддерживает псевдокласс :focus К счастью, возможно повторить эффект, используя JavaScript:

 <input type="text" name="myfield" id="myfield"   
      onfocus="this.style.border='2px solid #000'"  
      onblur="this.style.border='2px solid #ccc'">

Это приносит эффект в IE, за счет большого количества дополнительной печати. Если у вас есть много полей формы на странице, имеет смысл сделать это вместо этого, снова используя функцию addEvent

 <script type="text/javascript">  
addEvent(window, 'load', function() {  
 var input, textarea;  
 var inputs = document.getElementsByTagName('input');  
 for (var i = 0; (input = inputs[i]); i++) {  
   addEvent(input, 'focus', oninputfocus);  
   addEvent(input, 'blur', oninputblur);  
 }  
 var textareas = document.getElementsByTagName('textarea');  
 for (var i = 0; (textarea = textareas[i]); i++) {  
   addEvent(textarea, 'focus', oninputfocus);  
   addEvent(textarea, 'blur', oninputblur);  
 }  
});  
function oninputfocus(e) {  
 /* Cookie-cutter code to find the source of the event */  
 if (typeof e == 'undefined') {  
   var e = window.event;  
 }  
 var source;  
 if (typeof e.target != 'undefined') {  
    source = e.target;  
 } else if (typeof e.srcElement != 'undefined') {  
    source = e.srcElement;  
 } else {  
   return;  
 }  
 /* End cookie-cutter code */  
 source.style.border='2px solid #000';  
}  
function oninputblur(e) {  
 /* Cookie-cutter code to find the source of the event */  
 if (typeof e == 'undefined') {  
   var e = window.event;  
 }  
 var source;  
 if (typeof e.target != 'undefined') {  
    source = e.target;  
 } else if (typeof e.srcElement != 'undefined') {  
    source = e.srcElement;  
 } else {  
   return;  
 }  
 /* End cookie-cutter code */  
 source.style.border='2px solid #ccc';  
}  
</script>

Код cookie-резака в приведенном выше примере имеет дело с некоторыми неудобствами, связанными с совместимостью браузеров, и обсуждался в моей предыдущей статье.

Расширение полей ввода текста

Наиболее распространенным полем формы является <input type="text"> Мы уже видели, как автоматическая фокусировка на этом, когда загрузка страницы может сделать хорошее улучшение. Полезный прием для полей, содержащих значение по умолчанию, которое необходимо изменить, заключается в следующем:

 <input type="text" name="myfield" id="myfield" size="30"   
      value="This should be changed"  
      onfocus="this.select()">

Когда поле получает фокус, текст внутри него будет мгновенно выделен; он будет перезаписан в тот момент, когда пользователь начнет вводить свой собственный текст. Это также полезно, если пользователь может скопировать и вставить текст из виджета, поскольку это избавляет его от необходимости сначала выбирать его.

Вот хороший трюк для форм, которые используются для создания чего-то с очевидным названием — например, электронное письмо или статья на веб-сайте:

 <input type="text" name="title" id="title" size="30"   
      onkeyup="document.title = 'New item: ' + this.value">

Это создает эффект, подобный многим популярным почтовым программам, когда текст в строке заголовка документа изменяется по мере ввода темы электронного письма. Это может быть особенно полезно в среде, где несколько окон могут быть открыты одновременно — например, клиент Web-почты.

Что касается примечания, иногда значение одного поля формы можно изначально угадать, посмотрев на значение другого. Классическим примером является система управления контентом, где каждая запись имеет удобочитаемый заголовок и уникальный URL-адрес. По умолчанию URL может соответствовать заголовку, но с удаленной пунктуацией и пробелами, преобразованными в подчеркивания. Вот код для этого:

 <input type="text" name="title" id="title" size="30"   
      onkeydown="document.getElementById('url').value =    
               this.value.replace(/[^a-z0-9 ]/ig,  
               '').replace(/ /g, '_')">  
<input type="text" name="url" id="url" size="30">

Важнейшим моментом здесь является то, что пользователь может переопределить предполагаемое значение для URL, если он хочет, введя текст непосредственно в поле. Если вы просто хотите создать URL-адрес из заголовка без какого-либо вмешательства со стороны пользователя, лучше всего это сделать в коде на стороне сервера, который обрабатывает форму.

Проверка

Проверка формы на стороне клиента — одно из самых популярных применений JavaScript. Прежде чем мы продолжим, я хотел бы отметить, что если вы создаете приложение на стороне сервера, вы всегда должны проверять правильность данных в коде на стороне сервера, независимо от того, использовали ли вы проверку на стороне клиента. Невыполнение этого требования может сделать ваше приложение широко открытым для всевозможных неприятных проблем безопасности — помните, что злоумышленники знают, как отключить JavaScript в своем браузере. Этот момент нельзя подчеркнуть достаточно. Теперь вернемся к нашему обычному программированию …

Валидация — большая тема, и она широко освещалась в учебных пособиях по всей сети. Вместо того, чтобы перефразировать старые идеи, я сосредоточусь на более удобном способе проверки пользовательского ввода. Для мгновенной обратной связи с пользователем, как насчет отображения значка рядом с каждым полем формы, которое указывает, правильно ли заполнено это поле? Такая иконка может быть прямо подключена к элементам метки, которые мы добавили ранее, и может быть изменена с помощью JavaScript для изменения атрибута класса элемента метки.

Вот простой пример для обязательного поля формы, разбитого на CSS, JavaScript и HTML:

 <label for="subject" class="required">Subject:</label>   
<input type="text" id="subject" name="subject" size="40"    
      onblur="checkRequired('subject');">

Это достаточно просто. Элемент label начинается с класса «required», чтобы визуально указать, что это поле является обязательным. Функция JavaScript checkRequired('subject')

 <style type="text/css">   
label {  
 padding-left: 22px; /* To leave room for the icon */  
}  
label.required {  
 background-image: url(required.gif);  
 background-repeat: no-repeat;  
 background-position: 3px 0px;  
}  
label.problem {  
 background-image: url(caution.gif);  
 background-repeat: no-repeat;  
 background-position: 3px 0px;  
}  
label.completed {  
 background-image: url(complete.gif);  
 background-repeat: no-repeat;  
 background-position: 3px 0px;  
}  
</style>

CSS дает каждой метке левый отступ в 22 пикселя. Значки, которые мы будем использовать, будут иметь размер 15 × 15, что дает нам немного свободного места. Определены специальные классы «Требуется», «Задача» и «Завершено», каждый со своим собственным значком фона, расположенным слева от текста формы.

 <script type="text/javascript">   
function getLabelForId(id) {  
 var label, labels = document.getElementsByTagName('label');  
 for (var i = 0; (label = labels[i]); i++) {  
   if (label.htmlFor == id) {  
     return label;  
   }  
 }  
 return false;  
}  
function checkRequired(id) {  
 var formfield = document.getElementById(id);  
 var label = getLabelForId(id);  
 if (formfield.value.length == 0) {  
   label.className = 'problem';  
 } else {  
   label.className = 'completed';  
 }  
}  
</script>

Здесь мы определяем две функции JavaScript: одну для поиска метки, связанной с конкретным идентификатором, и другую, которая проверяет, что в указанном поле формы что-то есть, и соответственно устанавливает класс связанной метки. Это простейший возможный случай проверки; Дополнительные функции могут быть написаны для решения таких проблем, как проверка того, что адреса электронной почты находятся в полезном формате. Эту технику можно пойти еще дальше, отключив кнопку отправки, пока все поля формы не будут заполнены правильно; однако, если это будет сделано, жизненно важно, чтобы первоначальное отключение кнопки отправки происходило в JavaScript, чтобы гарантировать, что браузеры без поддержки JavaScript все еще могут использовать форму.

Последний трюк, о котором я расскажу, вращается вокруг данных, имеющих очень специфический формат. Вместо того, чтобы отклонять ввод пользователя, если он не полностью соответствует правилам форматирования, иногда возможно переформатировать данные пользователя после их ввода. Классическим примером является поле формы для приема телефонных номеров в США. Телефонные номера в США, если указан код города, имеют длину 10 цифр. Традиционный способ их отображения — (785) 555-5555. Используя JavaScript, мы можем взять введенные пользователем данные, удалить все нецифровые символы и, если у нас осталось 10 цифр, переформатировать их, чтобы они выглядели так, как показано выше:

 <script type="text/javascript">   
function checkPhone() {  
 var phone = document.getElementById('phone');  
 var label = getLabelForId('phone');  
 var digits = phone.value.replace(/[^0-9]/ig, '');  
 if (!digits) {  
   return;  
 }  
 if (digits.length == 10) {  
   phone.value = '(' + digits.substring(0, 3) + ') ' +    
     digits.substring(3, 6) + '-' +    
     digits.substring(6, 10);  
 } else {  
   phone.value = digits;  
 }  
}  
</script>  
 
<label for="phone">Phone Number:</label>  
<input type="text" id="phone" name="phone" size="20"    
      onblur="handlePhone();">

Эту технику можно использовать еще дальше, чтобы разрешить несколько способов ввода структурированных данных, таких как дата, при этом любые распознанные значения преобразуются в стандартный формат. Мой лучший скрипт ввода даты делает именно это, и я рекомендую вам проверить исходный код, чтобы увидеть, как именно он работает.

Чтобы лучше проиллюстрировать идеи в этой статье, я собрал эту простую форму, которая демонстрирует некоторые из представленных методов. Надеюсь, я вдохновил вас подумать о новых способах повышения удобства использования вашей формы с помощью JavaScript и CSS.