AutoComplete
Многие JavaScript-библиотеки для AJAX предоставляют функционал для
автодополнения, с его помощью отображается список
возможных соответствий в то время, пока пользователь набирает текст.
Помощник AutoComplete предназначен для облегчения возврата
допустимых ответов для функционала такого рода.
Поскольку не все JavaScript-библиотеки реализуют автодополнение
одинаково, то помощник AutoComplete предоставляет в
абстрактном классе некоторый базовый функционал, необходимый для
большинства библиотек, и конкретные реализации для отдельных библиотек.
Возвращаемые данные в
основном - JSON-массивы строк, JSON-массивы массивов (в которых каждый
массив-член является ассоциативным массивом метаданных, используемых при
создании списка), либо HTML.
Базовое использование одинаково для всех реализаций:
_helper->autoCompleteDojo($data);
// То же самое явным образом:
$response = $this->_helper->autoCompleteDojo
->sendAutoCompletion($data);
// Или просто подготовьте ответ для автодополнения:
$response = $this->_helper->autoCompleteDojo
->prepareAutoCompletion($data);
}
}
]]>
По умолчанию этот помощник делает следующее:
Отключает макеты и ViewRenderer.
Устанавливает необходимые заголовки ответа.
Устанавливает тело ответа с закодированными данными в нужном
формате для автодополнения.
Отправляет ответ.
Доступные методы помощника включают в себя:
disableLayouts() может использоваться для
отключения макетов и ViewRenderer. Обычно он вызывается в
prepareAutoCompletion().
encodeJson($data, $keepLayouts = false) будет
кодировать данные в формат JSON, при этом можно опционально
включать или отключать макеты. Обычно этот метод вызывается в
prepareAutoCompletion().
prepareAutoCompletion($data, $keepLayouts = false)
используется для подготовки ответа в формате, необходимом для
конкретной реализации, при этом можно опционально включать или
отключать макеты. Возвращаемое значение может варьироваться в
зависимости от используемой реализации.
sendAutoCompletion($data, $keepLayouts = false)
используется для отправки данных в формате, необходимом для
конкретной реализации. Он вызывает
prepareAutoCompletion() и затем отправляет ответ.
direct($data, $sendNow = true, $keepLayouts =
false)
используется, когда помощник вызывается как метод брокера
помощников. Флаг $sendNow используется для
определения того, какой метод вызывать -
sendAutoCompletion() или
prepareAutoCompletion(). По умолчанию ответ
отправляется сразу.
В настоящее время AutoComplete поддерживает AJAX-библиотеки
Dojo и Scriptaculous.
Автодополнение c Dojo
В Dojo нет собственно виджета для автодополнения, но есть два
виджета, которые могут производить автодополнение: ComboBox и
FilteringSelect. В обоих случаях они требуют использования хранилища
данных, который реализует QueryReadStore, читайте документацию по
dojo.data для получения более подробной информации по этой теме.
В Zend Framework вы можете передавать простой индексный массив для
помощника AutoCompleteDojo, и он будет возвращен в формате,
пригодном для использования с хранилищем в Dojo:
_helper->autoCompleteDojo($data);
]]>
Автодополнение с Dojo и Zend MVC
Автодополнение с Dojo через Zend MVC требует реализации
нескольких вещей:
генерация объекта формы для того ComboBox, для которого нужно
реализовать автодополнение, действие контроллера для
обслуживания автодополнения, создание своего QueryReadStore для
связи с этим действием и генерация javascript-кода для
инициализации автодополнения.
Для начала рассмотрим, что нужно сделать по части
javascript. Dojo представляет собой полный фреймворк для
создания объектно-ориентированного кода на языке JavaScript,
почти так же, как Zend Framework на языке PHP. Он позволяет
создавать псевдопространства имен, используя для этого иерархию
директорий. Создадим директорию 'custom' на том же уровне,
что и директория Dojo. В этой директории создадим файл
TestNameReadStore.js со следующим содержимым:
Этот класс просто наследует от класса QueryReadStore фреймворка
Dojo, который сам по себе является абстрактным. Мы просто
определяем метод, по которому производится запрос, и присваиваем
его элементу 'test'.
Далее создадим элемент формы, для которого хотим реализовать
автодополнение:
_form) {
$this->_form = new Zend_Form();
$this->_form->setMethod('get')
->setAction(
$this->getRequest()->getBaseUrl() . '/test/process'
)
->addElements(array(
'test' => array('type' => 'text', 'options' => array(
'filters' => array('StringTrim'),
'dojoType' => array('dijit.form.ComboBox'),
'store' => 'testStore',
'autoComplete' => 'false',
'hasDownArrow' => 'true',
'label' => 'Your input:',
)),
'go' => array('type' => 'submit',
'options' => array('label' => 'Go!'))
));
}
return $this->_form;
}
}
]]>
Здесь мы просто создаем форму с методами 'test' и 'go'. Метод
'test' добавляет несколько специальных, специфических для Dojo
атрибутов: dojoType, store, autoComplete и hasDownArrow. Через
'dojoType' мы указываем, что создается ComboBox, он связан
с хранилищем данных (ключ 'store') 'testStore'. Устанавливая
'autoComplete' в false, мы говорим Dojo, чтобы он не выбирал
автоматически первое соответствие, а вместо этого показывал
список соответсвий. Наконец, 'hasDownArrow' создает стрелку
наподобие той, что присутствует в выпадающем списке, чтобы можно
было выводить и убирать список соответствий.
Добавим метод для отображения формы и действие для обработки
автодополнения:
view->form = $this->getForm();
}
public function autocompleteAction()
{
if ('ajax' != $this->_getParam('format', false)) {
return $this->_helper->redirector('index');
}
if ($this->getRequest()->isPost()) {
return $this->_helper->redirector('index');
}
$match = trim($this->getRequest()->getQuery('test', ''));
$matches = array();
foreach ($this->getData() as $datum) {
if (0 === strpos($datum, $match)) {
$matches[] = $datum;
}
}
$this->_helper->autoCompleteDojo($matches);
}
}
]]>
В методе autocompleteAction() мы делаем несколько
вещей. Сначала мы проверяем, был ли произведен POST-запрос и
имеет ли параметр 'format' значение 'ajax', это помогает
отсечь большинство ложных запросов. Далее мы получаем
параметр 'test' и сравниваем его с нашими данными (здесь я
намеренно опустил реализацию метода getData(),
источники данных могут быть любыми). В конце выполнения
передаем найденные соответствия помощнику AutoCompletion.
Теперь на очереди написание скрипта вида для страницы с формой.
В нем нужно установить хранилище данных, вывести
форму и подключить все необходимые библиотеки
Dojo, включая наше хранилище данных. Ниже приведен
скрипт вида с комментариями:
form ?>
// подключение CSS для Dojo в HTML-заголовке: ?>
headStyle()->captureStart() ?>
@import "baseUrl()
?>/javascript/dijit/themes/tundra/tundra.css";
@import "baseUrl() ?>/javascript/dojo/resources/dojo.css";
headStyle()->captureEnd() ?>
headScript()
->setAllowArbitraryAttributes(true)
->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
'text/javascript',
array('djConfig' => 'parseOnLoad: true'))
->captureStart() ?>
djConfig.usePlainJson=true;
dojo.registerModulePath("custom","../custom");
dojo.require("dojo.parser");
dojo.require("dojox.data.QueryReadStore");
dojo.require("dijit.form.ComboBox");
dojo.require("custom.TestNameReadStore");
headScript()->captureEnd() ?>
]]>
Обратите внимание на вызовы помощников видов, таких, как
headStyle м headScript, - это метки заполнения, которые могут
затем рендериться в HTML-заголовке скрипта макета.
Теперь у нас есть всё для того, чтобы автодополнение с Dojo заработало.
Автодополнение с Scriptaculous
Scriptaculous
ожидает HTML-ответ в определенном формате.
С этой библиотекой используется помощник
'AutoCompleteScriptaculous'.
Просто передавайте ему массив данных, и он создает ответ HTML,
совместимый с Ajax.Autocompleter.