Script.aculo.usのコントロールでWebアプリケーションをもっと使いやすくはじめに筆者はDevXの以前の記事で、動的なWebアプリケーションの開発に役立つJavaScriptフレームワーク「Prototype」を取り上げましたが、その記事の最後で、PrototypeをベースにしたUIライブラリであるScript.aculo.usについて少し触れました。本稿ではScript.aculo.usが提供するオートコンプリータ、インプレースエディタ、スライダというWebコントロールについて説明します。Script.aculo.usは大きなライブラリなので、1つの記事で網羅的に説明することはできません。しかし、本稿の説明を読めば、Script.aculo.usのWebコントロールを利用してエンドユーザーエクスペリエンスを向上させることができるでしょう。 環境のセットアップまずブラウザでPrototypeのホームページにアクセスし、最新バージョン(本稿の執筆時点では1.6.0.2)をダウンロードしてください。実際に必要なファイルは「prototype.js」だけです。次にScript.aculo.usをダウンロードします。ダウンロードページにアクセスし、最新バージョン(本稿の執筆時点では1.8.1)をダウンロードしてください。アーカイブを解凍し、「src」ディレクトリの下にあるファイルを「prototype.js」と一緒に適当なディレクトリの下に配置します。筆者は「scripts」ディレクトリの下に配置しました。以降の説明では、このディレクトリが何度も出てきます。 この時点で、次のスクリプトファイルを次のようなコードを使って自分のページに組み込めば、Script.aculo.usのコントロールをアプリケーションで使用できるようになります。 <script type="text/javascript" src="scripts/prototype.js"></script> <script type="text/javascript" src="scripts/scriptaculous.js?load=effects,controls"></script> 環境が設定されたら、Script.aculo.usコントロールの世界がどのようなものか探索してみることができます。まずはオートコンプリータから始めることをお勧めします。これが最もよく使われるコントロールです。 ''注''
お気づきかもしれませんが、Script.aculo.usはPrototypeよりも高度にモジュール化されています。そのため、ライブラリの中の必要な部分だけを組み込むことができます。ただし、Script.aculo.usライブラリ全体を必要とする場合は、次の構文によって全体を組み込むことができます。
<script type="text/javascript" src="scripts/scriptaculous.js"> </script> オートコンプリータオートコンプリータがどのようなものかご存じない方は、WeeFlyのホームページにアクセスして実際の動作を確かめてみるとよいでしょう。WeeFlyは最新技術を利用した格安航空チケット&ホテル検索エンジンです。WeeFlyのトップページには2つのテキストボックスがあります。1つ目では出発空港、2つ目では到着空港を指定します。[Departure Airport]フィールドに、空港名を構成する文字列として少なくとも3文字を入力してください。その文字列が含まれている空港名のドロップダウンリストが表示されるはずです。図1は、「MIL」を検索文字列として指定したときの結果です。 図1 WeeFlyのDeparture Airportフィールドで使われているオートコンプリータ。このフィールドに少なくとも3文字(この例ではMIL)を入力すると、一致する空港名のリストが表示されます。 ![]() 既にお気づきでしょうが、オートコンプリータはテキストボックスと隠れた <div>とで構成されており、後者はユーザーがテキストボックスに3文字を入力すると表示されます。もちろん、オートコンプリータは<div>を表示する前に、ユーザーの要求に一致するアイテムのリストを用意しなければなりません。しかし、これらのアイテムをどのように取得するのでしょうか。基本的には、アイテムが存在する場所に応じて、次の2つの方法のいずれかを使用します。
Ajaxベースのオートコンプリータの使用このタイプのオートコンプリータの動作は次のようになります。ユーザーが一定の文字数を入力すると、入力された文字列に一致するデータを取得するために非同期の要求を開始します。もちろん、サーバーサイドの処理を記述するための言語/テクノロジはJSP、サーブレット、ASP.NETなど、自分にとって都合のよいものを使ってかまいません。本稿ではPHPを使用します。Script.aculo.usを使用する場合、Ajaxベースのオートコンプリータは Ajax.Autocompleterクラスを使って作成できます。次に例を示します。
new Ajax.Autocompleter(
'autoCompleteTextField',
'autoCompleteMenu',
'countries-list.php',
{
minChars: 1
}
);
リスト1 国名リストのオートコンプリータ
<html> <head> <style type="text/css"> div.auto_complete { width: 350px; background: #72f068; font-size: 9pt; color: #234e87; font-family: arial; } div.auto_complete ul { border:1px solid #888; margin:0; padding:0; width:100%; list-style-type:none; } div.auto_complete ul li { margin:0; padding:3px; } div.auto_complete ul li.selected { background-color: #234e87; color: #fff; } div.auto_complete ul strong.highlight { color: #800; margin:0; padding:0; } </style> <script type="text/javascript" src="../scripts/prototype.js"></script> <script type="text/javascript" src="../scripts/script.aculo.us.js?load=effects,controls"> </script> <script type="text/javascript"> function buildAutocompleter() { new Ajax.Autocompleter( 'autoCompleteTextField', 'autoCompleteMenu', 'countries-list.php' ); } Event.observe(window, "load", buildAutocompleter); </script> </head> <body> <div> <label>Text field:</label> <input type="text" style="width: 300px;" id="autoCompleteTextField" name="autoCompleteTextField"/> <div id="autoCompleteMenu" class="auto_complete"> </div> </div> </body> </html> <div>にWeeFlyと同じような外観を与える働きをします(CSSコードの詳細については本稿では説明しません)。<body>セクションはごく簡単です。ここにはラベル、テキストボックス、そして一致したアイテムが入る<div>が含まれます。中心的な関数はbuildAutocompleterで、これはウィンドウのロード時に呼び出されます(Prototypeフレームワークで提供されるEvent.observeメソッドのおかげです)。ご覧の通り buildAutocompleterはAjaxベースのオートコンプリータを作成し、そこにテキストボックス、<div>、およびデータを取得するために呼び出すコンポーネントをアタッチします。Ajax.Autocompleterはサーバーの応答が次の形式になっていることを想定しています。<ul> <li>Item1</li> <li>Item2</li> ... </ul> リスト2 countries-list.php
<?php
require_once("countries.inc.php");
if(!isset($_REQUEST["autoCompleteTextField"]))
{
die();
}
$chars = $_REQUEST["autoCompleteTextField"];
$listToReturn = array();
foreach($list as $name)
{
if(strtolower($chars) ==
substr(strtolower($name), 0, strlen($chars)))
{
$listToReturn[] = $name;
}
}
if(count($listToReturn) == 0)
{
die();
}
echo "<ul>";
foreach($listToReturn as $item)
{
echo "<li>" . $item . "</li>";
}
echo "</ul>";
?>
図2 国名リストを表示するAjaxベースのオートコンプリータ。PHPスクリプトcountries.inc.phpの表示例です。 ![]() オートコンプリータのカスタマイズ既に見たように、Ajax.Autocompleterコンストラクタは4つのパラメータを受け取ります。4番目のパラメータは、オートコンプリータのカスタマイズに使用する任意指定のリテラルオブジェクトです。このオブジェクトのプロパティのうちで最もよく使われるものを表1に示します。表1 Ajaxベースのオートコンプリータのカスタマイズオプション
new Ajax.Autocompleter( 'autoCompleteTextField', 'autoCompleteMenu', 'countries-list.php', { minChars: 2, frequency : 0.5, indicator : "loadingGif", afterUpdateElement : function(){alert($F("autoCompleteTextField"));}, } ); 表1のオプションはローカルオートコンプリータでも使用できます(ただし、parametersなど一部のオプションはローカルでは意味を持ちません)。 ローカルオートコンプリータの使用Script.aculo.usでは、Ajaxベースのオートコンプリータに加えて、ローカルオートコンプリータも使用できます。ところで、ローカルオートコンプリータとは何でしょうか。基本的に、データがサーバーではなくてローカルなJavaScript配列内に格納されているオートコンプリータのことです。次の例はローカルオートコンプリータの作成方法を示しています。
new Autocompleter.Local(
'autoCompleteTextField',
'autoCompleteMenu',
COUNTRY_LIST,
{
minChars: 2
}
);
表2 ローカルオートコンプリータのカスタマイズオプション
カスタムオートコンプリータの実装既に述べたように、Ajaxベースのオートコンプリータの問題点は、サーバー応答として順序なしリスト<ul>を想定していることです。この節では、どんなタイプの応答でも処理できるオートコンプリータの実装方法を具体例で示すことにします。この例では、サーバー応答をリスト更新用のScript.aculo.us関数に渡す前にインターセプトし、オートコンプリータのコンストラクタ呼び出し時にパラメータで定義したコールバック関数へと渡します。クライアントコードでこのコールバック関数を実装するわけですが、この関数ではXMLやJSON、あるいはその他の形式の応答を解析し <ul>ブロックを組み立てて、それをScript.aculo.usのupdateChoices関数に渡します(この関数によってリストが更新されます)。このオートコンプリータをAjax.Autocompleter.Customと呼ぶことにします。実装は次のとおりです。
Ajax.Autocompleter.Custom = Class.create(Ajax.Autocompleter, {
initialize: function(element, update, url, options) {
this.baseInitialize(element, update, options);
this.options.asynchronous = true;
this.options.onComplete = this.onComplete.bind(this);
this.options.defaultParams = this.options.parameters || null;
this.url = url;
this.options.responseProcessor =
this.options.responseProcessor || Prototype.K;
},
onComplete: function(request) {
var htmlUL =
this.options.responseProcessor(request.responseText,
this.element);
if(htmlUL)
{
this.updateChoices(htmlUL);
}
}
});
responseProcessorという追加的なパラメータの定義とonCompleteの再定義だけです。responseProcessorパラメータは、次の2つのパラメータを受け取るコールバック関数でなければなりません。
onCompleteを再定義したのは、updateChoicesの呼び出しをインターセプトすることにより、クライアントコードで定義したコールバック関数がサーバー応答を処理して、updateChoicesで期待される適切な文字列を用意できるようにするためです。この新しいオートコンプリータの使用例をリスト3に示します(本稿のダウンロードサンプルに完全なコードが収録されています)。リスト3 新しいオートコンプリータの使用例
function jsonResponseProcessor(respText, elem) { var countries = eval(respText); var ret = "<ul>"; for(var i = 0; i < countries.length; ++i) { ret += "<li>" + countries[i] + "</li>"; } ret += "</ul>"; return ret; } function buildAutocompleter() { new Ajax.Autocompleter.Custom( 'autoCompleteTextField', 'autoCompleteMenu', 'countries-list-json.php', { responseProcessor : jsonResponseProcessor } ); } jsonResponseProcessorというコールバック関数を使用しています。同じようにしてXML応答を解析するコールバック関数も簡単に実装できます。応答プロセッサをどのように定義するかは開発者の自由です。コールバック関数の出力は<ul>ブロックを表す文字列である必要がありますが、その他の部分は自由に実装してかまいません。インプレースエディタインプレースエディタとは、基本的には、ユーザーがクリックして編集できるテキストを含んだ<div>のことです。このコントロールに関係する要素は次のとおりです。
リスト4 ごく単純なインプレースエディタの例
<html> <head> <script type="text/javascript" src="../scripts/prototype.js"> </script> <script type="text/javascript" src="../scripts/script.aculo.us.js"> </script> <script type="text/javascript"> Event.observe(window, "load", function() { new Ajax.InPlaceEditor('elem', 'editor-test.php', { okText: 'Update', cancelText: 'Cancel', size: 70 } ); } ); </script> </head> <body> <div id="elem" style="width: 300px;"> Click here to make the text editable</div> </body> </html> 図3 インプレースエディタの初期状態 ![]() 図4 ユーザーがテキストをクリックした後のインプレースエディタの状態 ![]()
表3 インプレースエディタのカスタマイズオプション
スライダスライダはデスクトップアプリケーションで日常的に使われているコントロールです。例えば、ボリュームコントロールはスライダの典型例です。スライダは基本的に「トラック」と、トラックに沿って動かせる「ハンドル」とから成っています。次の例では、ユーザーがハンドルをドラッグしたときに値を表示する簡単なスライダを作成しています。Event.observe(window, "load", function() { new Control.Slider( 'sliderHandle', 'sliderTrack', { range : $R(0, 100), values : [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], onChange : updateValue, onSlide : updateValue } ); } ); このコードでは、 Control.Sliderのインスタンスを作成し、そこに次のパラメータを渡します。
onChangeとonSlideのどちらについても、コールバック関数としてupdateValueを使用しました。この関数はスライダの現在の値を表示する<div>の状態を更新するだけです。このHTMLコードの要件は、次のように、ハンドルがトラックの子要素でなければならないという点だけです。 <div id="sliderTrack"> <div id="sliderHandle"></div> </div> 図5 スライダの動作 ![]() 最後にもう1つヒントを紹介しておきましょう。次のようにすると、スライダの値をプログラム的に変更することができます。 var sliderRef = new Control.Slider( 'sliderHandle', 'sliderTrack', { range: $R(0, 100), values : [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], onChange : upDateValue, onSlide : updateValue } ); // set the slider value sliderRef.setValue(80); Control.SliderクラスのsetValueメソッドを使って値を変更できます。エンドユーザーエクスペリエンスの向上これまでアプリケーション開発の世界では、応答性や使用できるコントロールの多彩さといった理由から、Webアプリケーションよりもデスクトップアプリケーションの方が好まれてきました。しかし今日では、Script.aculo.usなどのUIライブラリとAjaxライブラリを利用することで、応答性も見栄えもよいWebアプリケーションを開発できます。本稿では、Script.aculo.usのコントロールをWebアプリケーションに組み込んで、より良いエンドユーザーエクスペリエンスを実現するための方法を紹介しました。 著者紹介Alessandro Lacava(Alessandro Lacava)
イタリアを活動拠点とするソフトウェア開発者、テクニカルライター。Javaと.NETテクノロジ、Webアプリケーション、通信システムを得意分野とする。通信エンジニアリングの資格を保有。連絡先については個人のWebサイトを参照。
関連記事 最新トップニュース
|
|