Глава 10. Формы и внутренние элементы управления



В данной главе показано, как программировать пользовательские интерфейсы, которые запрашивают и обрабатывают вводимую пользователем информацию. HTML поддерживает элементы управления, которые принимают вводимую пользователем информацию, и элемент, который предоставляет модель формы для группирования содержания и отправки его обратно на сервер. Данные элементы управления называются внутренними элементами управления (intrinsic controls), поскольку они встроены в HTML. Их функциональные возможности сильно ограничены при сравнении с большинством пакетов форм и баз данных. Проверка и форматирование еще прямо не поддерживаются, но вы можете легко добавить данные элементы, используя объектную модель. В данной главе представлены методы манипулирования формами и внутренними элементами управления внутри документа. Внутренние элементы управления представлены в функциональных категориях, кроме того показаны методы расширения HTML для соответствия возможностям, предоставляемым мощными пакетами форм.

В данной главе рассмотрены следующие темы:



HTML-формы

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

<HTML>
<HEAD>
<TITLE> Информация о пользователе </TITLE>
</HEAD>
<BODY>
<FORM NAME="UserInfo">
<LABEL FOR="USER">User Name: </LABEL>
<INPUT TYPE=TEXT NAME="USER" VALUE="User Name" ID="USER">
<LABEL FOR="ADDRESS">Address: </LABEL>
<TEXTAREA ROWS=2 COLS=50 NAME="ADDRESS" ID="ADDRESS">
Enter Address
</TEXTAREA>
<INPUT TYPE=SUBMIT VALUE="Submit Information">
</FORM>
</BODY>
</HTML>

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



Область действия форм

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

Определение области действия разделяет пространство имен, доступных для элементов. Например, если две формы содержат элемент user, то эти элементы будут функционировать независимо. Это особенно важно для групп кнопок-переключателей, в которых объединение определяется каждым именем элемента. Кнопки-переключатели обеспечивают простой способ демонстрации разделения областей действия. Например, если две формы на одной странице могут иметь группу кнопок-переключателей state, то кнопки-переключатели будут взаимоисключающими только внутри своих форм. Приведенный ниже документ определяет две раздельные группы кнопок-переключателей, которые совместно используют одно имя:

<HTML>
<HEAD>
<TITLE> Демонстрация области действия кнопки-переключателя </TITLE>
</HEAD>
<BODY>
<!-- Кнопки-переключатели за пределами формы имеют одну область действия. -->
<INPUT TYPE=RADIO NAME="State" VALUE="NJ">NJ
<INPUT TYPE=RADIO NAME="State" VALUE="NY">NY
<FORM STYLE="margin-left: 25pt">
<!-- Данные две кнопки-переключателя являются взаимоисключающими
и независимыми кнопками за пределами данной формы. -->
<INPUT TYPE=RADIO NAME="State" VALUE="WA">WA
<INPUT TYPE=RADIO NAME="State" VALUE="CA">CA
</FORM>
<INPUT TYPE=RADIO NAME="State" VALUE="MA">MA
</BODY>
</HTML>

В данном примере все пять кнопок-переключателей совместно используют имя State, но имеют разные области действия. Первые две кнопки-переключателя (NJ, NY) и последняя кнопка-переключатель (МА) находятся внутри одной глобальной области действия и являются взаимоисключающими. Две кнопки-переключателя внутри формы (WA, СА) находятся в области действия формы и являются взаимоисключающими только друг для друга. Поэтому пользователь может выбрать одно значение из каждой группы кнопок-переключателей.



Программирование элемента Form

Формы и внутренние элементы управления в пределах области действия имеют богатую модель программирования. С помощью объекта form вы можете отправить и очистить форму, а также получить доступ и манипулировать индивидуальными элементами управления.


Семейство forms

Формы в документе представлены посредством семейств all и forms. Кроме того, именованные формы имеют специальные отношения с документом и к ним можно обратиться непосредственно как к свойствам самого документа.

Приведенный ниже код демонстрирует несколько способов обращения к элементам Form с использованием объектной модели. В примечаниях указано, что будет отображено в диалоговых окнах Alert.

<HTML>
<HEAD>
<TITLE> Формы в объектной модели </TITLE>
</HEAD>
<BODY>
<FORM NAME="form1">
</FORM>
<FORM NAME="form2">
</FORM>
<SCRIPT LANGUAGE="JavaScript">
alert(document.forms.length); // 2
alert(document.forms[0].name); // form1
alert(document.forms.form2.name); // form2
alert(document.form1.name); // form1
alert(document.all.form2.name); // form2
alert(document.forms["form1"].name); // form1
</SCRIPT>
</BODY>
</HTML>


Семейство elements

Между формой и ее внутренними элементами управления поддерживаются определенные отношения. Все внутренние элементы управления, находящиеся внутри формы, представлены посредством свойств объекта form, a также посредством семейства elements, что обеспечивает прямой доступ ко всем внутренним элементам управления, которые существуют в форме. Семейство elements объекта form работает аналогично семейству frames объекта window, в котором семейство представлено просто для повышения легкости чтения кода. Как и семейство frames, семейство elements действительно возвращает ссылку на объект form. Например, приведенные ниже две строки кода выполняют одинаковые операции:


document.forms[0].length // Число элементов в первой форме
document.forms[0].elements.length

Также эквивалентны следующие три ссылки:


document.forms[0]
document.forms[0].elements
document.forms[0].elements.elements

Семейство elements работает аналогично другим семействам в объектной модели и обеспечивает доступ к индивидуальным внутренним элементам управления в форме. Семейство elements также содержит все изображения внутри области действия формы.

Правила, изложенные в главе 7, могут быть использованы для доступа к содержанию семейства elements объекта form. Если в форме имеются элементы с одинаковыми именами, то они представлены как подсемейство. Также доступны методы tags и item. Например, приведенный ниже код может быть использован для быстрого доступа ко всем элементам Button в первой форме и для доступа к третьему элементу в данном семействе:


// Возвращает семейство кнопок в первой форме.
document.forms[0].elements.tags("BUTTON") // Доступ к третьему внутреннему элементу управления в форме.
document.forms[0].elements[2]

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

<FORM NAME="User">
<!-- Передает текущую форму обработчику событий. Свойство this обращается к внутреннему элементу управления, а свойство формы обращается к форме, в области действия которой находится элемент управления. -->
<INPUT TYPE=TEXT ONCHANGE="doClick(this.form);">
</FORM>

Примечание: Если внутренний элемент управления находится за пределами области действия формы, то свойство form возвращает null.



Передача содержания формы

Как упоминалось выше, формы могут быть использованы для обработки данных на клиентской стороне или для отправки данных обратно на сервер. При передаче формы на сервер имя и значение всех элементов формы помещаются в одну строку, которая отправляется на сервер. Строка состоит из пар имя-значение, которые разделены амперсандами (&). Данная строка содержит имена и значения всех элементов формы, которые имеют имя. Например, для формы ввода пользовательской информации в начале данной главы отправляемая строка будет выглядеть следующим образом:


?USER=SCOTT+ISAACS&ADDRESS=1+Somewhere+Street+WA

В данной строке все пробелы заменены на знаки (+).


Значения кнопок

Кнопки отправляются несколько иным образом, чем стандартные текстовые элементы управления. В табл. 10.1 перечислены правила для различных типов кнопок.

Таблица 10.1. Типы кнопок


Тип кнопки Описание

Кнопка-переключатель В форме отправляется только значение выбранной кнопки-переключателя .из группы кнопок-переключателей. Если кнопка-переключатель не выбрана, то значение по умолчанию равно ON
Флажок Флажки отправляют свои пары имя-значение только когда они выбраны. Если флажок не указан, то значение по умолчанию равно ON
Submit (Отправить) В форме может быть указано несколько кнопок Submit. Если кнопке Submit назначено имя, то ее пара имя-значение отправляется вместе с формой


Имена разделяемых элементов

Правила определения содержания отправляемой формы просты: внутренний элемент управления должен иметь имя и должны быть выбраны кнопки. Поскольку в группе кнопок-переключателей может быть выбрана одновременно только одна кнопка-переключатель, то для каждой группы кнопок-переключателей отправляется только одно значение. Однако не требуется, чтобы имена в отправляемой строке были уникальными. Например, если имена ряда флажков совпадают, то будут отправлены пары имя-значение всех выбранных флажков с данным именем. И в полях со списками, допускающими выбор нескольких вариантов (multiple-select list box) (в дальнейшем мы будет называть их поля со списками для множественного выбора) пара имя-значение отправляется для каждого выбранного элемента.

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


Отключенные элементы и элементы только для чтения

Элементы могут быть отключены с помощью сценария или HTML. Отключенные элементы (disabled elements) не могут получать фокус и отображаются серым цветом в окне браузера Microsoft Internet Explorer. Поскольку отключенный элемент не учитывается в текущем контексте формы, то его значение опускается при отправке формы.

Содержание элементов только для чтения (read-only elements) не может быть изменено. По умолчанию кнопки предназначены только для чтения, а все остальные внутренние элементы управления можно изменять. Хотя отсутствует возможность изменения кнопки, можно установить запрет на модификацию других внутренних элементов управления, используя атрибут readOnly языка HTML или соответствующее свойство объектной модели В отличие от отключенных элементов, элементы только для чтения отправляются вместе с содержанием формы.


Значения элемента Object

Браузер Internet Explorer 4.0 поддерживает отправку элемента Object (объект) вместе с формой, если объект имеет имя и значение по умолчанию, которое может быть отправлено. Это позволяет отправлять апплеты и элементы управления ActiveX так же, как и другие внутренние элементы управления.


Куда отправляется содержание формы?

По умолчанию отправляемая строка передается обратно на сервер с текущим адресом URL. Для отправки данных можно использовать два метода: GET и POST. Используемый метод определяется в свойстве формы method. По умолчанию установлен метод GET, который обеспечивает присоединение отправляемой строки к адресу URL. Полученная в результате строка открывается как новый якорь. Выбор используемого метода отправки зависит от того, какое приложение запущено на сервере.

Вместо отправки формы обратно по адресу URL страницы можно установить индивидуальное местоположение для формы, используя свойство action формы. Свойство action содержит адрес URL программы сервера, которая принимает отправленные формой данные. Данное свойство может динамически изменяться для приема данных в разных точках.


Куда возвращаются результаты формы?

В то время как свойство action определяет место на сервере для приема данных, свойство get определяет место на клиентской машине, где будет храниться возвращаемая информация. Свойство target работает аналогично свойству target элемента Anchor и используется для определения окна или фрейма, в котором будет отображаться содержание. Данное свойство может быть использовано для создания пользовательского интерфейса, в котором постоянно обновляется не вся область экрана. Например, отображаются два фрейма, один из которых может запрашивать ввод информации пользователем, а другой может отображать возвращаемый результат.


Отмена отправки формы

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


<HTML>
<HEAD>
<TITLE> Отмена отправки формы - неправильный способ </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function doSubmit(f) {
return false;
}
</SCRIPT>
</HEAD>
<BODY>
<!-- Отправка формы не отменена. -->
<FORM ONSUBMIT="doSubmit(this);">
<INPUT TYPE=CHECKBOX NAME="Info">
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

В данном примере отправка формы не отменяется, хотя значение false возвращается вызванной функцией, поскольку возвращаемое значение потом не передается в обработчик событий onsubmit.

Правильным способом отмены отправки формы является возвращение значения, которое вернула вызванная функция. Ниже показано, как определить тег <FORM>:


<FORM ONSUBMIT="return doSubmit(this);">

Теперь, когда выполняется обработчик событий onsubmit, значение, возвращаемое функцией, корректно передается в обработчик событий.


Отправка формы

Метод submit объекта form обеспечивает отправку данных формы. Вызов метода submit не запускает события onsubmit. Поэтому если необходима проверка, то обработчик событий onsubmit должен быть вызван вручную,


<HTML>
<HEAD>
<TITLE> Отправка формы вручную </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function doSubmit(f) {
// Код условия, который определяет, // будет ли произведена отправка.
return f.Info.checked;
}
function manualSubmit(f) {
var isSubmit = f.onsubmit();
// Отправка, если не возвращается никакого значения или // значения true. if ((isSubmit) || (null==isSubmit))
f.submit(); // Submit the form.
}
</SCRIPT>
</HEAD>
<BODY>
<FORM ONSUBMIT="return doSubmit(this)
// Должно быть возвращено значение обработчика событий.">
<INPUT TYPE=CHECKBOX NAME="Info">
<INPUT TYPE=BUTTON ONCLICK="manualSubmit(this.form)"
VALUE="Submit">
</FORM>
</BODY>
</HTML>



Сброс содержания формы

При первой загрузке страницы исходные установки элементов управления сохраняются в специальных свойствах по умолчанию. Для текстовых элементов управления свойством по умолчанию является defaultValue. Для командных кнопок или кнопок-переключателей свойством по умолчанию является свойство defaultChecked, для элементов списков свойством по умолчанию для каждого элемента является defaultSeiected. При сбросе содержания формы значения данных свойств копируются обратно в значе-ния элементов управления.

Кнопка Reset обеспечивает выполнение встроенного метода для сброса содержания формы к исходным значениям. Аналогичное действие может быть промоделировано в форме путем вызова метода reset в самой форме. Подобно методу submit формы событие onreset не возникает, когда вызывается метод reset. Прием, продемонстрированный в предыдущем разделе для метода submit, может быть также использован для запуска метода reset после первого вызова обработчика событий onreset.



Надо ли использовать элемент Form?

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

Использование элемента Form для манипуляций на клиентской стороне не оказывает отрицательного воздействия и предоставляет ряд преимуществ. Использование элемента Form обеспечивает группирование элементов Input внутри семейства elements и выделение пространства имен для кнопок-переключателей. Кроме того, в Netscape Navigator элементы управления отображаются и доступны из сценариев, только если они содержатся внутри блока формы. Если требуется обеспечить совместимость с Netscape Navigator, то элементы управления всегда должны находиться внутри элемента Form.



Скрытие и отображение внутренних элементов управления

Динамический HTML поддерживает специальный тип внутренних элементов управления, которые всегда скрыты. Поскольку пользователь может обращаться к данному элементу и манипулировать им, то данный элемент преимущественно используется в качестве места для рассчитанной величины, которая должна быть отправлена вместе с формой. Элемент Input невидим, если значение его атрибута TYPE равно HIDDEN. Поэтому если необходимо динамически изменять режим вывода элемента на экран, то следует использовать стандартный внутренний элемент управления и установить для его свойства display в CSS значение none или значение hidden для свойства visibility. Впоследствии, изменив значение свойств visibility или display, можно вывести элемент управления на экран. Подобно элементу Input со значением HIDDEN, невидимые внутренние элементы управления отправляются вместе с содержанием формы. Приведенный ниже код делает видимый в исходном состоянии элемент видимым. Если внутренний элемент управления являлся элементом Input со значением HIDDEN, то свойство display не оказывает на него влияния.


<INPUT TYPE=TEXT STYLE="display:none" ID="myTextbox">
<SCRIPT LANGUAGE="JavaScript">
// Отображение текстового окна.
document.all.myTextbox.style.display = "";
</SCRIPT>


Использование элементов Input со значением HIDDEN

Элементы Input HIDDEN наиболее полезны для передачи рассчитанных данных вместе с формой. С помощью элементов Input HIDDEN можно обойти недостаток браузера Netscape Navigator, который обусловливает повторную инициализацию переменных в сценариях при каждом изменении размеров окна. Вы можете сохранить переменные в скрытых полях и не волноваться об изменении пользователем размеров окна. Спрятанное поле представляет ту же объектную модель, что и текстовое окно без событий, связанных с пользовательскими действиями.



Взаимодействие с отключенными внутренними элементами управления

Отключенные элементы отображаются серым цветом. Однако если отключенное текстовое окно содержит текст, то пользователю нелегко определить, что данный элемент является отключенным. Проверив, взаимодействует ли пользователь с отключенным элементом управления с помощью всплывания событий, вы можете обеспечить вывод объяснения для пользователей, когда они попытаются щелкнуть по отключенному элементу управления.

Отключенные элементы управления не генерируют события. Напротив, события генерируются на первом активизированном родительском элементе. Приведенный ниже код демонстрирует добавление специального сообщения "disabledError" для внутреннего элемента управления и затем проводит его общую проверку:


<HTML>
<HEAD>
<TITLE> Демонстрация отключенных элементов </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function checkControl() {
/* Если пользователь щелкает по отключенному элементу управления, то данный код отображает сообщение об ошибке, если оно существует */
var el = event.srcElement;
if (el.disabled) {
var msg = el.getAttribute("disabledError");
if (null != msg) alert(msg);
else
alert("You clicked on a disabled element.");
}
}
</SCRIPT>
</HEAD>
<BODY ONCLICK="checkControl()">
<INPUT TYPE=BUTTON DISABLED VALUE="Demo"
disabledError = "This element is disabled because...">
</BODY>
</HTML>

Примечание: В ранних проектах HTML был предложен атрибут ERROR для внутренних элементов управления. Не следует добавлять индивидуальный атрибут error для гарантии отсутствия конфликтов, если данный атрибут станет частью рекомендаций HTML в будущем.



Программирование текстовых элементов Input

В HTML поддерживаются перечисленные ниже четыре типа текстовых элементов управления для запроса информации у пользователя:

Элемент Input TEXT создает текстовое окно с одной строкой, а элемент TextArea создает текстовое окно со множеством строк. Элемент Input PASSWORD представляет текстовое окно с одной строкой, в которой вводимые пользователем символы отображаются в виде звездочек (*). Элемент Input FILE отображает текстовое окно и кнопку, с помощью которой пользователь Может выбрать локальный файл. При отправке формы содержание выбранного файла отправляется обратно на сервер.

Примечание: Элемент TextArea, так же как и любой другой элемент, который отображает полосы прокрутки в динамическом HTML, представляет свойства scrollTop, scrollLeft, scrollwidth и scrollHeight. Данные свойства обеспечивают полный набор возможностей для изменения размера вывода на экран содержания документа. Более подробную информацию о данных четырех свойствах можно найти в главе 9.

Различные текстовые элементы Input в HTML на данный момент не имеют встроенных возможностей по проверке и форматированию пользовательского ввода. До появления сценариев эти функциональные возможности приходилось реализовывать на сервере, что часто приводило к росту трафика между сервером и клиентом. С помощью сценариев на клиентской стороне и возможностей динамического HTML вы можете форматировать и проверять вводимую пользователем информацию мгновенно на стороне клиента. В данном разделе внимание сосредоточено на проверке введенной пользователем информации.



Доступ к содержанию элемента управления

Содержание текстовых элементов input представлено с помощью свойства value или innerText для прямого доступа к содержанию как строке и метода createTextRange для расширенного доступа к символам, словам или предложениям содержания. Свойство innerText является псевдонимом свойства value. Данные свойства используются взаимозаменяемо.

Манипулирование текстом с помощью объекта TextRange обсуждается в главе 14. В данной главе внимание обращено на использование свойства value для манипулирования содержанием элемента управления.



Элемент загрузки файлов

Тег <INPUT TYPE=FILE> позволяет загружать на сервер содержание файла, имя которого указано в текстовом окне. По соображениям безопасности элемент File Upload (Загрузка файлов) имеет ограниченную объектную модель. Элемент File Upload поддерживается в Netscape Navigator версий 3.0 и более поздних и в Internet Explorer 3.02 и более поздних версиях. Свойство value данного элемента предназначено только для чтения и содержит имя файла и путь, а не содержание файла. В элементе File Upload поддерживаются события, но их использование сильно ограничено, так как вы не можете манипулировать введенной пользователем информацией. При необходимости можно использовать данные события и свойство value, чтобы проверить был ли выбран файл.



Проверка введенной пользователем информации

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


Проверка во время ввода пользователем текста

Проверка каждого вводимого пользователем символа может выполняться путем отслеживания событий клавиатуры: keypress, keydown и keyup. Событие keypress является самым полезным событием для отслеживания ввода с клавиатуры, поскольку действие по умолчанию события keypress заключается в обработке вводимого символа. Возврат значения false в данное событие препятствует обработке символа, поэтому символ не будет присоединен к введенной пользователем информации. Приведенный ниже пример иллюстрирует установку ограничения для ввода в текстовом окне только числовой информации.


<HTML>
<HEAD>
<TITLE> Проверка во время набора пользователем текста </TITLE>
</HEAD>
<BODY>
<LABEL FOR="age">Age</LABEL>
<INPUT ID="age" TYPE=TEXT SIZE=3
ONKEYPRESS="if ((event.keyCode < 48) ||
(event.keyCode > 57)) event.returnValue = false;">
</BODY>
</HTML>

В данном текстовом окне можно вводить только значения ASCII в диапазоне от 48 до 57, которые представляют цифры на клавиатуре от 0 до 9. Любые другие символы, введенные пользователем, будут проигнорированы.


Проверка после выхода пользователя из элемента управления

Немедленная проверка наиболее полезна для фильтрации вводимых пользователем данных. Более общим подходом является проверка введенной пользователем информации после окончания ввода. При вводе недействительных значений будет выведено уведомление с использованием одного из двух следующих методов:

Оба метода используют событие onchange, которое запускается в момент выхода пользователя из внутреннего элемента после изменения значения. Событие onchange генерируется для данного элемента непосредственно перед событием onblur. Оно может быть использовано для проверки введенных пользователем данных и затем для отображения диалогового окна или изменения внешнего вида формы на основе ввода. Отмена события onchange запрещает пользователю выход из элемента управления при навигации на данной странице. Если пользователь переходит на другую страницу, то отмена данного события не отменяет возможности перехода.

Приведенный ниже код демонстрирует изменение стиля элемента на основе введенного значения. Данный метод подробно описан в главе 11. Динамическое изменение стиля полезно для обеспечения ясной обратной связи с пользователем.


<HTML>
<HEAD>
<TITLE> Проверка при выходе из элемента управления - метод 1 </TITLE>
<STYLE TYPE="text/css">
.badValue {background:red; color:white}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function validateNumber() {
// Получение исходного элемента.
var el = event.srcElement;
// Valid numbers
var num = "0123456789";
event.returnValue = true;
/* Циклическая проверка содержания. Если обнаруживается символ, не являющийся числом, то возвращается значение false. */
for (var intLoop = 0; intLoop < el.value.length; intLoop++)
if (-1 == num.indexOf(el.value.charAt(intLoop))) event.returnValue=false;
if (!event.returnValue) // Неправильное значение
el.className = "badValue"; // Изменение класса.
else
// Сброс класса для использования воспроизведения по умолчанию.
el.className="";
}
</SCRIPT>
</HEAD>
<BODY>
<LABEL FOR="Age">Age:</LABEL>
<INPUT ID="Age" TYPE=TEXT SIZE=3 TITLE="Enter your age"
ONCHANGE="validateNumber();">
</BODY>
</HTML>

Вместо изменения стиля элемента вы можете предупредить пользователя с помощью диалогового окна Alert о том, что введено недействительное значение. Приведенный ниже код демонстрирует вывод предупреждение, если пользователь вводит недействительное значение в поле State. Кроме того, данный код демонстрирует выполнение элементарного форматирования, переводя введенные пользователем символы в верхний регистр.


<HTML>
<HEAD>
<TITLE> Проверка при выходе из элемента управления - метод 2 </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function checkState(check) {
var states = "ALAKAZARCACOCTDEDCFLGAHIIDILINIAKS";
states += "KYLAMEMDMAMIMSMNMOMTNENMNVNHNJNMNY";
states += "NCNDOHOKORPARISCSDTNTXUTVTVAWAWVWIWY";
// Приведенный ниже код проверяет ввод провинций Канады. /* Провинции Канады добавляются только в случае, если указан второй параметр, значение которого равно true. */
if (arguments[1])
states += "ABBCMBNBNFNSONPEPQSK";
/* Если строка не обнаружена в четной позиции, то штат является недействительным. */
return (0 == (states.indexOf(check) % 2));
}
</SCRIPT>
</HEAD>
<BODY>
<LABEL FOR="state">State:</LABEL>
<INPUT ID="state" TYPE=TEXT SIZE=2 MAXLENGTH=2
ONCHANGE="this.value = this.value.toUpperCase();
if (!checkState(this.value)){
alert('Invalid State');
return false;}">
</BODY>
</HTML>


Проверка при отправке формы

Можно использовать проверку при отправке данных формы, чтобы выяснить, является ли связанная информация действительной или для обеспечения передачи всей запрашиваемой информации. Например, если пользователь указывает, что он состоит в браке, то может также потребоваться ввести имя супруга (или супруги). Приведенный ниже код демонстрирует расширение текстового окна с помощью атрибута required гарантирующего его заполнение пользователем:


<HTML>
<HEAD>
<TITLE> Проверка при отправ.ке пользователем формы </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function isEmpty(str) {
// Проверка, является ли строка пустой.
for (var intLoop = 0; intLoop < str.length; intLoop++)
if (" " != str.charAt(intLoop))
return false;
return true;
}
function checkRequired(f) {
var strError = "";
for (var intLoop = 0; intLoop<f.elements.length; intLoop++)
if (null!=f.elements[intLoop].getAttribute("required")) if (isEmpty(f.elements[intLoop].value))
strError += " " + f.elements[intLoop].name + "\n";
if ("" != strError) {
alert("Required data is missing:\n" + strError);
return false;
}
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="demo" ONSUBMIT="return checkRequired(this);">
User Name: <INPUT TYPE=TEXT NAME="User Name" required><BR>
E-Mail Address:
<INPUT TYPE=TEXT NAME="E-Mail Address" required><BR>
Age (optional): <INPUT TYPE=TEXT NAME="Age"><BR>
<INPUT TYPE=SUBMIT VALUE="Submit">
</FORM>
</BODY>
</HTML>


Представление требуемой информации

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


<HTML>
<HEAD>
<TITLE> Представление требуемой информации </TITLE>
<STYLE TYPE="text/css">
.required {background: red}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function isEmpty(str) {
for (var intLoop = 0; intLoop<str.length; intLoop++)
if (" " != str.charAt(intLoop))
return false;
return true;
}
function checkRequired(f) {
for (var intLoop = 0; intLoop<f.elements.length; intLoop++)
if ("required"==f.elements[intLoop].className) {
alert("All red fields are required.");
return false;
}
}
function fixUp(el) {
el.className = isEmpty(el.value) ? "required" : "";
}
function checkChar(el) {
if (32 != event.keyCode) el.className = "";
}
</SCRIPT>
</HEAD>
<BODY> <FORM NAME="demo" ONSUBMIT="return checkRequired(this);">
User Name: <INPUT TYPE=TEXT CLASS="required" ONKEYPRESS="checkChar(this);" ONCHANGE="fixUp(this);"><BR>
E-Mail Address: <INPUT TYPE=TEXT CLASS="required" ONKEYPRESS="checkChar(this);" ONCHANGE="fixUp(this);"><BR>
Age (optional): <INPUT TYPE=TEXT SIZE=3><BR>
<INPUT TYPE=SUBMIT VALUE="Submit">
</FORM>
</BODY>
</HTML>

В данном примере для идентификации необходимых полей вместо определяемого пользователем атрибута required используется атрибут CLASS.



Форматирование введенной пользователем информации

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

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


<HTML>
<HEAD>
<TITLE> Форматирование введенной пользователем информации </TITLE>
<STYLE TYPE="text/css">
.positive {color:green}
.negative {color:red} .badValue {background:red; color:white}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function formatNumber() {
with (event.srcElement) className =
parseInt(value) >= 0 ? "positive" : "negative";
}
function validateNumber() {
// Получение исходного элемента.
var el = event.srcElement;
var num = "0123456789"; // Valid numbers
event.returnValue = true;
// Проверка знака первого символа.
event.returnValue = ("-" == el.value.charAt(0)) ||
(-1 != num.indexOf(el.value.charAt(0)));
/* Циклическая проверка остального содержания. Если
обнаруживается символ, который не является числом, то
возвращается значение false. */
for (var intLoop = 1; intLoop < el.value.length;
intLoop++)
if (-1 == num.indexOf(el.value.charAt(intLoop))) event.returnValue = false;
if (!event.returnValue) // Bad value
el.className = "badValue"; // Change class.
else
// Очистка класса для использования воспроизведения по умолчанию.
el.className = "";
}
function checkFormat() {
event.returnValue = true;
if (null != event.srcElement.validate)
if ("number" == event.srcElement.validate)
validateNumber(); // Sets event.returnValue
if ((null != event.srcElement.getAttribute("format")) &&
(event.returnValue))
if ("number" ==
event.srcElement.getAttribute("format"))
formatNumber();
}
</SCRIPT>
</HEAD>
<BODY>
<INPUT TYPE=TEXT ONCHANGE="checkFormat();" format="number" validate="number">
</BODY>
</HTML>



Использование элементов ввода пароля

Поле Password представляет собой текстовое поле, в котором вводимые пользователем символы отображаются в виде звездочек. Эта мера безопасности полезна, когда пользователь вводит важную информацию. По соображениям безопасности сценарии, выполняющиеся в Internet Explorer 4.0, не могут обращаться к действительным значениям элемента управления. Вместо этого свойство value всегда возвращает знак * для всех вводимых пользователем символов. Звездочки помогают клиентской программе проверить, что был введен пароль и что пароль имеет определенное число символов Связанные с нажатием клавиш события также всегда возвращают символ звездочка (*).

При использовании полей Password для передачи данных следует применять метод POST. В противном случае значение пароля будет отображаться как значение search в отправляемой форме. В любом случае значение не шифруется. Более того, Netscape Navigator в настоящее время отображает реальное введенное значение, а не звездочки, так что поля Password следует использовать аккуратно.



Программирование элементов списков

Элемент select используется для предоставления пользователю списка вариантов. Существуют два типа списков: раскрывающееся поле со списком (combo box) и поле со списком (list box). Данные два типа списков взаимозаменяемы и их модели сценариев идентичны. Единственным исключением является то, что стиль поля со списком может быть использован для создания поля со списком для множественного выбора, что позволяет пользователю выбирать элементы из нескольких полей со списками. На рис. 10.1 показаны три типа списков.

Рис. 10.1. При использовании элемента select доступны три типа списков



Определение поля со списком

Для создания поля со списком используется элемент Select. Элемент Select содержит элементы Options, представляющие каждый элемент списка. Могут быть созданы три типа полей со списками, как показано в приведенном ниже коде:


<HTML>
<HEAD>
<TITLE> Типы списков </TITLE>
</HEAD>
<BODY>
<FORM NAME="lists">
<SELECT NAME="combostore">
<OPTION VALUE="Computer" SELECTED>Computer</OPTION>
<OPTION VALUE="Bookstore">Book Store</OPTION>
<OPTION VALUE="MailOrder">Mail Order</OPTION>
</SELECT>
<SELECT NAME="liststore" SIZE=3>
<OPTION VALUE="Computer" SELECTED>Computer</OPTION>
<OPTION VALUE="Bookstore">Book Store</OPTION>
<OPTION VALUE="MailOrder">Mail Order</OPTION>
</SELECT>
<SELECT NAME="multistore" SIZE=3 MULTIPLE>
<OPTION VALUE="Computer" SELECTED>Computer</OPTION>
<OPTION VALUE="Bookstore">Book Store</OPTION>
<OPTION VALUE="MailOrder" SELECTED>Mail Order</OPTION>
</SELECT>
</FORM>
</BODY>
</HTML>

Определение атрибута приводит к образованию поля со списком вместо раскрывающегося поля со списком. Значение атрибута SIZE определяет число отображаемых строк. Для создания нескольких полей со списками следует определить атрибут MULTIPLE. Если атрибут MULTIPLE указан без атрибута SIZE, то автоматически создается поле со списком, содержащее четыре строки.



Добавление стилей в поле со списком

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


<HTML>
<HEAD>
<TITLE> Селектор цветов </TITLE>
</HEAD>
<BODY>
<SELECT STYLE="width:75pt">
<OPTION STYLE="background:red; color:white" VALUE="RED">
Red
</OPTION>
<OPTION STYLE="background:navy; color:white" VALUE="NAVY">
Navy
</OPTION>
<OPTION STYLE="background:black; color:white" VALUE="BLACK">
Black
</OPTION>
<OPTION STYLE="background:white; color:black" VALUE="WHITE">
White
</OPTION>
</SELECT>
</BODY>
</HTML>

Стиль для выбранных Элементов в списке в данном примере не изменяется.



Связь списка с отправляемым значением

Содержание элемента Option отображается на экране, но это отображаемое значение не отправляется обратно на сервер. Вместо этого значения отправляется атрибут value, который должен быть определен в теге <ОРТION>. В общем, при использовании элемента Select внутри отправляемой формы каждый вариант должен иметь атрибут value. Для списков, которые манипулируются сценарием и не отображаются на экране, может быть использован атрибут value, или сценарии могут непосредственно учитывать значение свойства text.



Программирование содержания списка

Семейство options представляет элементы Option, содержащиеся в элементе Select. Каждый вариант в данном семействе представляет свои атрибуты, а также содержание, ограниченное открывающими и закрывающими тегами элемента Option, которые представлены с помощью свойства text.


Элементы Option

Элементы Option в документе являются исключением в объектной модели динамического HTML, поскольку они не представлены в семействе all документа. Кроме того, элемент Option не предоставляет никаких дополнительных событий или свойств помимо стандартного набора атрибутов и свойства text. Элемент option представлен только родительским элементом Select, владеющим всеми взаимодействиями со списком, включая события.


Добавление и удаление элементов списка

Вы можете динамически добавлять или удалять элементы из поля списка. Данный метод позволяет настраивать список в ответ на ввод информации пользователем.

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

Семейство options поддерживает способность динамического добавления или удаления элементов. Элементы создаются с использованием метода createElement или с помощью оператора new, как показано ниже:


var elOption = createElement("OPTION");
// or
var elOption = new Option; // Netscape Navigator // поддерживает данный метод.

Затем варианты добавляются в поле со списком при помощи метода add в семействе options или удаляются с помощью метода remove. Варианты могут быть добавлены или удалены путем назначения варианта непосредственно индексу массива или путем установки существующего параметра, равным null. Данный метод поддерживается для совместимости с Netscape Navigator. Приведенный ниже код сравнивает использование данных мето-дов в поле со списком lb в форме с именем demo:


var elOption = new Option();
// Add and remove using methods.
document.demo.lb.options.add(elOption, 0); // Добавляет первый элемент.
document.demo.lb.options.remove(2); // Удаляет третий элемент.
// Add and remove using Netscape Navigator-compatible technique.
document.demo.lb.options[0] = elOption; // Добавляет первый элемент.
document.demo.lb.options[2] = null; // Удаляет третий элемент.

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


<HTML>
<HEAD>
<TITLE> Список закладок </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function addNew(text, value) {
// Добавляет новый вариант. var el = document.createElement("OPTION");
el.text = text;
el.value = value;
document.all.bm.options.add(el);
}
function buildList() {
/* При добавлении нового элемента списка текст является содержанием якоря, а значением является имя закладки. Значение используется для прокручивания элемента в окне. */
for (var intLoop = 0; intLoop < document.anchors.length;
intLoop++) addNew(document.anchors[intLoop].innerText,
document.anchors[intLoop].name);
}
function scrollit(where) {
// Прокручивает выбранную закладку в области просмотра.
document.all[where.value].scrollIntoView();
// Сброс поля со списком.
where.value = null;
}
</SCRIPT>
</HEAD>
<BODY ONLOAD="buildList();">
<LABEL FOR="bm">Bookmarks: <SELECT ID=bm STYLE="width:100pt" ONCHANGE="scrollit(this);">
</SELECT>
<H1><A NAME="Contents">Contents</A><H1>
Table of Contents
<H2><A NAME="Abstract">Abstract</A></H2>
About this document
<H2><A NAME="Chapter1">Chapter 1</A></H2>
Chapter 1
<H2><A NAME="Summary">Summary</A></H2>
Summary contents
</BODY>
</HTML>



Программирование множественного выбора в поле со списком

Поле со списком, допускающее множественный выбор (multiple-select list box), позволяет пользователю выбрать более одного элемента. В поле со списком с множественным выбором свойство value возвращает только первый выбранный элемент. Для определения всех выбранных элементов должен быть перечислен весь список элементов с помощью сценария. Приведенная ниже функция демонстрирует построение массива из элементов, которые выбраны из поля со списком. (При использовании данной функции для поля со списком с одиночным выбором полученный в результате массив будет содержать только одно значение).


<SCRIPT LANGUAGE="JavaScript">
function getSelected(opt) {
var selected = new Array();
var index = 0;
for (var intLoop=0; intLoop < opt.length; intLoop++) {
if (opt[intLoop].selected) {
index = selected.length;
selected[index] = new Object;
selected[index].value = opt[intLoop].value;
selected[index].index = intLoop;
}
}
return selected;
}
</SCRIPT>


Использование флажков для небольших списков

Если число вариантов в списке невелико, то может оказаться разумнее использовать набор флажков вместо поля со списком с множественным выбором. Путем совместного использования одного имени для всех флажков в наборе для флажков может быть установлена модель отправки, аналогичная модели поля со списком с множественным выбором. Приведенная выше функция может быть переписана, как показано в следующем коде, для определения выбранных флажков. Вместо перечисления элементов семейства options, находящихся в элементе Select, вы должны перечислить элементы Form с данным именем. Вместо передачи семейства options функции используется семейство флажков. Еще одним отличием является то, что флажки представляют свойство checked для определения, были ли они выбраны, в то время как поле со списком использует свойство selected. Поэтому условие в функции проверяет свойства selected и checked.


<HTML>
<HEAD>
<TITLE> Поле со списком для множественного выбора </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function getSelected(opt) {
var selected = new Array();
var index = 0;
for (var intLoop = 0; intLoop < opt.length; intLoop++) {
if ((opt[intLoop].selected) ||
(opt[intLoop].checked)) {
index = selected.length;
selected[index] = new Object;
selected[index].value = opt[intLoop].value;
selected[index].index = intLoop;
}
}
return selected;
}
function outputSelected(opt) {
var sel = getSelected(opt);
var strSel = "";
for (var item in sel) strSel += sel[item].value + "\n";
alert("Selected Items:\n" + strSel);
}
</SCRIPT> </HEAD>
<BODY> <FORM NAME="ColorSelector">
<INPUT TYPE=CHECKBOX NAME="color" VALUE="Red">Red
<INPUT TYPE=CHECKBOX NAME="color" VALUE="Navy" CHECKED>Navy
<INPUT TYPE=CHECKBOX NAME="color" VALUE="Black">Black
<INPUT TYPE=CHECKBOX NAME="color" VALUE="White" CHECKED>White
<INPUT TYPE=BUTTON VALUE="Selected Check Box Items" ONCLICK="outputSelected(this.form.color);">
<P>
<SELECT NAME="multistore" SIZE=3 MULTIPLE>
<OPTION VALUE="Computer" SELECTED>Computer</OPTION>
<OPTION VALUE="Bookstore">Book Store</OPTION>
<OPTION VALUE="MailOrder" SELECTED>Mail Order</OPTION>
</SELECT>
<INPUT TYPE=BUTTON VALUE="Selected List Items" ONCLICK="outputSelected(this.form.multistore.options)">
</FORM>
</BODY>
</HTML>



Программирование списков с использованием кнопок-переключателей и флажков

Кнопки-переключатели и флажки воспроизводятся аналогично, но разным целям. Кнопки-переключатели используются для представления набора из двух или более взаимоисключающих вариантов. Флажки используются для выбора решения с учетом двух или большего количества независимых установок.

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

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



Кнопки-переключатели

Кнопки-переключатели (radio buttons) представлены как группа, подобно вариантам в окне со списком для одиночного выбора. Как упоминалось выше, определение одного имени для кнопок внутри одной области действия приводит к созданию группы. Взаимное исключение на основе имени поддерживается только для кнопок-переключателей. При отправке формы с группой кнопок-переключателей отправляется только значение выбранной кнопки-переключателя. Назначение того же имени любому другому типу элементов управления не приводит к появлению специального поведения при отправке. Когда элементы управления, которые не являются кнопками-переключателями, совместно используют одно имя, то все пары имя-значение отправляются соответствующим образом, в зависимости от правил для каждого элемента управления - например, отправляются только выбранные именованные флажки и все именованные текстовые окна.


Поддержка пользовательских элементов списка

Кнопки-переключатели полезны для предоставления возможных ответов при проведении опросов. Иногда возникает необходимость предоставить возможность пользователю самому дать ответ на вопрос, если не подходят все указанные варианты ответа. Приведенный ниже код демонстрирует пробой способ создания текстового окна для индивидуальных ответов, если пользователь не нашел подходящего варианта среди предложенных. Текстовый элемент управления активизируется только после выбора параметра Other (Другие).


<HTML>
<HEAD>
<TITLE> Индивидуальный ввод </TITLE>
<SCRIPT LANGUAGE="JavaScript">
function checkRadio(f) {
f.Custom.disabled = !f.Q1["Other"].checked;
if ("Other" == event.srcElement.id)
f.Custom.focus(); }
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="Demo" ONCLICK="checkRadio(this);">
<FIELDSET>
<LEGEND>Where did you buy this book?</LEGEND>
<P><INPUT ID="BStore" TYPE=RADIO NAME="Q1"
VALUE="Bookstore">
<LABEL FOR="BStore"> Bookstore</LABEL>
<P><INPUT ID="MOrder" TYPE=RADIO NAME="Q1"
VALUE="Mail Order">
<LABEL FOR="MOrder"> Mail Order</LABEL>
<P><INPUT ID="CStore" TYPE=RADIO NAME="Q1"
VALUE="Comp Store">
<LABEL FOR="CStore"> Computer Store</LABEL>
<P><INPUT ID="Other" TYPE=RADIO NAME="Q1">
<LABEL FOR="Other"> Other: </LABEL>
<INPUT ID="Custom" NAME="Other" TYPE=TEXT DISABLED>
</FIELDSET>
</FORM>
</BODY>
</HTML>

Данный код работает правильно независимо от того, щелкнет ли пользователь по надписи Other или самой кнопке-переключателю, поскольку когда пользователь щелкает по надписи, то сначала генерируется событие onclick с элементом srcElement в качестве надписи и затем данное событие генерируется снова с элементом srcElement в качестве кнопки-переключателя. Обработчик событий onclick также запускается, если выбрана кнопка-переключатель с помощью клавиатуры, поскольку событие связано не с мышью, а с операцией изменения значения элемента управления. По данной причине одного обработчика событий onclick для кнопки-переключателя достаточно для отслеживания любых возможных изменений.



Флажки

Флажки (check boxes) полезны для создания вопросов, на которые требуется простой ответ типа да/нет. Во многих случаях текстовые поля используются при необходимости определения дополнительной информации. Создав простой код, вы можете сделать установку флажка условием активизации определенных полей в форме. В приведенном ниже коде, если пользователи запрашивают дополнительную информацию, то они должны ввести имя и адрес электронной почты. Если дополнительная информация не запрашивается, то эти поля не используются.


<HTML>
<HEAD>
<TITLE> Активизация полей ввода </TITLE>
</HEAD>
<BODY>
<FORM NAME="Info">
<LABEL FOR=INFO>Send Info:</LABEL>
<INPUT ID=INFO TYPE=CHECKBOX
ONCLICK="document.all.address.fieldset.disabled =
!this.checked;">
<BR>
<FIELDSET NAME="address" DISABLED>
<LEGEND>Address Information</LEGEND>
<LABEL FOR="email">E-Mail Address:</LABEL>
<INPUT TYPE=TEXT NAME="email">
<LABEL FOR="snailMail">Street Address:</LABEL>
<TEXTAREA ROWS=3 COLS=40></TEXTAREA>
</FIELDSET>
</FORM>
</BODY>
</HTML>

Примечание: На данный момент отсутствует метод для изменения воспроизведения по умолчанию отключенных элементов управления.


Состояние неопределенности

Флажки поддерживают состояние неопределенности, что позволяет флажкам находиться в одном из трех состояний: включено (on), выключено (off) и неопределенное (unknown). Предположим, что вы используете флажок, чтобы выяснить, набран ли выбранный текст шрифтом с полужирным начертанием. Неопределенное состояние возникнет, когда часть выбранного текста будет набрана полужирным шрифтом, а другая часть - обычным шрифтом. Состояние неопределенности может быть установлено только посредством объектной модели, используя свойство indeterminate для флажка. Свойство indeterminate представляет собой логическое значение - если свойство имеет значение true, то флажок будет отображен в неопределенном состоянии.

Свойство checked неопределенного флажка возвращает значение флажка до его перехода в неопределенное состояние. Даже если неопределенный флажок всегда остается неизменным в пользовательском интерфейсе. Значение флажка отправляется в зависимости от значения его свойства checked, независимо от того, находится ли флажок в неопределенном состоянии или нет. На рис. 10.2 показаны флажки в различных состояниях.

Рис. 10.2. Возможные состояния флажков

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



Событие onclick

Для кнопок-переключателей и флажков событие onclick ведет себя несколько по-иному, чем для других элементов. Событие onclick запускается до выполнения действия по умолчанию, что дает Web-автору возможность его отмены. Для флажков действие по умолчанию заключается в выборе или отключении элемента, а для кнопок-переключателей действие по умолчанию заключается в выборе элемента. Когда событие onclick генерируется для этих событий, то значение элемента управления уже представляет новое значение для элемента. Отмена действия по умолчанию приводит к актуализации предыдущего значения. Данный процесс отличен для других элементов, состояние которых не изменяется до возникновения события.



Программирование элементов командных кнопок

Командные кнопки создаются с использованием стандартного элемента Input или элемента Button. Элемент Input поддерживает три типа командных кнопок: отправка, сброс и просто текст. Элемент Button является новым элементом в Internet Explorer 4.0 и обеспечивает способность создания элементов с форматированием HTML.



Определение кнопок по умолчанию и отмены

Кнопки отправки и сброса ведут себя как кнопки Default (По умолчанию) и Cancel (Отмена) в контексте формы или области действия документа. Кнопка Default первоначально отображается с дополнительной рамкой вокруг нее и определяет действие по умолчанию, которое возникает при нажатии пользователем клавиши <Enter>. Кнопка Cancel определяет действие, происходящее при нажатии пользователем клавиши <Esc>.

Внутри области действия формы кнопки отправки и сброса представляют собой командные кнопки, для которых установлено определенное поведение отправки или сброса содержания формы. За пределами формы данные кнопки ведут себя как стандартные командные кнопки Default и Cancel. Во всех случаях вызов модели поведения кнопки Default или Cancel с помощью клавиатуры запускает событие click в соответствующем элементе кнопки.

Кнопки отправки и сброса определены с помощью атрибута TYPE элемента Input или Button, как показано ниже:


<FORM NAME="User">
<INPUT TYPE=TEXT NAME="User" VALUE="User Name">
<INPUT TYPE=RESET VALUE="Reset the Form">
<INPUT TYPE=SUBMIT VALUE="Submit the Form">
<BUTTON TYPE=SUBMIT><EM>Submit</EM> the Form</BUTTON>
</FORM>

В форме или области действия документа может быть только одна кнопка Default и одна кнопка Cancel. Если в некоторой области действия определено несколько кнопок Default или Cancel (то есть, более одной кнопки отправки или сброса), то в данной области будет использована первая определенная в коде HTML кнопка каждого типа.



События кнопок и форм

Если требуется код, который будет выполняться для моделей поведения отправки или сброса формы, то следует написать код для событий onsubmit и onreset формы, но не события onclick кнопок отправки и сброса, поскольку форма может быть случайно отправлена или сброшена без получения кнопкой события onclick. Например, если форма имеет одно текстовое окно, кнопку отправки и кнопку сброса, то нажатие клавиши <Enter>, пока курсор находится в текстовом окне, автоматически отправляет значение, но кнопка отправки не получает событие onclick. Аналогично, если пользователь нажимает клавишу <Esc>, то кнопка сброса не получает события onclick, но генерируется событие onreset.



Создание кнопок при помощи элемента Button

Вы можете создать кнопку в коде HTML, используя тег <INPUT TYPE=BUTTON> или более общие теги <BUTTON> ... </BUTTON>. Приведенный ниже код создает кнопки отправки и сброса с надписями:


<FORM NAME="test">
<BUTTON TYPE=SUBMIT>
<H1>Submit this form.</H1>
</BUTTON>
<BUTTON TYPE=RESET>
<H2>Reset this form.</H2>
</BUTTON>
</FORM>

Поместив HTML в элемент Button, можно создать интересные эффекты для кнопки. Хотя код HTML и стиль могут быть определены для содержания, но модель событий ограничена в сравнении с остальной частью динамического HTML.


События кнопки

Как показано в приведенном ниже коде, элемент Button поддерживает форматирование HTML, но элементы внутри кнопки не генерируют события. Поэтому нельзя написать обработчики событий для элементов, которые существуют внутри кнопки.


<!-- The event handlers defined in this button do not fire. -->
<BUTTON>
<H1 ONCLICK="alert('clicked!');">Click Me!</H1>
<H2 ONMOUSEOVER="this.style.color = 'red';">Turn red.</H2>
</BUTTON>

Напротив, все события элементов внутри элемента Button направляются непосредственно кнопке.


Содержание кнопки

Содержание кнопки представлено различно в зависимости от того, с помощью каких тегов определена кнопка: тега <INPUT> или <BUTTON>. Содержание кнопки, созданной с помощью тега <INPUT>, представлено свойствами value и innerText, аналогично другим типам Input. Содержание кнопки, созданной с помощью тега <BUTTON>, представлено свойствами innerText и innerHTML, а не свойством value. Подобно элементу TextArea кнопка, созданная с помощью тега <BUTTON>, также предоставляет расширенный доступ к содержанию с помощью метода createTextRange.



Программирование элементов Label и Fieldset

Надписи используются для связи содержания HTML с элементом Input, a наборы полей применяются для группирования нескольких элементов управления. Элементы Label и Fieldset в настоящее время поддерживаются только браузером Internet Explorer 4.0.

Элемент Fieldset полезен при группировании различных элементов ввода пользователем в одной форме - например, для группирования адресов отправки и получения в одной форме. Элемент Fieldset не имеет дополнительных элементов в объектной модели кроме стандартных событий и их атрибутов. Однако совместно с процедурой всплывания событий элементы Fieldset могут быть использованы для обеспечения индивидуального поведения групп элементов управления.

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



Элемент Label и события onclick

Элемент Label оказывает интересное влияние на модель событий. Действие по умолчанию при щелчке по элементу Label заключается в том, что связанный элемент управления получает фокус. Поэтому, когда пользователь щелкает по элементу Label, этот элемент и все его родительские элементы получают событие onclick. Если действие по умолчанию не отменяется, то указанный элемент управления получает фокус. Если указанный элемент является флажком или кнопкой-переключателем, то событие onclick затем всплывает снова из этого элемента управления. Второе всплывание дает возможность щелкать по надписи кнопки-переключателя или флажка для изменения значения элемента.

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