1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect3 id="zend.controller.actionhelpers.autocomplete">
4 <title>AutoComplete</title>
7 Многие JavaScript-библиотеки для AJAX предоставляют функционал для
8 автодополнения, с его помощью отображается список
9 возможных соответствий в то время, пока пользователь набирает текст.
10 Помощник <code>AutoComplete</code> предназначен для облегчения возврата
11 допустимых ответов для функционала такого рода.
15 Поскольку не все JavaScript-библиотеки реализуют автодополнение
16 одинаково, то помощник <code>AutoComplete</code> предоставляет в
17 абстрактном классе некоторый базовый функционал, необходимый для
18 большинства библиотек, и конкретные реализации для отдельных библиотек.
20 основном - JSON-массивы строк, JSON-массивы массивов (в которых каждый
21 массив-член является ассоциативным массивом метаданных, используемых при
22 создании списка), либо HTML.
26 Базовое использование одинаково для всех реализаций:
29 <programlisting language="php"><![CDATA[
30 class FooController extends Zend_Controller_Action
32 public function barAction()
34 // Выполнение некоторой логики...
36 // Кодирование и отправка ответа:
37 $this->_helper->autoCompleteDojo($data);
39 // То же самое явным образом:
40 $response = $this->_helper->autoCompleteDojo
41 ->sendAutoCompletion($data);
43 // Или просто подготовьте ответ для автодополнения:
44 $response = $this->_helper->autoCompleteDojo
45 ->prepareAutoCompletion($data);
51 По умолчанию этот помощник делает следующее:
56 Отключает макеты и ViewRenderer.
60 Устанавливает необходимые заголовки ответа.
64 Устанавливает тело ответа с закодированными данными в нужном
65 формате для автодополнения.
74 Доступные методы помощника включают в себя:
79 <code>disableLayouts()</code> может использоваться для
80 отключения макетов и ViewRenderer. Обычно он вызывается в
81 <code>prepareAutoCompletion()</code>.
85 <code>encodeJson($data, $keepLayouts = false)</code> будет
86 кодировать данные в формат JSON, при этом можно опционально
87 включать или отключать макеты. Обычно этот метод вызывается в
88 <code>prepareAutoCompletion()</code>.
92 <code>prepareAutoCompletion($data, $keepLayouts = false)</code>
93 используется для подготовки ответа в формате, необходимом для
94 конкретной реализации, при этом можно опционально включать или
95 отключать макеты. Возвращаемое значение может варьироваться в
96 зависимости от используемой реализации.
100 <code>sendAutoCompletion($data, $keepLayouts = false)</code>
101 используется для отправки данных в формате, необходимом для
102 конкретной реализации. Он вызывает
103 <code>prepareAutoCompletion()</code> и затем отправляет ответ.
107 <code>direct($data, $sendNow = true, $keepLayouts =
109 используется, когда помощник вызывается как метод брокера
110 помощников. Флаг <varname>$sendNow</varname> используется для
111 определения того, какой метод вызывать -
112 <code>sendAutoCompletion()</code> или
113 <code>prepareAutoCompletion()</code>. По умолчанию ответ
119 В настоящее время <code>AutoComplete</code> поддерживает AJAX-библиотеки
120 Dojo и Scriptaculous.
123 <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
124 <title>Автодополнение c Dojo</title>
127 В Dojo нет собственно виджета для автодополнения, но есть два
128 виджета, которые могут производить автодополнение: ComboBox и
129 FilteringSelect. В обоих случаях они требуют использования хранилища
130 данных, который реализует QueryReadStore, читайте документацию по
131 <ulink url="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0">dojo.data</ulink> для получения более подробной информации по этой теме.
135 В Zend Framework вы можете передавать простой индексный массив для
136 помощника AutoCompleteDojo, и он будет возвращен в формате,
137 пригодном для использования с хранилищем в Dojo:
140 <programlisting language="php"><![CDATA[
141 // в контроллере действий:
142 $this->_helper->autoCompleteDojo($data);
145 <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
146 <title>Автодополнение с Dojo и Zend MVC</title>
149 Автодополнение с Dojo через Zend MVC требует реализации
151 генерация объекта формы для того ComboBox, для которого нужно
152 реализовать автодополнение, действие контроллера для
153 обслуживания автодополнения, создание своего QueryReadStore для
154 связи с этим действием и генерация javascript-кода для
155 инициализации автодополнения.
159 Для начала рассмотрим, что нужно сделать по части
160 javascript. Dojo представляет собой полный фреймворк для
161 создания объектно-ориентированного кода на языке JavaScript,
162 почти так же, как Zend Framework на языке PHP. Он позволяет
163 создавать псевдопространства имен, используя для этого иерархию
164 директорий. Создадим директорию 'custom' на том же уровне,
165 что и директория Dojo. В этой директории создадим файл
166 TestNameReadStore.js со следующим содержимым:
169 <programlisting language="javascript"><![CDATA[
170 dojo.provide("custom.TestNameReadStore");
171 dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
172 fetch:function (request) {
173 request.serverQuery = { test:request.query.name };
174 return this.inherited("fetch", arguments);
180 Этот класс просто наследует от класса QueryReadStore фреймворка
181 Dojo, который сам по себе является абстрактным. Мы просто
182 определяем метод, по которому производится запрос, и присваиваем
187 Далее создадим элемент формы, для которого хотим реализовать
191 <programlisting language="php"><![CDATA[
192 class TestController extends Zend_Controller_Action
196 public function getForm()
198 if (null === $this->_form) {
199 $this->_form = new Zend_Form();
200 $this->_form->setMethod('get')
202 $this->getRequest()->getBaseUrl() . '/test/process'
205 'test' => array('type' => 'text', 'options' => array(
206 'filters' => array('StringTrim'),
207 'dojoType' => array('dijit.form.ComboBox'),
208 'store' => 'testStore',
209 'autoComplete' => 'false',
210 'hasDownArrow' => 'true',
211 'label' => 'Your input:',
213 'go' => array('type' => 'submit',
214 'options' => array('label' => 'Go!'))
223 Здесь мы просто создаем форму с методами 'test' и 'go'. Метод
224 'test' добавляет несколько специальных, специфических для Dojo
225 атрибутов: dojoType, store, autoComplete и hasDownArrow. Через
226 'dojoType' мы указываем, что создается ComboBox, он связан
227 с хранилищем данных (ключ 'store') 'testStore'. Устанавливая
228 'autoComplete' в false, мы говорим Dojo, чтобы он не выбирал
229 автоматически первое соответствие, а вместо этого показывал
230 список соответсвий. Наконец, 'hasDownArrow' создает стрелку
231 наподобие той, что присутствует в выпадающем списке, чтобы можно
232 было выводить и убирать список соответствий.
236 Добавим метод для отображения формы и действие для обработки
240 <programlisting language="php"><![CDATA[
241 class TestController extends Zend_Controller_Action
248 public function indexAction()
250 $this->view->form = $this->getForm();
253 public function autocompleteAction()
255 if ('ajax' != $this->_getParam('format', false)) {
256 return $this->_helper->redirector('index');
258 if ($this->getRequest()->isPost()) {
259 return $this->_helper->redirector('index');
262 $match = trim($this->getRequest()->getQuery('test', ''));
265 foreach ($this->getData() as $datum) {
266 if (0 === strpos($datum, $match)) {
270 $this->_helper->autoCompleteDojo($matches);
276 В методе <code>autocompleteAction()</code> мы делаем несколько
277 вещей. Сначала мы проверяем, был ли произведен POST-запрос и
278 имеет ли параметр 'format' значение 'ajax', это помогает
279 отсечь большинство ложных запросов. Далее мы получаем
280 параметр 'test' и сравниваем его с нашими данными (здесь я
281 намеренно опустил реализацию метода <code>getData()</code>,
282 источники данных могут быть любыми). В конце выполнения
283 передаем найденные соответствия помощнику AutoCompletion.
287 Теперь на очереди написание скрипта вида для страницы с формой.
288 В нем нужно установить хранилище данных, вывести
289 форму и подключить все необходимые библиотеки
290 Dojo, включая наше хранилище данных. Ниже приведен
291 скрипт вида с комментариями:
294 <programlisting language="php"><![CDATA[
295 <?php // установка хранилища данных: ?>
296 <div dojoType="custom.TestNameReadStore" jsId="testStore"
297 url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
298 requestMethod="get"></div>
300 <?php // рендеринг формы: ?>
301 <?php echo $this->form ?>
303 <? // подключение CSS для Dojo в HTML-заголовке: ?>
304 <?php $this->headStyle()->captureStart() ?>
305 @import "<?php echo $this->baseUrl()
306 ?>/javascript/dijit/themes/tundra/tundra.css";
307 @import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
308 <?php $this->headStyle()->captureEnd() ?>
310 <?php // подключение javascript в HTML-заголовке, включая все
311 // необходимые библиотеки для Dojo: ?>
312 <?php $this->headScript()
313 ->setAllowArbitraryAttributes(true)
314 ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
316 array('djConfig' => 'parseOnLoad: true'))
318 djConfig.usePlainJson=true;
319 dojo.registerModulePath("custom","../custom");
320 dojo.require("dojo.parser");
321 dojo.require("dojox.data.QueryReadStore");
322 dojo.require("dijit.form.ComboBox");
323 dojo.require("custom.TestNameReadStore");
324 <?php $this->headScript()->captureEnd() ?>
328 Обратите внимание на вызовы помощников видов, таких, как
329 headStyle м headScript, - это метки заполнения, которые могут
330 затем рендериться в HTML-заголовке скрипта макета.
334 Теперь у нас есть всё для того, чтобы автодополнение с Dojo заработало.
339 <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
340 <title>Автодополнение с Scriptaculous</title>
342 <ulink url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
343 ожидает HTML-ответ в определенном формате.
347 С этой библиотекой используется помощник
348 'AutoCompleteScriptaculous'.
349 Просто передавайте ему массив данных, и он создает ответ HTML,
350 совместимый с Ajax.Autocompleter.