Форма является единственным средством, которое предоставляет пользователю возможность вводить данные в Web-документы без помощи каких-либо программ. Взаимодействие JavaScript-программ и форм обеспечивается за счет того, что в языке JavaScript имеется множество объектов, соответствующих HTML-тегам, которые могут присутствовать в теге <form>. Из этой главы вы узнаете: — Как JavaScript-программа обращается к формам, содержащимся в HTML-документе — Как обращаться к селекторным кнопкам и спискам — Как определять обработчики событий для элементов форм — Как использовать JavaScript-программы для проверки правильности данных, введенных в форму
Взаимодействие HTML-форм и языка JavaScript
Язык JavaScript расширил возможности многих элементов форм, главным образом благодаря возможности определения функций-обработчиков событий. При щелчке мыши или выборе нового элемента из списка возникают события, которые можно перехватывать и обрабатывать в JavaScript-программе. В этой главе рассмотрены принципы взаимодействия JavaScript-программ с такими элементами форм, как поля ввода (text field), контрольные переключатели (checkbox), селекторные кнопки (radio button) и списки (selection list). Здесь также описаны возможности динамического обновления этих элементов и управления ими при помощи JavaScript-программ.
Тег <fopm>
Любой элемент формы определятся в контейнере <form>...</form>. Таким образом, поля ввода (text-field), области текста (text-area), селекторные кнопки, списки и контрольные переключатели не могут располагаться вне этого контейнера. Поля формы предоставляют возможность вводить данные и сохранять их для дальнейшей обработки. До появления языка JavaScript формы были единственным способом ввода данных в HTML-документы. В языке JavaScript имеется собственный метод (prompt()), обеспечивающий ввод текста, однако формы в этом случае предоставляют все же больше удобств. Тег <form> языка HTML имеет следующий синтаксис:
<form name = "formName"
[method = "POST|GET"]
[action = "URL"]
[enctype = "type"]
[onSubmit = "function()|expression"]
form tag elements
</form>
Атрибут name задает имя формы, а атрибут enctype — тип кодирования для передаваемых данных формы (по умолчанию используется MIME). Посредством атрибута method определяется метод передачи данных формы, а посредством атрибута action — адрес URL для CGI-скрипта, который вызывается на сервере для обработки данных формы. Атрибут обработчика события on Submit используется для указания JavaScript-программы, вызываемой при активизации кнопки передачи данных. Эта кнопка задается в теге <input type="submit">.
Интерфейс CGI и язык JavaScript
До появления броузера Navigator 2.0 и языка JavaScript данные HTML-формы обрабатывались только с помощью CGI-скрипта, работающего на сервере. Интерфейс CGI (Common Gateway Interface) — это стандарт обслуживания запросов, широко применяемый на интерактивных Web-узлах. Главным в концепции интерфейса CGI является CGI-скрипт (программа, которая принимает данные, передаваемые клиентом). Данные формы посылаются клиентом в закодированном виде. Скрипты, как правило, преобразовывают их для чтения и записывают в обычный текстовый файл или в базу данных на сервере. Программы CGI используются в разных целях, например для ведения журналов посещений (guest-book), для обработки данных форм HTML, электронной почты и даже для игр. При помощи языка JavaScript проверка правильности введенной пользователем информации может выполняться на локальной клиентской станции и в большинстве случаев не требует передачи данных на сервер. Значения атрибутов method и action используют главным образом разработчики программ CGI, которые принимают и обрабатывают данные формы. Возможности языка JavaScript по хранению данных ограничены: в настоящее время "ключики" (cookie) являются единственным способом хранения данных на локальном диске (см. главу 13), хотя серверный JavaScript-модуль в продукте Live Wire компании Netscape предоставляет возможность ведения баз данных. Программы на языке JavaScript предназначены для локальной обработки данных. Одной из главных проблем, возникающих при обработке данных форм, является проверка правильности таких данных, и язык JavaScript может помочь в этом. Если на локальном компьютере не производится проверки правильности форм, выполнение этой задачи должен взять на себя сервер. Тогда увеличится не только нагрузка на сервер, но и время реакции системы в целом, поскольку данные формы сначала передаются серверу, который проверяет их и при обнаружении ошибок пересылаются обратно вместе с сопроводительным сообщением. При большом количестве ошибок многократная передача исправленных данных занимает много времени и ресурсов. Проверка правильности данных формы при помощи JavaScript-программы перед передачей их на сервер имеет большие преимущества: во-первых, экономится время, а во-вторых, облегчается сетевой трафик. Кроме того, сервер, принимая данные формы, не выполняет проверки, предполагая, что переданная ему информация является полной и корректной.
Элементы Формы
Контейнер <f orm>... </form> может содержать любой из приведенных в следующей таблице тегов элементов формы языка HTML.
Описание
Тег элемента Формы
Контрольный переключатель
<input type="checkbox">
Кнопка передачи формы
<input type="submit">
Скрытое поле
<input type="hidden">
Кнопка
<input type="button">
Селекторная кнопка
<input type="radio">
Список
<selectx/select>
Поле ввода
<input type="text">
Область текста
<textarea></textarea>
Каждый из этих элементов формы в языке JavaScript представляется в виде свойства объекта form и описывается ниже в этой главе.
Как язык JavaScript работает с Формами
Каждому контейнеру <form>...</form>, считанному в броузер Navigator, в языке JavaScript соответствует объект form. Кроме того, каждый такой объект является элементом массива forms, например forms[0] — первая форма текущего HTML-документа, и каждому элементу формы, например селекторной кнопке, списку или полю ввода, в языке JavaScript соответствует определенный объект. Для обращения к таким объектам и для работы с ними необходимо понять иерархию объектов HTML-документа. Рассмотрим HTML-документ, содержащий две формы:
<!--
Program 7-1
-->
<html>
<head>
<title>Some sample forms</title>
</head>
<body>
<basefont size=4>
<tt>
<form name="forml">
Введите ваше имя <input type="text" size=30 name="fullname"><p>
После загрузки в броузер Navigator этот документ будет иметь вид, как показано на рис.7.1. Некоторые элементы формы уже выделены или заполнены данными.
Рис. 7.1. Формы, загруженные в броузер Navigator
При загрузке этого документа в броузер интерпретатор языка JavaScript автоматически создаст соответствующий объект для каждого элемента формы. Например, к контейнерам <form> из JavaScript-программы можно обратиться с помощью выражений document.forms[0] и document.forms[1]. Поскольку в первой форме определен атрибут name, к ней позволяет обратиться и выражение document. forms ["forml" ]. Учтите, что последний способ обращения неприменим для второй формы, потому что атрибут name для нее не указан. Если имя формы задано, то для обращения к форме лучше использовать выражения вида document.form1, а не массив forms. Таким образом, атрибуты, определенные в теге формы, позволяют по-разному обратиться к этой форме из программы. Для обращения к первому полю ввода, заданному в первой форме, применяется выражение document.forms[0].fullname (или document.form1.fullname). Для определения текста, введенного в это поле, служит атрибут value. Например, значением выражения document.forms[0].fullname.value в предыдущем примере является строка "Jason" (рис.7.1). Этот текст можно также динамически обновлять, поскольку поле ввода является структурой для чтения/записи. Следующие элементы формы — это два контрольных переключателя с именами cdl и cd2. В JavaScript-программе им соответствуют объекты document.forms[0].cd1 и document.forms[0].cd2. Свойство checked объекта checkbox позволяет определить, включен переключатель в данный момент или нет. В нашем примере (рис.7.1) значением выражения document.forms[0].cd1. checked является true, поскольку контрольный переключатель с именем cdl включен. Благодаря тому, что для каждого контрольного переключателя определен атрибут value, значение любого из этих элементов может быть считано. В данном случае выражение document.forms[0].cd2. value возвратит строку "hhcs". Определять атрибуты value для кнопок различных типов совсем не обязательно, хотя в некоторых приложениях все же необходимо связывать значение value с селекторной кнопкой для обеспечения дальнейшей обработки информации. Определение атрибутов name иногда также не является обязательным. К объектам, для которых атрибут name не определен, следует обращаться как к элементам массива elements, представляющего собой список всех объектов, содержащихся в форме в том порядке, в котором они указаны в исходном документе. Поэтому значением выражения doсument.fоrms[0].еlеments[2].value в приведенном примере является строка "hhcs". В языке JavaScript номера элементов массива начинаются с нуля, поэтому elements[2] — это третий элемент. Третьим элементом в форме forms[0] является второй контрольный переключатель. Таким образом, запись document.forms[0].elements[2].value равноценна записи document.forms[0].cd2.value. Как видите, язык JavaScript предлагает множество способов для достижения одной и той же цели. Элементы массива elements можно перебирать при помощи оператора for языка JavaScript. Однако учтите, что этот способ неприменим для просмотра массива forms, поэтому рекомендуется присвоить имя каждой форме.
Совет: Значение атрибута name лучше определить для всех элементов HTML-формы. Хотя массив elements также позволяет обращаться к элементам формы, даже если не заданы атрибуты name элементов. Обращение к элементам формы по именам намного удобнее.
Вторая форма в приведенном примере определена в теге, атрибут name в котором отсутствует. Поэтому из JavaScript-программы к ней следует обращаться только как к элементу массива forms[1]. Чтобы облегчить обращение к этой форме и улучшить читаемость программы, значение forms[1] следует присвоить отдельной переменной. Такой прием весьма удобен, особенно если форма находится в другом окне. Первым элементом во второй форме является объект textarea (область текста). К значению, хранящемуся в этом поле, можно обращаться, используя выражение document.forms[1].comments.value, где comments — имя объекта textarea, заданное в атрибуте name тега <textarea>. Если же атрибут name в этом теге отсутствует, необходимо обратиться к массиву elements. Наконец, в HTML-теге <select> определен объект select (список) с именем books. В JavaScript-программе управлять подобными объектами сложнее всего, поскольку они содержат множество значений. Однако, обратившись к свойству selectedlndex, вы сможете определить, какой элемент списка выбран (см. главу 4). Кроме того, одним из свойств объекта-списка является массив options, элементы которого соответствуют тегам <орtion>, заданным в контейнере <select>. Объекты select, в свою очередь, имеют свойство text, соответствующее тексту, который задан после тега <option>. Чтобы определить, какой элемент списка выбран, применяется выражение вида
document.forms[I].books.options.selectedIndex
Если выбран первый элемент списка, это выражение возвратит значение 0, поскольку нумерация элементов списка в языке JavaScript начинается с нуля. Чтобы выяснить, какой текст следует за тегом <option>, можно использовать следующее несколько устрашающее выражение:
Опустив ту часть выражения, которая заключена в скобках массива options[], получим более краткую, хотя и неполную, запись:
document.forms[1].books.options[...].text
Теперь необходимо получить значение индекса массива options. Для этого следует задать выражение, которое возвращает свойство selectedlndex массива options. Чтобы добраться до этого значения, нужно проследить путь вниз по иерархии объектов. Именно поэтому выражение получается настолько длинным. К счастью, такие выражения можно упростить, разбив их на две части: первая получает индекс выбранного элемента, а вторая с помощью этого индекса обращается к содержимому текущего элемента массива:
Переменная it emText содержит текст: "Essential Java*", определяемый тегом <option> (рис. 7.1). Далее рассматриваются особенности различных элементов форм.
Обращение к элементам форм в JavaScript-программах
К определенному элементу формы из JavaScript-программы обращаются одним из двух способов: — путем обращения к заданному в документе имени элемента; — путем передачи содержимого (значения) элемента формы в качествепараметра, используя оператор this. При обращении к элементу формы с использованием его имени, определенного в HTML-форме, необходимо также задать иерархию объектов, начиная с окна верхнего уровня или родительского фрейма и опускаясь к объекту document, а затем к соответствующему массиву forms и имени элемента формы. Например, следующее приложение обращается к требуемому полю формы по его имени.
<!--
Program 7-2
-->
<html>
<head>
<script language="JavaScript">
<!--
function getData() {
alert("Вы ввели строку: " +
document.forms[0].myField.value);
}
</script>
</head>
<body>
<form>
<input name="myField" type="text" size=45><br>
<input type="button"
value=" Click"
onClick="getData()">
</form>
</body>
</html>
В данном случае при щелчке мыши на кнопке для обработки события Click активизируется функция getData(), которая отображает на экране текст, введенный в текстовое поле. Обратите внимание, что для обращения к текстовому полю задано полное имя поля формы, включающее полную иерархию объектов документа. Если данная форма находится не в отдельном окне и не во фреймсодержащем документе, то указывать имя окна в префиксе к объекту document нет необходимости. Выражение, которое обращается к элементу формы, можно записать более компактно, используя оператор this:
<!--
Program 7-3
-->
<html>
<head>
<script language="JavaScript">
function getData(val) {
alert ("Вы ввели строку: " + val);
}
//-->
</script>
</head>
<body>
<form>
<input name="myField" type="text" size==45><br>
<input type="button"
value="Click"
onClick="getData(this.form.myField.value)">
</form>
</body>
</html>
В JavaScript-программе выражение this.form обращается к текущему объекту form. Указав это выражение перед именем элемента формы, к содержимому которого необходимо обратиться, вы передадите этот элемент формы как параметр функции getData(). Обратите внимание, что функция getData() принимает аргумент val, который является литеральным значением текстового поля. Для обращения к литеральному значению элемента формы можно использовать свойство value. Некоторые скрипты передают функции только значение this.form, а затем обращаются к требуемому полю путем добавления имени поля и значения value. Золотое правило обращения к полям заключается в том, что указывая формы, особенно те, которые существуют в отдельных окнах или фреймах, необходимо помнить об иерархии объектов (см. главы 8 и 9).
Управление элементами Форм посредством JavaScript-программ
В этом параграфе мы продолжим рассматривать возможности управления элементами форм в JavaScript-программах. Для элементов форм каждого типа приводятся примеры, демонстрирующие, как управлять этими элементами при помощи программ на языке JavaScript.
Контрольные переключатели
Контрольные переключатели (checkbox) определяют в теге <input type="checkbox">. Они обеспечивают возможность выбора одного или нескольких вариантов и могут иметь два состояния — включено или выключено (on или off). В языке JavaScript контрольному переключателю соответствуют два объекта: — элемент массива elements; — массив, имя которого соответствует значению атрибута name, заданногов теге контрольного переключателя. Рассмотрим документ, содержащий два контрольных переключателя и JavaScript-программу, позволяющую увидеть значения их свойств в окне сообщения, отображаемом при вызове метода alert():
<!--
Program 7-4
-->
<html>
<head>
<script language="JavaScript">
<!--
function showValues() {
alert("CHECKBOX l:\n" +
"value : " +
document.forms[0].cbl.value + "\n" +
"name : " +
document.forms[0].cbl.name + "\n" +
"checked: " +
document.forms[0].cbl.checked + "\n" +
"\nCHECKBOX 2:\n " +
"value : " +
document.forms[0].cb2.value + "\n" +
"name : " +
document.forms[0].cb2.name + "\n" +
"checked: " + document.forms[0].cb2.checked);
}
</script>
</head>
<body>
<form>
Задайте способ платежа:<br>
<input type="checkbox"
name="cb1"
value="VS">Visa<br>
<input type="checkbox"
name="cb2"
value="MC" checked>Mastercard<p>
<input type="button"
value="See values"
onClick="showValues()">
</form>
</body>
</html>
Свойство контрольного переключателя checked содержит булево значение true, если данный переключатель включен, и false, если он выключен. Атрибут тега checked определяет состояние контрольного переключателя по умолчанию. Этому атрибуту в языке JavaScript соответствует свойство def aultChecked, значение которого зависит от того, задан атрибут checked в теге <input> или нет. К контрольному переключателю в JavaScript-программе можно также обратиться при помощи массива elements, как показано в следующем примере:
<!--
Program 7-5
-->
<html>
<head>
<script language="JavaScript">
function showValues() {
alert("CHECKBOX l:\n" +
"value : "+
document.forms[0].elements[0].value + "\n" +
"name : "+
document.forms[0].elements[Oj.name + "\n" +
"checked: "+
document.forms[0].elements[0].checked + "\n" +
"\n CHECKBOX 2:\n" +
"value : " +
document.forms[0].elements[1].value + "\n" +
"name : " +
document.forms[0].elements[1].name + "\n" +
"checked : " +
document.forms[0].elements[1].checked);
}
//-->
</script>
</head>
<body>
<form>
Задайте способ платежа:<br>
<input type="checkbox"
name="cb1"
value="VS">Visa<br>
<input type="checkbox"
name="cb2"
value="MC">Mastercard<p>
<input type="button"
value="See values"
onClick="showValues()">
</form>
</body>
</html>
Здесь первые два элемента формы — контрольные переключатели (checkbox). Чтобы обеспечить правильное обращение к объектам при использовании массива elements, необходимо тщательно следить за соблюдением соответствия элементов массива в программе и элементов формы в документе.
Совет: Состояние контрольных переключателей можно изменять динамически, присваивая значения true или false свойству checked объекта checkbox. К этому объекту следует обращаться либо посредством массива elements, либо используя имя контрольного переключателя. Так, в предыдущих примерах для этого применялся оператор
document.forms[0].elements[1].checked = true;
или оператор
document.forms[0].cb2.checked = true;
В любом случае, выполнение таких операторов приведет к включению второго контрольного переключателя Mastercard.
Чтобы упростить обращение к контрольным переключателям из программы, их лучше определить в отдельном теге <form>. Можно также задать имя формы, содержащей эти контрольные переключатели, посредством атрибута пате и обращаться к данной форме по имени, а не при помощи массива forms.
Скрытые поля Скрытые поля (hidden field) — это поля ввода, которые не отображаются в окне броузера, поэтому они не могут быть активизированы пользователем. Такие элементы обычно используются для сохранения определенных значений, которые должны существовать, пока существует документ. Для создания скрытого элемента применяется HTML-тег <input type = hidden>. Доступ к значению этого элемента в JavaScript-программе можно получить такими способами: — обращаясь к элементу при помощи массива elements; — обращаясь к элементу по имени, заданному как значение атрибута nameтега <input>.
Поля ввода пароля Поля ввода пароля (password field) — это такие поля ввода, где вместо каждого введенного символа отображается символ звездочки(*). Пароли используются для защиты конфиденциальной информации, которая должна быть доступна только определенным пользователям. Однако содержимое такого поля, доступ к которому можно получить с помощью его свойства value, не является скрытым. Поле ввода пароля создается в теге <input value="password">, и доступ к нему можно получить либо обратившись к соответствующему элементу массива elements, либо с помощью его имени, заданного в атрибуте name тега <input>.
Селекторные кнопки Селекторные кнопки (radio button) создаются в теге <input type="radio">. В группе селекторных кнопок можно выбрать только одну.
Примечание: Задавая имена селекторных кнопок, принадлежащих к определенной группе, помните, что эти элементы должны иметь одно и то же имя, т.е. значения атрибутов name должны быть одинаковыми. В языке JavaScript группе селекторных кнопок соответствуют объекты, к которым можно обратиться: — как к элементам массива elements; — как к массиву с именем, заданным в атрибуте name тегов селекторных кнопок.
Чтобы увидеть, каким образом селекторные кнопки обрабатываются в JavaScript-программе, рассмотрим пример, в котором группа селекторных кнопок позволяет пользователю ввести ответ (да или нет).
<!--
Program 7-6
-->
<html>
<head>
<script language="JavaScript">
function seeValues() {
alert("Radio button 1 is: " +
document.forms[0].elements[0].checked + "\n" +
"Radio button 2 is: " +
document.forms[0].elements[1].checked);
}
//-->
</script>
</head>
<body>
<form>
<input name="yesno"
type="radio"
checked>fla<br>
<input name="yesno"
type="radio">Нет<р>
<input type="button"
value="Click me"
onClick="seeValues()">
</form>
</body>
</html>
В этом примере при нажатии кнопки Click meвызывается функция seeValues(), которая после обращения к свойству checked выводит на экран информацию о текущем состоянии селекторных кнопок. Для обращения к ним используется массив elements. Поскольку селекторные кнопки одной группы должны иметь одно и то же значение атрибута name, обращение посредством массива elements не является единственно возможным. Группе селекторных кнопок соответствует отдельный массив, поэтому в приведенной выше программе объект yes по является массивом селекторных кнопок, содержащим два элемента — yesno[0] и yesno[1]. Рассмотрим приложение*{Этот пример не работает в броузере Microsoft Internet Explorer, поскольку последний не всегда корректно обрабатывает адреса ресурсов, начинающиеся с javascript: . Однако если выделить форму с селекторными кнопками в отдельный документ и загрузить его в верхний фрейм основного документа, все будет работать правильно.}, в котором группа селекторных кнопок используется для соединения с Web-узлами, обеспечивающими широкие возможности поиска информации в Internet. Приведенный ниже документ является фреймсодержащим. Форма, обеспечивающая возможность выбора требуемого узла, загружается в нижний фрейм, а нижний фрейм предназначен для загрузки домашней страницы выбранного узла.
Функция loadUrl () в качестве аргумента принимает ссылку на форму, содержащуюся в верхнем фрейме. Вызывается эта функция при нажатии кнопки Загрузить:
<input type="button" value="3arpyзить"
onClick="parent.loadUrl(this.form)">
Значением выражения this.form является ссылка на текущую форму. Это значение передается функции как аргумент "f":
function loadUrl(f) {
for (var n=0; n<f.radioBut.length; n++) {
if (f.radioBut[n].checked) {
parent.frames[1].location = f.radioBut[n].value;
break;
}
}
}
Затем для просмотра всех селекторных кнопок группы radioBut выполняется цикл for. Если текущая селекторная кнопка выбрана, ее свойство checked содержит значение true (т.е. это значение возвращает выражение f.radioBut[n].checked). Зная, какая селекторная кнопка выбрана, вы можете обратиться к свойству value, чтобы увидеть, значение, которое задано в атрибуте value тега <input>. В данном случае каждый атрибут value хранит адрес URL поискового узла. Этот адрес присваивается в качестве значения свойству location нижнего фрейма, в котором отображается домашняя страница выбранного узла. Здесь цикл завершается, потому что может быть выбран только один элемент, и он найден. Описание фреймов и процесса загрузки в них новых ресурсов приведено в главе 9. Функцию loadUrl () можно переписать, используя массив elements:
function loadUrl(f, start, end) {
for (var n=start/ n <= end; n++) {
if (f.elements[n].checked) {
parent.frames[1].location = f.elements[n].value;
break;
}
}
}
Обратите внимание, что с помощью новых аргументов start и end в данном случае задаются индексы начального и конечного элементов группы селекторных кнопок. Помните, что массив elements содержит все элементы формы, а не только селекторные кнопки. Поэтому функции удобно передавать диапазон значений индексов элементов формы, которые необходимо проверить. Переписанную функцию следует вызывать следующим образом:
<input type="button" value="3агрузить"
onClick="parent.loadUrl(this.form,0,2)">
При этом функция loadUrl() начнет проверку с элемента 0 (первой селекторной кнопки) и закончит ее элементом 2 (третьей селекторной кнопкой). Элементы 0, 1 и 2 — это первые три элемента формы.
Примечание: В данном случае в качестве параметра функции передается текущий объект form, а не объекты radio button. Доступ к последним осуществляется через элементы массива elements.
Кроме свойств checked и value удобно использовать и свойство defaultchecked, которое позволяет определить, какая селекторная кнопка выбрана по умолчанию. Селекторные кнопки, выбранные по умолчанию, задаются атрибутом checked. Например, следующий фрагмент документа определяет форму, в группе селекторных кнопок которой по умолчанию выбрана вторая кнопка:
<form>
How do you wish to pay?<br>
<input value="visa"
name="payment"
type="radio">Visa<br>
<input value="ax"
name="payment"
type="radio"
<checked>American Express<br>
<input value="mc"
name="payment"
type="radio">Mastercard<br>
</form>
В данном случае свойству defaultchecked этой селекторной кнопки присваивается значение true. Учтите, что значения true могут храниться одновременно в свойствах checked и def aultchecked селекторной кнопки.
Совет: Присваивая свойству checked значения true или false, можно выбирать селекторные кнопки программным путем. В частности, с помощью оператора document.forms[0].elements[0] = true; в приведенном примере будет выбрана первая селекторная кнопка Visa.
Кнопки переустановки Кнопка переустановки (reset button), как следует из ее названия, инициализирует все элементы текущей формы, в результате чего каждый из них снова получает начальное значение. Для задания начальных значений элементов используются различные атрибуты, в зависимости от типа конкретного элемента. Например, для выбранных по умолчанию контрольных переключателей применяется атрибут checked, а значения текстовых полей по умолчанию задаются в атрибуте value. Тег, определяющий кнопку переустановки, имеет вид:
<input type="reset" value="Reset the form">
Посредством атрибута value этого тега задают текст, отображаемый на кнопке.
Списки Списки (selection list) обеспечивают возможность выбора одного (single) или нескольких (multiple) элементов из определенного множества. Для создания списка используется контейнер <select>. . .</select>, в котором с помощью тегов <option> задаются его элементы. Количество элементов списка не ограничено. В языке JavaScript элементам списка соответствует массив options, индексы которого начинаются с нуля. Элементы списка имеют свойство selected, которое содержит значение true, если данный элемент выбран, и false — в противном случае. В HTML-теге <option> также можно указать атрибут selected и задать в нем элемент, выбранный по умолчанию. Чтобы получить информацию о состоянии элемента списка по умолчанию в JavaScript-программе, необходимо обратиться к свойству default Che eked элемента списка. Элементы списка имеют также свойство text, значением которого является текст, заданный после тега <option>. Свойство списка selectedlndex возвращает индекс выбранного элемента. Списки могут быть представлены несколькими способами. Если в теге <select> определен атрибут multiple, на экран выводится обычный список, в котором можно выбрать несколько элементов. Кроме того, с помощью атрибута size тега <select> задается количество одновременно отображаемых элементов списка. Создавая список, необходимо выполнять перечисленные ниже правила. — Когда для определения списка использован тег <select multiple>, все элементы, заданные в тегах <option>, выводятся на экран, и вы можете выбрать несколько из них. JavaScript-программа, обрабатывающая список этого типа, должна организовать цикл по элементам массива options и проверять свойство selected каждого элемента. Выполнение цикла необходимо продолжать до тех пор, пока не будут обработаны все элементы. Количество элементов в списке можно получить, обратившись к свойству length массива options. Например, для формы с именем myForm используйте выражение myForm.options.length. При работе со списками с возможностью выбора нескольких элементов свойство selectedlndex применять не следует. Для определения текста, заданного в теге <option>, обратитесь к свойству text.
Примечание: Если элемент в списке не выбран, свойство selectedIndex содержит значение -1. Не обращайтесь к элементу options[-1], чтобы не произошла ошибка. Поэтому при обращении к выбранному элементу списка необходимо сначала проверить, существует ли такой элемент вообще. Выбор нескольких элементов производится при нажатой клавише [Ctrl].
Если в теге <select> атрибут multiple не задан, то определен список с возможностью выбора одного элемента. В этом случае для получения номера выбранного элемента используйте свойство списка selectedIndex, а для доступа к содержимому этого элемента — свойство text объекта option. Если атрибут selected не задан ни для одного элемента списка, по умолчанию выбирается первый элемент, т.е. элемент с индексом нуль. Поэтому для списков с возможностью выбора одного элемента свойство selectedlndex никогда не содержит значения -7. При определении списка с помощью тега <select size=n> на экране одновременно отображается п элементов списка, однако выбрать несколько элементов в нем невозможно. Таким образом, для определения выбранного элемента списка и в этом случае следует использовать свойство selectedlndex. Если же атрибут selected не задан ни для одного из элементов списка, по умолчанию будет выбран первый элемент (элемент с индексом нуль).
Списки с возможностью выбора одного элемента и ниспадающие списки Для определения в документе ниспадающего списка используется контейнер <select>...</select>, в котором задается необходимое количество тегов <option>. В списке этого типа можно выбрать только один элемент (single selection). Все элементы списка появляются после щелчка мышью на кнопке списка или на элементе списка, а когда список закрыт, отображается тот элемент, который выбран по умолчанию. На следующем рисунке слева изображен закрытый список (установка по умолчанию), а справа — открытый список. Если список содержит много элементов, в нем присутствует полоса прокрутки (scroll bar).
Например, список, определенный в следующем документе, содержит три элемента:
<!--
Program 7-8
-->
<html>
<body>
<form>
<select>
<option>Option 1
<option>Option 2
<option selected>Option 3
</select>
</form>
</body>
</html>
При появлении списка на экране в нем отображается только элемент, выбранный по умолчанию. Поскольку в данном примере атрибут selected задан в третьем теге <option>, именно этот элемент будет выбран по умолчанию. Для доступа к остальным элементам списка предназначена кнопка списка, расположенная справа. При щелчке мыши на этой кнопке или на элементе списка на экран выводятся остальные элементы, и можно выбрать один из них. В приведенном примере объект <select> не имеет имени, поэтому из JavaScript-программы к нему можно обратиться только при помощи массива elements. Данный массив содержит все объекты формы в том порядке, в котором они определены в документе. Каждой форме в HTML-документе соответствует массив elements. В этом примере выражение document.forms[0].elements [0] ссылается на список. Поскольку в нашем примере форма не имеет определенного имени, для обращения к ней применяется массив forms. Данная форма является первой и единственной формой, определенной в документе, поэтому чтобы обратиться к ней, следует использовать первый элемент массива forms[0]. Для получения значений, определенных в тегах <option>, необходимо обратиться к элементам массива options. Например, значение, определенное в первом теге <option>, возвращается выражением
document.forms[0].elements[0].options[0].
Однако для получения текста, помещенного после тега <option>, необходимо использовать свойство text соответствующего элемента массива options. Таким образом, текст, заданный для первого элемента списка, может быть получен как значение выражения
document.forms[0].elements[0].options[0].text
Данное выражение возвратит строку "Option I". Выражение кажется сложным, но его приходится использовать, потому что ни в одном из HTML-тегов не было определено имя. Использование имен позволяет существенно упростить подобные выражения. Изменим исходный текст документа следующим образом:
<!--
Program 7-9
-->
<html>
<body>
<form name="fl">
<select name="selObj1">
<option>Option 1
<option>Option 2
<option selected>Option 3
</select>
</form>
</body>
</html>
Получить текст, заданный в первом элементе списка, можно посредством выражения
document.f1.selObj1.options[0].text
Для получения значения выбранного элемента необходимо использовать свойство списка selectedlndex. Значением данного свойства является номер выбранного в настоящее время элемента. Этот номер используется как индекс массива options[]. Выражение
document.forms[0].elements[0].selectedIndex
возвратит значение 2, поскольку в приведенном примере выбран третий элемент списка. Индексы массива в языке JavaScript начинаются с нуля, поэтому options[2] — это третий элемент массива. Помните, что свойство selectedlndex должно применяться только к объектам выбора. В данном примере элемент массива elements [0] ссылается на список, определенный в теге <select>. Если использовать имена элементов, последнее выражение можно заменить более простым
document.f1.selObj1.selectedIndex
Чтобы упростить программу, значение данного выражения присвоим переменной
var sellx = document.fl.selObj1.selectedIndex;
а значение этой переменной будем использовать в качестве индекса массива options для получения необходимых свойств выбранного элемента списка. Следующий документ содержит список и JavaScript-программу, позволяющую определить, какой элемент списка выбран:
<!--
Program 7-10
-->
<html>
<head>
<script language="JavaScript">
<!--
function showltem() {
var selIx = document.f1.selObj1.selectedIndex;
var optText = document.f1.selObjl.options[selIx].text;
alert("Item selected: " + optText);
}
</script>
</head>
<body>
<form name="f1">
<select name="fselObj1">
<option>Option 1
<option>Option 2
<option selected>Option 3
</select><p>
<input type="button"
value="See value"
onClick="showItem()">
</form>
</body>
</html>
Обратите внимание, что текст, заданный для текущего выбранного элемента списка, присваивается переменной optText. При этом для индексации массива options[] используется переменная sellx, которая сохраняет индекс выбранного элемента. Функция showitem(), отображающая окно сообщения с информацией о выбранном элементе списка, вызывается при обработке события click для кнопки See value,определенной в теге <input type="button">. Окно сообщения выводится на экран при помощи метода alert (), которому в качестве аргумента передается переменная optText. Поскольку объект select является массивом, для обращения к его элементам массив options можно не использовать. Так, если список задан в HTML-теге
<select name="selObj1">
то к его элементам позволяют обращаться выражения selObjl[0], seiobjl[l], seiobjl[2] и т.д. Точно так же можно обращаться и к свойствам элементов списка, например selObjl[0] selected, selObjl[0].text и т.п. Однако этим способом воспользоваться невозможно, если имя списка не задано.*{Данный способ обращения к элементам списка лучше не использовать. Он действительно работает в броузере Navigator, но не в Internet Explorer.} Выражение document.f1.elements[0].text не возвратит значение первого элемента списка, поскольку элемент массива elements[0] ссылается на элемент формы вообще, а не на конкретный список. Если же имя списка определено, при интерпретации программы создается соответствующий объект-список, поэтому для обращения к его элементам массив options[] можно опустить, сократив таким образом текст программы. Признаком того, что элемент списка выбран, является булево значение true свойства selected этого элемента. Поэтому при выборе третьего элемента списка значением JavaScript-выражения
document.f1.selObj1.selected
или аналогичного выражения
document.f1.selObj1.options[2].selected
будет true. В последнем выражении, как вы теперь знаете, часть "options[2]" использовать не обязательно, поскольку задано имя списка. Таким образом, существует возможность записать функцию showitem() иначе, задав в ней просмотр массива options[], чтобы выяснить у какого элемента списка свойство selected имеет значение true. Переписанная функция приведена в следующем примере**{Эта программа не будет работать в броузере Internet Explorer, поскольку при обращении к элементам списка в ней пропущено свойство options. Если же использовать традиционный способ обращения к элементам списка, в обоих броузерах Netscape и Microsoft программа будет работать правильно.}. Заметьте, что свойство selectedIndex списка в этом случае не используется.
<!--
Program 7-11
-->
<html>
<head>
<script language="JavaScript">
function showltem() {
var optText = "";
for (var i=0; i < document.f1.selObj1.length; i++) {
if (document.fl.selObjl[i].selected) {
optText = document.f1.selObj1[i].text;
break;
}
}
alert("Item selected: " + optText);
}
//-->
</script>
<head>
<body>
<form name="f1">
<select name="selObj1">
<option>Option 1
<option>Option 2
<option selected>Option 3
</select><p>
<input type="button"
value="See value"
onClick="showItem()">
</form>
</body>
</html>
Здесь оператор for перебирает все элементы списка, определенные в теге <select>. Значением выражения document.f1.selObj1.length является количество элементов списка (в данном случае их три, поэтому цикл повторяется трижды). Переменная i используется в качестве счетчика цикла и для индексации массива элементов списка. При каждой итерации цикла ее значение увеличивается на единицу. В первой итерации проверяется выражение
document.f1.selObj1[0].selected
Если его значение равно true, то значение свойства text текущего элемента списка присваивается переменной optText. Оператор break (см. главу 3) завершает цикл при обнаружении выбранного элемента списка, а метод alert() выводит на экран текст этого элемента. Обнаружение выбранного элемента списка путем перебора всех его элементов занимает больше времени и запись программы сложнее, чем при использовании свойства selected-index, поскольку в данном случае программа самостоятельно определяет значение этого свойства. Самая компактная запись для обращения к свойству text выбранного элемента списка получается при использовании следующего варианта функции showItem():
<script language="JavaScript">
function showltem(f) {
alert("Selected item: " +
f.selObj1[f.selObj1.selectedIndex].text);
}
//-->
</script>
В данном случае предполагается, что ссылка на форму, содержащую список, передается функции в качестве параметра при помощи выражения this.form:
<form>
<input type="button"
value="See value"
onClick="showItem(this.form)">
</form>
Здесь функция showItem() должна вызываться посредством выражения showItem(this.form) или выражения showltem(document.forms [0]). Поскольку имя объекта select задано, объект можно индексировать как массив, используя для этого значение свойства selectedIndex. В данном примере имя формы указывать не обязательно, потому что значение выражения this.form представляет собой ссылку на текущую форму независимо от того, определено ее имя или нет.
Списки с возможностью выбора нескольких элементов Списки с возможностью выбора нескольких элементов (multiple selection lists) не являются ниспадающими и в них отображаются сразу все элементы или некоторое их количество (см. рис. ниже).
Нужные элементы в таких списках выбирают, щелкая на них мышью при нажатой клавише [Ctrl]. Для определения списка этого типа необходимо задать атрибут multiple в теге <select>. Кроме того, атрибут selected может быть указан в нескольких тегах <option>. На следующем рисунке показаны два списка: слева — список с возможностью выбора одного элемента, а справа — список с возможностью выбора нескольких элементов.
Другая важная особенность списков с возможностью выбора нескольких элементов состоит в том, что в них может быть не выбрано ни одного элемента. При этом возникает необходимость дополнительной проверки правильности данных формы, поскольку если список не содержит выбранных элементов, обращение к массиву options приводит к ошибке. Учтите, что свойство selectedlndex для списков с возможностью выбора нескольких элементов неприменимо, так как оно содержит индекс только первого выбранного элемента. Поэтому для таких списков необходимо проверять свойство checked каждого элемента массива options. Приведем пример списка с возможностью выбора нескольких элементов:
<!--
Program 7-12
-->
<html>
<body>
<form name="forml">
Какие броузеры вам приходилось использовс1Ть?<br>
<select multiple name="objSell">
<option selected>Navigator 3.0
<option>NCSA Mosaic 2.0
<option>MSIE 3.0
</select>
</body>
</html>
Программа для определения выбранных элементов списка*{Эта программа не будет работать в Internet Explorer, поскольку в ней используется индексация самого списка, а не массива options. Применение подобной нотации является верным способом сделать ваши документы непереносимыми.} подобна программе, приведенной в предыдущем параграфе, однако она не должна останавливаться при обнаружении первого выбранного элемента, а должна просмотреть весь массив options:
<!--
Program 7-13
-->
<html>
<head>
<script language="JavaScript">
function showltem(selField) {
var optText = "";
var counter = 1;
for (var i=0; i < selField.length; i++) {
if (selField[i].selected) {
optText += counter + 11. " +
selField[i].text + "\n";
counter++;
}
}
if (counter == 1)
alert("Ни один элемент списка не выбран.");
else
alert("Выбранные элементы списка:\n" + optText);
}
</script>
</head>
<body bgcolor="White">
<form name="forml">
Какие броузеры вам приходилось использовать?<br>
<select name="selObj1" multiple>
<option>Navigator 3.0
<option>NCSA Mosaic 2.0
<option>MSIE 3.0
</select>
<p>
<input type="button"
value="See value"
onClick="showItem (this.form.selObj1)">
</form>
</body>
</html>
Данный документ содержит список с возможностью выбора нескольких элементов и кнопку, после щелчка на которой вызывается функция showitem(). Выражение this.form.selobj1 передает ссылку на список в качестве аргумента этой функции. В функции showltem() при помощи оператора цикла перебираются все элементы списка, заданные в тегах <option>. Количество этих элементов возвращается выражением selobj1.length (а при использовании параметра функции — выражением selField.length). Благодаря тому, что имя списка задано, список может быть индексирован без обращения к массиву options. В цикле for проверяется значение свойства selected каждого элемента списка, и, если оно равно true, текст этого элемента добавляется к строке с именем optText. Кроме того, в программе определена переменная-счетчик, которая используется для проверки наличия в списке выбранных элементов и для их нумерации. После завершения цикла с помощью метода alert() на экране появляется окно сообщения с перечнем выбранных элементов. Если ни один элемент из списка не выбран, в окне сообщения выводится соответствующий текст.
Совет: Элементы массива options имеют свойство def aultSelected, которое содержит значение true, если в соответствующем теге <option> задан атрибут selected, т.е. этот элемент является выбранным по умолчанию.
В теге <select> можно задать еще один атрибут — size. Значением данного атрибута является целое число, определяющее количество элементов списка одновременно отображаемых на экране. Атрибут size может быть задан как для списков с возможностью выбора одного элемента, так и для списков с возможностью выбора нескольких элементов. При этом для определения выбранного элемента (в списке с возможностью выбора одного элемента) можно воспользоваться программой, приведенной в предыдущем параграфе, в которой используется свойство selectedIndex. Списки с возможностью выбора одного элемента, для которых определен атрибут size, отображаются как обычные (не ниспадающие) списки. В некоторых списках полоса прокрутки отсутствует, потому что все элементы списка помещаются на экране. Однако отсутствие полосы прокрутки не исключает возможности перемещения вверх и вниз по элементам списка. Приведенный ниже документ*{Поскольку в Internet Explorer события Click и Mouseover для изображений не обрабатываются, эта программа в нем работать не будет — функции up() и down() просто не будут вызываться. Однако если заменить рисунки кнопками, все будет работать правильно.} содержит список с возможностью выбора нескольких элементов и два небольших рисунка с изображением стрелок вверх и вниз. Оба рисунка являются гиперсвязями, для которых определены обработчики события click (если рисунки вам не нравятся, можно заменить их кнопками). Щелчок мыши на рисунке со стрелкой вверх активизирует функцию up(), а на рисунке со стрелкой вниз — функцию down():
<!--
Program 7-14
-->
<html>
<head>
<script language="JavaScript">
<!--
var num = 0;
function up() {
var num = document.forms[0].selOpts.selectedIndex;
if (num != 0) {
document.forms[0].selOpts[num].selected = false;
document.forms[0].selOpts[num-1].selected = true;
}
}
function down() {
var num = document.forms[0].selOpts.selectedIndex;
if (num != document.forms[0].selOpts.length-1) {
document.forms[0].selOpts[num].selected = false;
document.forms[0].selOpts[num+1].selected = true;
}
}
//-->
</script>
</head>
<body>
<center>
<table border=0>
<tr>
<form>
<td colspan=2>
<select multiple name="selOpts">
<option selected>Egypt
<option>South America
<option>Instanbul
<option>The Gallapogas Islands
<option>Indonesia
<option>Malasia
<option>South Africa
<option>Portugal
<option>Spain
<option>The United Kingdom
</select>
</td>
<td>
<tr>
<td align="left">
<a href="#"
onClick="up()"
onMouseOver="window.status='Up'; return true">
<img border=0 src="up.gif"></a>
</td>
<td align="right">
<a href="#"
onClick="down() "
onMouseOver="window.status='Down'; return true">
<img border=0 src="down.gif"></a>
</td>
</tr>
</td>
</form>
</tr>
</table>
</center>
</body>
</html>
Функции up() и down() определяют первый выбранный элемент списка и присваивают значение true свойству selected следующего или предыдущего элемента списка соответственно. При этом свойству selected выбранного элемента необходимо присвоить значение false, в противном случае при каждом щелчке мыши на рисунке будет выбираться еще один элемент списка до тех пор, пока не будут выбраны все элементы. Функция up() проверяет, не является ли выбранный элемент первым в списке, чтобы предотвратить попытку обращения к несуществующему элементу. Для этого достаточно сравнить значение свойства selectedlndex с нулем. В функции down() необходимо проверить, не равно ли значение свойства selectedlndex значению свойства списка length-1, поскольку значением свойства length является количество элементов списка. Это значение обязательно уменьшается на 1, поскольку нумерация элементов списка начинается с нуля.
Динамическое изменение содержимого списков В броузере Navigator 3.0 имеются дополнительные возможности динамического изменения содержимого списков. Например, изменять выбранные элементы списка можно программным путем, не используя в теге <option> атрибута selected. Это делают двумя способами: — путем присваивания значения true или false свойству selected соответствующего элемента списка; — путем присваивания свойству selectedIndex номера элемента списка,который необходимо выбрать. Следующая программа*{В этой программе индексируется список, а не массив options, поэтому при загрузке ее в Internet Explorer вы получите сообщение об ошибке.} определяет и автоматически выделяет текущий день в списке дней недели. Поскольку программа вызывается при загрузке документа, текущий день становится выбранным по умолчанию.
<!--
Program 7-15
-->
<html>
<head>
<script language="JavaScript">
function showDay() {
today = new Date();
day = today.getDay(); // 0: Sunday, 1: Monday...
if (day == 0) { document.forml.day[6].selected = true; }
if (day == 1) { document.forml.day[0].selected = true; }
if (day == 2) { document.forml.day[1].selected = true; }
if (day == 3) { document.forml.day[2].selected = true; }
if (day == 4) { document.forml.day[3].selected = true; }
if (day == 5) { document.forml.day[4].selected = true; }
if (day == 6) { document.forml.day[5].selected = true; }
}
//-->
</script>
<head>
<body bgcolor="White" onLoad="showDay()">
<form name="form1">
Сегодня:
<select name="day">
<option>Понедельник
<option>Вторник
<option>Среда
<option>Четверг
<option>Пятница
<option>Суббота
<option>Воскресенье
</select>
</form>
</body>
</html>
При определении списка в данном примере элементом, выбранным по умолчанию, является Понедельник, однако после загрузки документа посредством атрибута события onLoad будет вызвана функция showDay(), которая изменит выбранный элемент списка. Обратите внимание, что атрибут name задает имя списка, поэтому список можно индексировать как массив, не используя свойства options (применение массива options привело бы к тому же результату). Для определения текущего дня применяется метод getDay(), возвращающий номер дня недели: 0 — для воскресенья, 1 — для понедельника и т.д. Приведенную программу можно сделать более компактной. Это очень важно, поскольку, чем больше HTML-страница, тем дольше она загружается в броузер. Чтобы сократить программу, при присваивании свойству selected значения true или false нужно обращаться непосредственно к элементу массива. Это требует изменения порядка расположения тегов <option> в контейнере <select>...</select> таким образом, чтобы эти теги точно соответствовали значениям, возвращаемым методом getDay() языка JavaScript. Ниже приведен измененный документ, в котором учитывается порядок расположения тегов <option>.
<!--
Program 7-16
-->
<html>
<head>
<script language="JavaScript">
<!--
function showDay() {
today = new Date();
theDay = today.getDay();
document.forml.day[theDay].selected = true;
}
//-->
</script>
<head>
<body bgcolor="White" onLoad="showDay()">
<form name="form1">
Today is:
<select name="day">
<!--
Замечание: теги <option> должны задаваться в порядке,
Как видите, эта программа более компактна и выполняется значительно быстрее. Обратите внимание, что порядок расположения тегов, задающих дни недели, изменен. В броузер Navigator 3.0 введена новая функция, позволяющая изменять значение свойства text элемента списка. Рассмотрим программу, в которой номер элемента списка и новый текст для него вводятся с помощью формы и используются для изменения текста определенного элемента списка.