YUI を用いてオートコンプリートを実装する方法
Yahoo! UI Library には Auto Complete を簡単に実装できる便利な機能が実装されています。これを用いて AutoComplete を実装する方法を記載します。
この資料では Yahoo! UI Library (以下 YUI) を利用しています。必要に応じてお使いの環境にインストールしてください。
尚、この資料を書いている2008年 9 月 1 日現在、バージョン 2.5.2 です。
Yahoo! UI Library
デモはこちらになります。以下のテキストボックスにアメリカの都市名 (例: New York, Seattle, Los Angeles...) を入力すると、 サーバー上にあるアメリカの都市データから入力候補を表示します。
US City:
実行中のスクリーンショットはこのようになります (上記で試せますが...)
実装方法 (Step-By-Step)
ここでは、上記の例のように入力された文字列を使って、バックエンドでサーバーに問い合わせを行い、 入力候補を表示するタイプのオートコンプリートを考えます。市町村のデータのように、潜在的に候補となるデータが膨大になる場合、 クライアント側にデータをあらかじめダウンロードしておくことが難しいため、ユーザーの入力に応じて必要なデータをサーバーから 取ってくると良いでしょう。(YUI ではあらかじめダウンロードしておいたデータソースからのオートコンプリート等も用意してあるようですが、 ここではそれは扱いません。)
ここで実装するオートコンプリートでは、クライアント側とサーバー側が協調して動作する必要があります。 クライアントからは、適切なタイミングで適切なクエリをサーバーに送信し、レスポンスを適切に解釈してそれを表示します。 サーバー側ではクライアントからのリクエストを適切に解釈し、クライアントが読める形式でレスポンスを返す必要があります。
まずはクライアント側の実装です。非常に簡単です。
クライアント - JavaScript
1. HTML フォームを用意する
この資料では上記のように市町村の名前を入力する (データの都合でアメリカの市ですが...) テキストボックスがひとつあるだけのフォームを考えます。
US City: <input id="txt1" style="width:300px"> <div id="div1"></div>
2. ac.js を作る
次の内容を ac.js という名前で作成します。ac.js という名前は便宜上この資料のためにつけたもので、任意の名前でかまいません。 変更されたい方は以下の内容をご自身のファイル名で読み替えてください。
Event.observe(window,'load',window_onload,false); function window_onload(evt){ var d = new YAHOO.widget.DS_XHR("ac_test.php",["ResultSet.Result","city"]); d.queryMatchContains = true; d.scriptQueryParam = "q"; // Instantiate AutoComplete var ac = new YAHOO.widget.AutoComplete("txt1","div1", d); ac.minQueryLength = 3; ac.queryDelay = 0.2; ac.useShadow = true; ac.typeAhead = true; ac.forceSelection = false; ac.typeAhead = false; ac.animVert = true; ac.animHoriz = false; ac.allowBrowserAutocomplete = false; ac.setHeader('<div class="yui_ac_header">こちらですか?</div>'); ac.setFooter('<div class="yui_ac_footer">KeiCode.com Sample </div>'); ac.formatResult = function(r, q) { var s = r[0].substr(0,q.length); var k = r[0].substr(q.length); var m = ["<div>", "<span class='yui_ac_match'>", s, "</span>", k, "</div>"]; return m.join(''); }; ac.doBeforeExpandContainer = function(t, c, q, r) { var pos = YAHOO.util.Dom.getXY(t); pos[1] += YAHOO.util.Dom.get(t).offsetHeight; YAHOO.util.Dom.setXY(c,pos); return true; }; }
3. 必要な CSS を JavaScript をインクルードする
以下の内容を HTML ファイルの HEAD に含めます。
<link rel="stylesheet" type="text/css" href="../js/yui/build/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="../js/yui/build/autocomplete/assets/skins/sam/autocomplete.css" /> <style type="text/css"> .yui-skin-sam .yui-ac-container {position:absolute;top:1.6em;width:300px;} div.yui_ac_header {padding:2px;background-color:#ccc;color:#eee;font-size:9pt;} div.yui_ac_footer {text-align: right;color:#aaa;font-size:0.8em;} span.yui_ac_match {font-weight:bold;} </style> <script type="text/javascript" src="../js/prototype.js"></script> <script type="text/javascript" src="../js/common.js"></script> <script type="text/javascript" src="../js/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="../js/yui/build/animation/animation-min.js"></script> <script type="text/javascript" src="../js/yui/build/connection/connection-min.js"></script> <script type="text/javascript" src="../js/yui/build/autocomplete/autocomplete-min.js"></script> <script type="text/javascript" src="ac.js"></script>
クライアント側はこれだけです。次にサーバー側の実装です。
サーバー側
ここではサーバーに渡すパラメータの名前は q で、受け取るデータは city としています。 次のような形式でサーバーを返すことができれば、サーバー側のテクノロジは何を使ってもかまいません。
{ "ResultSet" : { "totalResultsAvailable" : 件数, "totalResultsReturned" : 件数, "firstResultPosition" : 順番, "Result" : 結果 (JSON) } }
今回の例では q という名前のパラメータで "Torr" という文字を受け取ったときに、サーバーは次のようなデータを返します。
{ "ResultSet" : { "totalResultsAvailable" : 4, "totalResultsReturned" : 4, "firstResultPosition" : 1, "Result" : [ {"city":"Torrance"}, {"city":"Torreon"}, {"city":"Torrey"}, {"city":"Torrington"} ] } }
サーバー側で JSON 形式の応答を返す場合、PHP なら json_encode 関数が使えます。配列に必要なデータを入れて、 この関数を呼べば、上記のようないい感じの形式を作ってくれます。他の言語については JSON のサイトで探してください。