DWR(3)
DWRの基本的な動きがわかってきたので、何か実際に作ってみることにした。選んだのはこの間XMLHttpRequestで作ったインクリメンタル検索機能付きリストボックス。
まずはサーバ側の改造。
package test; import java.util.ArrayList; public class ProductList { public ArrayList getItems(String key) { String[] pname = { "130", "230Cs", "235", "240", "240X", "240Z", "310", "310E", "315D", // : (途中ry "TransNote", "X20", "X21", "X22", "X23", "X24", "X30", "X31", "X32", "X40", "X41" }; int keylen = key.length(); // 結果を格納するarray ArrayList result = new ArrayList(); // ""以外が選択されていればoptionデータを追加 if (key != null && !key.equals("")) { for (int i = 0; i < pname.length; i++) { if (pname[i].length() >= keylen && key.equals(pname[i].substring(0, keylen))) { result.add(new String[] { "code_of_" + pname[i], pname[i] }); } } } return result; } }
サーブレットだったProductChangedに対してこれはPOJO。resultにadd()している各String型配列の0番目がリストボックスで選択されたとき返す値、1番目が表示させるテキスト。これをDWRがinstallされていてる環境へ追加し、さらにdwr.xmlにも以下の記述を追加する。
<create creator="new" javascript="Product"> <param name="class" value="test.ProductList"/> </create>
この状態でhttp://hogehoge/[WEB-APP-NAME]/dwr/test/Productをアクセスすると、このtest.Productのテストページが表示される。このページには
- このクラスをブラウザからアクセスするときに必要となるJavaScriptのファイル名(ソース名)
- 公開されているメソッド名のリスト
- 問題が発生したときの対処方法
などが記載されている。上記リストにはgetItems()も含まれているが、ブラウザ上から引数を与えて実行させ、帰ってくる値をチェックすることもできる。これ便利。
そしてクライアント側はこんな感じ。自分でXMLHttpRequestを操作するのに比べるとだいぶすっきり。
<html lang="ja"> <head> <title>List test</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <script type='text/javascript' src='/dwrsample/dwr/interface/Product.js'></script> <script type='text/javascript' src='/dwrsample/dwr/engine.js'></script> <script type='text/javascript' src='/dwrsample/dwr/util.js'></script> <script type="text/javascript"> </script> </head> <body onload="startup();"> <form name="form1"> 製品名:<BR> <input type="text" id="pname" STYLE="width: 150px;" onkeyup="getNewProductName()"><BR> <select name="productname" id="productname" STYLE="width: 150px;" size=5> <option value=""></option> </select> <P> </form> </body> </html>
上から見ていくと、FormがLoadされたとき実行するstartup()から呼び出されるDWRUtil.useLoadingMessage()は、DWRを実行しているとき"Loading"というメッセージをGmail風にWindowの右上に表示するためのもの。残念ながら表示されるメッセージは"Loading"固定らしい。
テキストフィールドのonkeyupイベントで実行するgetNewProductName()では、DWRが生成したProxy JavaScript(/dwrsample/dwr/interface/Product.js)を経由してサーバ上のProduct#getItems()を呼び出す。引数の先頭にあるpopulateListは、このgetItems()終了後実行する関数(コールバック関数)。$()も関数で、引数で与えられたidに該当するHTML要素を探して返す。document.getElementById("pname")みたいなもの。でもソースを見ると引数は任意個OKで、その場合の戻り値はArrayとなっている。
コールバックされるpopulateListでは、最初にDWRUtil.removeAllOptions()で指定されたidの要素のoptionを全て削除する。ソースを見るとselectのほか、ul, olもOKっぽい。そしてaddOptions()で"productname"のoptionにdataの内容をセットする。このdataはgetItems()の返したArrayListになる。0, 1は何かというと、optionのvalueと表示するテキストがdataの各要素のそれぞれ何番目なのかを表す添字。はじめ何を指定すればいいのかわからなく困ったけど、これもソースを見たら一発でわかりましたw。
一応IE6.0/FireFox1.0で動きます。