| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect3 id="zend.controller.actionhelpers.autocomplete">
- <title>AutoComplete</title>
- <para>
- Многие JavaScript-библиотеки для AJAX предоставляют функционал для
- автодополнения, с его помощью отображается список
- возможных соответствий в то время, пока пользователь набирает текст.
- Помощник <code>AutoComplete</code> предназначен для облегчения возврата
- допустимых ответов для функционала такого рода.
- </para>
- <para>
- Поскольку не все JavaScript-библиотеки реализуют автодополнение
- одинаково, то помощник <code>AutoComplete</code> предоставляет в
- абстрактном классе некоторый базовый функционал, необходимый для
- большинства библиотек, и конкретные реализации для отдельных библиотек.
- Возвращаемые данные в
- основном - JSON-массивы строк, JSON-массивы массивов (в которых каждый
- массив-член является ассоциативным массивом метаданных, используемых при
- создании списка), либо HTML.
- </para>
- <para>
- Базовое использование одинаково для всех реализаций:
- </para>
- <programlisting language="php"><![CDATA[
- class FooController extends Zend_Controller_Action
- {
- public function barAction()
- {
- // Выполнение некоторой логики...
- // Кодирование и отправка ответа:
- $this->_helper->autoCompleteDojo($data);
- // То же самое явным образом:
- $response = $this->_helper->autoCompleteDojo
- ->sendAutoCompletion($data);
- // Или просто подготовьте ответ для автодополнения:
- $response = $this->_helper->autoCompleteDojo
- ->prepareAutoCompletion($data);
- }
- }
- ]]></programlisting>
- <para>
- По умолчанию этот помощник делает следующее:
- </para>
- <itemizedlist>
- <listitem><para>
- Отключает макеты и ViewRenderer.
- </para></listitem>
- <listitem><para>
- Устанавливает необходимые заголовки ответа.
- </para></listitem>
- <listitem><para>
- Устанавливает тело ответа с закодированными данными в нужном
- формате для автодополнения.
- </para></listitem>
- <listitem><para>
- Отправляет ответ.
- </para></listitem>
- </itemizedlist>
- <para>
- Доступные методы помощника включают в себя:
- </para>
- <itemizedlist>
- <listitem><para>
- <code>disableLayouts()</code> может использоваться для
- отключения макетов и ViewRenderer. Обычно он вызывается в
- <code>prepareAutoCompletion()</code>.
- </para></listitem>
- <listitem><para>
- <code>encodeJson($data, $keepLayouts = false)</code> будет
- кодировать данные в формат JSON, при этом можно опционально
- включать или отключать макеты. Обычно этот метод вызывается в
- <code>prepareAutoCompletion()</code>.
- </para></listitem>
- <listitem><para>
- <code>prepareAutoCompletion($data, $keepLayouts = false)</code>
- используется для подготовки ответа в формате, необходимом для
- конкретной реализации, при этом можно опционально включать или
- отключать макеты. Возвращаемое значение может варьироваться в
- зависимости от используемой реализации.
- </para></listitem>
- <listitem><para>
- <code>sendAutoCompletion($data, $keepLayouts = false)</code>
- используется для отправки данных в формате, необходимом для
- конкретной реализации. Он вызывает
- <code>prepareAutoCompletion()</code> и затем отправляет ответ.
- </para></listitem>
- <listitem><para>
- <code>direct($data, $sendNow = true, $keepLayouts =
- false)</code>
- используется, когда помощник вызывается как метод брокера
- помощников. Флаг <varname>$sendNow</varname> используется для
- определения того, какой метод вызывать -
- <code>sendAutoCompletion()</code> или
- <code>prepareAutoCompletion()</code>. По умолчанию ответ
- отправляется сразу.
- </para></listitem>
- </itemizedlist>
- <para>
- В настоящее время <code>AutoComplete</code> поддерживает AJAX-библиотеки
- Dojo и Scriptaculous.
- </para>
- <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
- <title>Автодополнение c Dojo</title>
- <para>
- В Dojo нет собственно виджета для автодополнения, но есть два
- виджета, которые могут производить автодополнение: ComboBox и
- FilteringSelect. В обоих случаях они требуют использования хранилища
- данных, который реализует QueryReadStore, читайте документацию по
- <ulink url="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0">dojo.data</ulink> для получения более подробной информации по этой теме.
- </para>
- <para>
- В Zend Framework вы можете передавать простой индексный массив для
- помощника AutoCompleteDojo, и он будет возвращен в формате,
- пригодном для использования с хранилищем в Dojo:
- </para>
- <programlisting language="php"><![CDATA[
- // в контроллере действий:
- $this->_helper->autoCompleteDojo($data);
- ]]></programlisting>
- <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
- <title>Автодополнение с Dojo и Zend MVC</title>
- <para>
- Автодополнение с Dojo через Zend MVC требует реализации
- нескольких вещей:
- генерация объекта формы для того ComboBox, для которого нужно
- реализовать автодополнение, действие контроллера для
- обслуживания автодополнения, создание своего QueryReadStore для
- связи с этим действием и генерация javascript-кода для
- инициализации автодополнения.
- </para>
- <para>
- Для начала рассмотрим, что нужно сделать по части
- javascript. Dojo представляет собой полный фреймворк для
- создания объектно-ориентированного кода на языке JavaScript,
- почти так же, как Zend Framework на языке PHP. Он позволяет
- создавать псевдопространства имен, используя для этого иерархию
- директорий. Создадим директорию 'custom' на том же уровне,
- что и директория Dojo. В этой директории создадим файл
- TestNameReadStore.js со следующим содержимым:
- </para>
- <programlisting language="javascript"><![CDATA[
- dojo.provide("custom.TestNameReadStore");
- dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
- fetch:function (request) {
- request.serverQuery = { test:request.query.name };
- return this.inherited("fetch", arguments);
- }
- });
- ]]></programlisting>
- <para>
- Этот класс просто наследует от класса QueryReadStore фреймворка
- Dojo, который сам по себе является абстрактным. Мы просто
- определяем метод, по которому производится запрос, и присваиваем
- его элементу 'test'.
- </para>
- <para>
- Далее создадим элемент формы, для которого хотим реализовать
- автодополнение:
- </para>
- <programlisting language="php"><![CDATA[
- class TestController extends Zend_Controller_Action
- {
- protected $_form;
- public function getForm()
- {
- if (null === $this->_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;
- }
- }
- ]]></programlisting>
- <para>
- Здесь мы просто создаем форму с методами 'test' и 'go'. Метод
- 'test' добавляет несколько специальных, специфических для Dojo
- атрибутов: dojoType, store, autoComplete и hasDownArrow. Через
- 'dojoType' мы указываем, что создается ComboBox, он связан
- с хранилищем данных (ключ 'store') 'testStore'. Устанавливая
- 'autoComplete' в false, мы говорим Dojo, чтобы он не выбирал
- автоматически первое соответствие, а вместо этого показывал
- список соответсвий. Наконец, 'hasDownArrow' создает стрелку
- наподобие той, что присутствует в выпадающем списке, чтобы можно
- было выводить и убирать список соответствий.
- </para>
- <para>
- Добавим метод для отображения формы и действие для обработки
- автодополнения:
- </para>
- <programlisting language="php"><![CDATA[
- class TestController extends Zend_Controller_Action
- {
- // ...
- /**
- * Страница с формой
- */
- public function indexAction()
- {
- $this->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);
- }
- }
- ]]></programlisting>
- <para>
- В методе <code>autocompleteAction()</code> мы делаем несколько
- вещей. Сначала мы проверяем, был ли произведен POST-запрос и
- имеет ли параметр 'format' значение 'ajax', это помогает
- отсечь большинство ложных запросов. Далее мы получаем
- параметр 'test' и сравниваем его с нашими данными (здесь я
- намеренно опустил реализацию метода <code>getData()</code>,
- источники данных могут быть любыми). В конце выполнения
- передаем найденные соответствия помощнику AutoCompletion.
- </para>
- <para>
- Теперь на очереди написание скрипта вида для страницы с формой.
- В нем нужно установить хранилище данных, вывести
- форму и подключить все необходимые библиотеки
- Dojo, включая наше хранилище данных. Ниже приведен
- скрипт вида с комментариями:
- </para>
- <programlisting language="php"><![CDATA[
- <?php // установка хранилища данных: ?>
- <div dojoType="custom.TestNameReadStore" jsId="testStore"
- url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
- requestMethod="get"></div>
- <?php // рендеринг формы: ?>
- <?php echo $this->form ?>
- <? // подключение CSS для Dojo в HTML-заголовке: ?>
- <?php $this->headStyle()->captureStart() ?>
- @import "<?php echo $this->baseUrl()
- ?>/javascript/dijit/themes/tundra/tundra.css";
- @import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
- <?php $this->headStyle()->captureEnd() ?>
- <?php // подключение javascript в HTML-заголовке, включая все
- // необходимые библиотеки для Dojo: ?>
- <?php $this->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");
- <?php $this->headScript()->captureEnd() ?>
- ]]></programlisting>
- <para>
- Обратите внимание на вызовы помощников видов, таких, как
- headStyle м headScript, - это метки заполнения, которые могут
- затем рендериться в HTML-заголовке скрипта макета.
- </para>
- <para>
- Теперь у нас есть всё для того, чтобы автодополнение с Dojo заработало.
- </para>
- </example>
- </sect4>
- <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
- <title>Автодополнение с Scriptaculous</title>
- <para>
- <ulink url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
- ожидает HTML-ответ в определенном формате.
- </para>
- <para>
- С этой библиотекой используется помощник
- 'AutoCompleteScriptaculous'.
- Просто передавайте ему массив данных, и он создает ответ HTML,
- совместимый с Ajax.Autocompleter.
- </para>
- </sect4>
- </sect3>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|