1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 20765 -->
4 <sect3 id="zend.controller.actionhelpers.autocomplete">
5 <title>AutoComplete</title>
8 多くの <acronym>AJAX</acronym> 用 javascript ライブラリでは、
10 これは、ユーザがタイプした内容にマッチする可能性のある候補の一覧を表示するものです。
11 <emphasis>AutoComplete</emphasis> ヘルパーは、
12 このような場合に使用できるレスポンスを返すためのものです。
16 オートコンプリート機能の実装方法は JS ライブラリによって異なるので、
17 <emphasis>AutoComplete</emphasis> では多くのライブラリで使用する共通機能を抽象化しています。
18 そして、個々のライブラリにあわせた実装を用意しています。
19 返り値の型は、<acronym>JSON</acronym> 形式の文字列の配列か
20 <acronym>JSON</acronym> 形式の配列の配列
21 (内部の配列は、選択リストを作成する際に使用するメタデータの連想配列)
22 あるいは <acronym>HTML</acronym> となります。
26 どの実装についての基本的な使用法は同じです。
29 <programlisting language="php"><![CDATA[
30 class FooController extends Zend_Controller_Action
32 public function barAction()
37 $this->_helper->autoCompleteDojo($data);
40 $response = $this->_helper->autoCompleteDojo
41 ->sendAutoCompletion($data);
43 // あるいは単純にオートコンプリート用のレスポンスを準備します
44 $response = $this->_helper->autoCompleteDojo
45 ->prepareAutoCompletion($data);
56 レイアウト機能と ViewRenderer を無効にする。
64 レスポンスボディにエンコード/フォーマットしたデータを設定する。
73 このヘルパーでは次のようなメソッドが使用できます。
78 <methodname>disableLayouts()</methodname> は、レイアウト機能と
79 ViewRenderer を無効にします。一般に、これは
80 <methodname>prepareAutoCompletion()</methodname> の中でコールされます。
84 <methodname>encodeJson($data, $keepLayouts = false)</methodname>
85 はデータを <acronym>JSON</acronym> 形式にエンコードし、オプションでレイアウト機能の有効/無効
87 <methodname>prepareAutoCompletion()</methodname> の中でコールされます。
91 <methodname>prepareAutoCompletion($data, $keepLayouts = false)</methodname>
92 は、各種具象実装にあわせてレスポンスデータをフォーマットし、
93 オプションでレイアウト機能の有効/無効を切り替えます。
98 <methodname>sendAutoCompletion($data, $keepLayouts = false)</methodname>
99 は、各種具象実装にあわせてフォーマットしたレスポンスデータを送信します。
100 これは、<methodname>prepareAutoCompletion()</methodname> をコールしたあとでレスポンスを送信します。
104 <methodname>direct($data, $sendNow = true, $keepLayouts =
105 false)</methodname> は、このヘルパーをヘルパーブローカのメソッドとしてコールする場合に使用します。
106 <varname>$sendNow</varname> フラグは、
107 <methodname>sendAutoCompletion()</methodname> と
108 <methodname>prepareAutoCompletion()</methodname> のどちらをコールするかを指定するものです。
113 現在 <emphasis>AutoComplete</emphasis> がサポートしている <acronym>AJAX</acronym>
114 ライブラリは、Dojo と Scriptaculous です。
117 <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
118 <title>Dojo でのオートコンプリート</title>
121 Dojo には、オートコンプリートのためだけのウィジェットはありません。
122 しかし、ComboBox と FilteringSelect
123 のふたつのウィジェットがオートコンプリート機能を持っています。
124 どちらのウィジェットも、QueryReadStore
126 <ulink url="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0">dojo.data</ulink>
131 Zend Framework では、単純な数値添字の配列を
132 AutoCompleteDojo ヘルパーに渡します。
133 そうすると、適切な形式の <acronym>JSON</acronym> オブジェクトを返します。
136 <programlisting language="php"><![CDATA[
138 $this->_helper->autoCompleteDojo($data);
141 <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
142 <title>Zend MVC を使用した、Dojo でのオートコンプリート</title>
145 Zend <acronym>MVC</acronym> で Dojo によるオートコンプリートを使用するには、
146 いくつかの準備が必要です。オートコンプリートを使用したい
147 ComboBox 用にフォームオブj稀有とを作成し、
148 オートコンプリートの結果を提供するためのコントローラアクションを作成し、
149 オートコンプリートアクションに接続するための
150 独自の QueryReadStore を作成し、
151 サーバ側でオートコンプリートを行わせるための javascript
156 まずは、必要となる javascript を見ていきましょう。
157 Dojo は javascript によるオブジェクト指向プログラミングを行うための
158 完全なフレームワークで、ちょうど <acronym>PHP</acronym> における Zend Framework
160 ディレクトリ構造を用いて擬似的な名前空間を作成する機能もあります。
161 ここでは、Dojo の配布ファイルの Dojo
162 ディレクトリと同じ階層に 'custom' ディレクトリを作成します。
163 そのディレクトリの中に <filename>TestNameReadStore.js</filename>
164 という javascript ファイルを作成し、次のようなコードを書きます。
167 <programlisting language="javascript"><![CDATA[
168 dojo.provide("custom.TestNameReadStore");
169 dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
170 fetch:function (request) {
171 request.serverQuery = { test:request.query.name };
172 return this.inherited("fetch", arguments);
178 このクラスは、単に Dojo 自身の QueryReadStore
179 クラスを継承したものです。継承元のクラス自体は抽象クラスです。
180 そこにリクエスト用のメソッドを定義し、'test'
185 次に、オートコンプリートを行うためのフォーム要素を作成します。
188 <programlisting language="php"><![CDATA[
189 class TestController extends Zend_Controller_Action
193 public function getForm()
195 if (null === $this->_form) {
196 $this->_form = new Zend_Form();
197 $this->_form->setMethod('get')
199 $this->getRequest()->getBaseUrl() . '/test/process'
202 'test' => array('type' => 'text', 'options' => array(
203 'filters' => array('StringTrim'),
204 'dojoType' => array('dijit.form.ComboBox'),
205 'store' => 'testStore',
206 'autoComplete' => 'false',
207 'hasDownArrow' => 'true',
208 'label' => 'Your input:',
210 'go' => array('type' => 'submit',
211 'options' => array('label' => 'Go!'))
220 ここでは、単に 'test' と 'go' メソッドのみを持つフォームを作成します。
221 'test' メソッドは、特別な Dojo 固有の属性
222 dojoType、store、autoComplete および hasDownArrow
223 を追加します。dojoType では、これから ComboBox
224 を作成することを指定します。そして、それを 'testStore' のデータストア
225 (キー 'store') にリンクします。詳細は後ほど説明します。
226 'autoComplete' を <constant>FALSE</constant> に設定することで、
227 最初にマッチしたものを自動選択するのではなく
228 マッチしたものの一覧を表示するよう Dojo に指示します。
229 最後に 'hasDownArrow' でセレクトボックス風の下向き矢印を作ります。
230 これで、マッチしたものを表示したり隠したりできるようになります。
235 オートコンプリートの処理用のエンドポイントを作成してみましょう。
238 <programlisting language="php"><![CDATA[
239 class TestController extends Zend_Controller_Action
246 public function indexAction()
248 $this->view->form = $this->getForm();
251 public function autocompleteAction()
253 if ('ajax' != $this->_getParam('format', false)) {
254 return $this->_helper->redirector('index');
256 if ($this->getRequest()->isPost()) {
257 return $this->_helper->redirector('index');
260 $match = trim($this->getRequest()->getQuery('test', ''));
263 foreach ($this->getData() as $datum) {
264 if (0 === strpos($datum, $match)) {
268 $this->_helper->autoCompleteDojo($matches);
274 <methodname>autocompleteAction()</methodname>
276 まず、POST リクエストを受け取ったことを確実にし、
277 'format' パラメータの値を 'ajax' に設定します。
278 これにより、余計なクエリがアクションに送られることを減らします。
279 次に、'test' パラメータの内容を確認し、私たちのデータと比較します
280 (ここでは、<methodname>getData()</methodname> の実装は意図的に控えています。
281 何らかのデータソースを使用することになるでしょう)。
282 最後に、マッチした内容を AutoCompletion ヘルパーに送信します。
286 これでバックエンド側の準備はすべて整いました。
287 次に、ページのビュースクリプト側ではどうすればいいのかを考えてみましょう。
288 まず、データストアを用意しなければなりません。
289 次にフォームをレンダリングし、最後に適切な Dojo ライブラリ
290 (使用するデータストアも含む) を読み込みます。
295 <programlisting language="php"><![CDATA[
296 <?php // データストアの準備 ?>
297 <div dojoType="custom.TestNameReadStore" jsId="testStore"
298 url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
299 requestMethod="get"></div>
301 <?php // フォームのレンダリング ?>
302 <?php echo $this->form ?>
304 <?php // Dojo 関連の CSS の、HTML head での読み込み ?>
305 <?php $this->headStyle()->captureStart() ?>
306 @import "<?php echo $this->baseUrl()
307 ?>/javascript/dijit/themes/tundra/tundra.css";
308 @import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
309 <?php $this->headStyle()->captureEnd() ?>
311 <?php // 必要な Dojo ライブラリを含む javascript の、
312 // HTML head での読み込み ?>
313 <?php $this->headScript()
314 ->setAllowArbitraryAttributes(true)
315 ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
317 array('djConfig' => 'parseOnLoad: true'))
319 djConfig.usePlainJson=true;
320 dojo.registerModulePath("custom","../custom");
321 dojo.require("dojo.parser");
322 dojo.require("dojox.data.QueryReadStore");
323 dojo.require("dijit.form.ComboBox");
324 dojo.require("custom.TestNameReadStore");
325 <?php $this->headScript()->captureEnd() ?>
329 headStyle や headScript といったビューヘルパーのコールに注意しましょう。
330 これらはプレースホルダで、ビュースクリプトをレンダリングする際に
331 <acronym>HTML</acronym> の head セクションとなります。
335 これで、Dojo のオートコンプリートを動作させるための準備がすべて整いました。
340 <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
341 <title>Scriptaculous でのオートコンプリート</title>
343 <ulink url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
344 は、所定の形式の <acronym>HTML</acronym> レスポンスを受け取ることを想定しています。
348 このライブラリで使用するヘルパーは 'AutoCompleteScriptaculous' です。
349 このヘルパーにデータの配列を渡せば、Ajax.Autocompleter
350 に対応した形式の <acronym>HTML</acronym> レスポンスができあがります。