http://blagtalkan.ru
http://oktpoisk.ru
http://mysorru.ru/
http://san-okt.ru/
http://pes6evolution.ru/
http://chasikigov.ru
http://serafimsovet.ru
http://filmsgov.ru
http://free-domen.ru
http://fithonda.ru/forums/index.php
http://avtogov.ru
http://www.1001bilet.com.ua/base/on-line/
http://pravilavoini.ru
http://school41ufa.ru
http://rusrav4.ru
Класс AutoSuggestControl | Книга AJAX
 

Класс AutoSuggestControl содержит всю функциональность, необходи¬мую для реализации автодополнения. Данный элемент управления дол-мен знать, с каким текстовым полем и с каким поставщиком подсказок АВ должен взаимодействовать. Все это делает простой конструктор:
... function AutoSuggestControl(oTextbox, oProvider) { 5- this, provider = oProvider; I this.textbox = oTextbox;
Именно на такой простой основе будет строиться сложная функцио¬нальность текстового поля.
Класс AutoSuggestCont rol довольно сложен, поэтому разобьем его описа-кве на разделы по типам функциональных возможностей. Описания, приводимые в следующих разделах, ссылаются друг на друга, а весь поляый код может быть загружен с сайта www.wrox.com.
РЕАЛИЗАЦИЯ АВТОДОПОЛНЕНИЯ
Для реализации функции автодополнения нелишним будет разобрать¬ся с тем, как она работает. Текстовые поля с функцией автодополне¬ния непрерывно следят за вводом пользователя и предсказывают воз¬можный вариант продолжения введенной части строки, подсвечивая ту ее часть, которая была добавлена автоматически. Например, вы вводите *Ма* в текстовое поле, функция автодополнения пре~ ет, что вы хотите ввести название штата *Maine» (штат Мэн), бавляет окончание строки *ine» в поле ввода и подсвечивает д ное окончание. Это не мешает пользователю продолжать ввод, скольку вновь вводимые символы просто затирают выделенную
Ранее с помощью JavaScript можно было выделить только всю в поле ввода, для чего предназначалась функция select ():
var oTextbox = document.getElementByldC'txtState"); oTextbox. selectO;
Этот фрагмент кода сначала получает ссылку на текстовое поле с тификатором txtState, а затем выделяет текст, содержащийся ■ Подобная функциональность прекрасно подходит для больт случаев, однако она малопригодна для реализации вывода авто нений. К счастью, Internet Explorer и Mozilla Firefox позволяют лить часть строки (в других броузерах эта возможность недо Но две крупнейшие в мире броузеров воюющие стороны, как делают это совершенно непохожими способами.
Решение, предлагаемое Internet Explorer, основано на текстовых пазонах. Не путайте их с текстовыми диапазонами интерфейса Текстовые диапазоны в Internet Explorer - это невидимый д текста на странице, начинающийся с одного символа и зак щийся на другом. Весь текст, попадающий в заполненный тек диапазон, можно выделить цветом, что отлично подходит для; ции функции автодополнения. Чтобы создать текстовый диап определенного текстового поля, необходимо вызвать метод create7 Range(), который предоставляется броузером Internet Explorer бого текстового поля.
Как только текстовый диапазон определен, его методы позволяют лить некоторую часть текста. У текстового диапазона довольно методов, но нас интересуют только moveStart() и moveEnd(). Оба они нимают два аргумента: единицу измерения и число. В качестве измерения могут выступать character, word, sentence или textedit, ж ло определяет количество единиц от начала до конца текста (для • moveStart() число должно быть положительным, а для moveEnd() -цательным). Задав границы диапазона, можно вызвать метод sel который выделит цветом символы выбранного диапазона. Так, щий фрагмент кода выделяет начальные три символа в текстовом
var oRange = oTextbox.createTextRange(); oRange.moveStart("character", 0); oRange.moveEnd("character", 3 - oTextbox.value.length); oRange.selectO; oTextbox.focus();
Обратите внимание, что для получения соответствующего зна для метода moveEnd() необходимо из количества выделяемых с вычесть общую длину текста в текстовом поле. Последняя строка - устанавливает фокус ввода в поле, чтобы сделать выделение видимым. (Текст может быть выделен, только если текстовое поле обладает фо¬кусом ввода.) Процедура выделения в Internet Explorer выглядит не¬много запутанной, но все-таки она достаточно проста, чтобы ее можно •ыло задействовать в сценариях. Метод, предлагаемый Firefox, гораз¬до прямолинейнее.
Текстовые поля в Firefox снабжаются нестандартным методом, кото¬рый называется setSelectionRange(). Он принимает два аргумента: ин¬декс начального символа и индекс символа, стоящего сразу за послед¬ним символом из выделенного диапазона. Таким образом, чтобы выде¬лить начальные три символа в текстовом поле Mozilla, потребуются ■сего две строки кода:
^г.oTextbox.setSelectionRange(0,3); „' oTextbox. focus();
Первый метод класса AutoSuggestControl, который нам необходимо реа¬лизовать, - это метод выделения символов, учитывающий различия между броузерами. Этот метод называется selectRange(), он будет вы¬полнять за вас всю неблагодарную работу:
AutoSuggestControl.prototype.selectRange = function (iStart, iEnd) {
if (this.textbox.createTextRange) {
^' var oRange = this.textbox.createTextRangeO;
- oRange. moveStartC'character", iStart);
-- .oRange.moveEnd("character", iEnd - this.textbox.value.length);
oRange,select(); } else if (this.textbox.setSelectionRange) { this,textbox;setSelectionRange(iStart, iEnd);
}
this.textbox.focus();
};
В этом методе решение о том, каким из двух способов следует выде¬лять символы, принимается на основании анализа функциональных особенностей броузеров. Сначала проверяется наличие метода create-TextRangeO, чтобы определить, должны ли использоваться текстовые диапазоны Internet Explorer, а затем - наличие метода setSelection-Range(), чтобы определить, должен ли применяться способ, предлагае¬мый броузером Firefox. В качестве аргументов принимаются индекс первого символа выделяемого диапазона и количество выделяемых символов. Значения этих аргументов передаются соответствующим методам броузеров.
Метод typeAhead ()
Теперь в вашем распоряжении появился метод, позволяющий выде¬лять часть текстового поля, и можно реализовать функцию автодопол¬нения. /Для этого предназначен метод typeAhead(). Он принимает единственный аргумент - текст подсказки, выводимой в текстовом Предполагается, что текст подсказки соответствует содержимому ля ввода (и имеет по крайней мере один символ). Этот метод вып ет следующие три действия:
1. Получает количество символов, уже введенных в текстовое по
2. Записывает текст подсказки в текстовое поле.
3. Выделяет только ту часть текста, которую пользователь еще не дил, отталкиваясь от информации, полученной на первом шаге.
Кроме того, поскольку функция автодополнения может работать ко в броузерах Internet Explorer и Firefox, необходимо убедиться, мы имеем дело с одним из них. Если броузер не поддерживает в ность выделения текста, то ни один из этих шагов не должен в няться, чтобы пользователь мог беспрепятственно вводить си~ Здесь проверяется наличие хотя бы одного из двух методов createl RangeO и setSelectionRange():
AutoSuggestControl.prototype.typeAhead = function (sSuggestion) {
if (this.textbox.'createTextRange II this.textbox.setSeiectionRange) var iLen = this.textbox.value.length; this.textbox.value = sSuggestion; this.selectRange(iLen, sSuggestion,length);
Теперь нам необходим еще один метод, который будет вызывать ный метод и передавать ему текст подсказки. Это метод autosugge Метод autosuggest() Метод autosuggest() - это, пожалуй, самый важный метод эл управления. Он один отвечает за прием массива с подсказками и ет, что с ними делать. Этот метод будет задействован в реализации держки всех функций автодополнения (включая выпадающий с подсказками), но нам он пока нужен только для автоматичес полнения поля ввода.
Метод autosuggest() будет принимать массив подсказок целиком, этому он должен каким-либо образом выбрать одну из них для в текстовом поле. Обычно, чтобы не усложнять алгоритм, берут первую подсказку. Однако подсказки могут попросту отсутс Когда методу передается пустой массив, он не должен вызывать typeAheadO; таким образом, сначала необходимо проверить ность массива:
откуда берутся подсказки? Эта задача ложится на плечи класса-по¬ставщика подсказок, который должен получить подсказки и передать ах данному методу. Реализация этого класса будет обсуждаться позд¬нее в этой же главе.