前回,Ajaxプログラミングを効率化する手段として,ライブラリやフレームワークの導入について述べました。様々な環境に対応したAjaxライブラリ/フレームワークが数あまた提供されていることがおわかりになったと思います。最終回である今回は,その中でも比較的手軽に導入することができるJKL.Hina+JKL.ParseXMLライブラリを使って,本連載の第6回で紹介したyahoo.htmlを改良してみましょう。

JKL.Hina+JKL.ParseXMLライブラリを使ってみよう

 前回,すでにライブラリの概要については紹介してありますので,さっそくyahoo.htmlを書き換えてみることにしましょう(リスト1)。

リスト1●JKL.Hina+JKL.ParseXMLライブラリを使ったコード(yahoo_jkl.html)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--必要なライブラリをあらかじめロード-->
<script language="JavaScript" src="jkl-parsexml.js"></script>
<script language="JavaScript" src="jkl-hina.js"></script>
<title>Yahoo! ウェブ検索Webサービス</title>
<script language="JavaScript">
<!--
 // [検索]ボタンをクリック時の処理を定義
function search() {
  result.innerHTML="通信中…";
   // サーバーからの応答時の処理を定義(結果のテンプレートへの反映)
  var callback = function(data){
    var hina=new JKL.Hina("template");
    template.style.display="block";
    hina.expand(data['ResultSet'],"result");
    template.style.display="none";
  };
  var jkl = new JKL.ParseXML("yahoo.php?keyword=" 
    + encodeURI(document.fm.keyword.value));  // 送信先URLの指定
  jkl.async(callback);  // 非同期通信の設定
  jkl.parse();          // リクエスト開始
}
-->
</script>
</head>
<body onload="template.style.display='none';">
<form name="fm">
  キーワード:
  <input type="text" name="keyword" size="15" maxlength="30" />
  <input type="button" value="検索" onclick="search()" />
  <hr />
  <!--出力テンプレートの定義-->
  <div id="template">
    <div title="@foreach info [/Result]">
      <li>
        <a _href="[/info/Url]" target="_blank">[/info/Title]</a>
      </li>
    </div>
  </div>
  <!--出力先のプレイスホルダ(置き場所)-->
  <ol type="1">
    <div id="result" />
  </ol>
</form>
</body>
</html>

 コードの大まかな流れについては,リスト内のコメントや前回までの解説を参照いただくとして,ここではポイントとなる3点にフォーカスしてみましょう。

(1)JKL.ParseXMLライブラリで非同期通信を行う
 JKL.ParseXMLライブラリで非同期通信を行っているのは,以下の部分です。

  var jkl = new JKL.ParseXML("yahoo.php?keyword="
               + encodeURI(document.fm.keyword.value));
  jkl.async(callback);
  jkl.parse();

JKL.ParseXMLライブラリの使い方はカンタン。JKL.ParseXMLライブラリのコンストラクタにXMLデータの取得先(ここではXMLデータを生成するPHPスクリプト)を指定した後,asyncメソッドでコールバック関数を指定するだけです*1。あとは,parseメソッドを呼び出すだけでXMLデータを取得できます。元のコードにあったXMLHttpRequestオブジェクトによる通信の手続きが一切不要であることがおわかりになるでしょう。

 取得したXMLデータは配列形式に変換されたうえで,コールバック関数(ここではcallback関数)の引数として渡されます。変換済みの配列にアクセスするには,例えば,以下のように記述します。

  data['ResultSet']['Result'][0]['Title']

これによって,「<ResultSet>要素配下の1番目の<Result>要素の<Title>要素」の値を取得できます。DOMによってノードウォーキングするのに比べ,はるかに直感的なコードで各要素にアクセスできることがおわかりになるはずです。

(2)JKL.Hinaクラスでテンプレートを記述する
 サーバーからデータを取得できたところで,いよいよJKL.Hinaライブラリの登場です。あらかじめ用意したテンプレートに対して必要なデータを流し込んでみましょう。

 まずはレイアウトを規定するテンプレートを用意する必要があります。JKL.Hinaライブラリで利用可能なテンプレートは,

タグに記述します。本サンプルでは,以下の部分です。

  <div id="template">
    <div title="@foreach info [/Result]">
      <li>
        <a _href="[/info/Url]" target="_blank">[/info/Title]</a>
      </li>
    </div>
  </div>

テンプレートに変数を埋め込むには,「[/変数名]」の形式で指定します。ただし,属性値として変数を埋め込む場合には,対応する属性名の先頭にアンダースコア(_)を付与しなければならない点に注意してください。

 配列に含まれるデータを順に取り出すのは,@foreach命令の役割です。JKL.Hinaライブラリでは,テンプレート内で条件分岐や繰り返し処理のようなごく基本的な制御構文にも対応しているのが特徴です。以下に@foreach命令の一般的な構文を示します。

  @foreach 取り出したデータを格納する一時変数 [元となる配列データ]

@foreachのような命令はtitle属性の値として記述する必要があります。取り出した一時変数には,<Result>要素が含まれているはずです。ループ内で<Result>要素配下の要素にアクセスするには,スラッシュ(/)区切りで「[/info/Url]」のように記述してください。

 なお,テンプレートはページロード時に非表示(displayプロパティを"none"に設定)にしておく必要があります。さもないと,未解析のテンプレートがそのままページ上に表示されてしまいますので,注意してください。

(3)JKL.Hinaクラスからテンプレートを利用する
 最後に,(2)で用意したテンプレートに対して,データを流し込んでいるのが,コールバック関数の中の以下の部分です。

  var hina=new JKL.Hina("template");
  template.style.display="block";
  hina.expand(data['ResultSet'],"result");
  template.style.display="none";

JKL.Hinaクラスのコンストラクタには,適用するテンプレートのID値を指定します。テンプレートを使用するにあたっては先ほど非表示にしたテンプレートを表示状態(displayプロパティを"block"に設定)にする必要があります。さもないと,正しくテンプレートが適用されませんので,注意が必要です。

 テンプレートを適用するのは,expandメソッドの役割です。第1引数から引き渡すデータ,適用結果の出力先(ID値)を指定します。テンプレートを使用した後は,テンプレートを元の非表示状態に戻すのを忘れないようにしてください。

 以上を理解したら,yahoo_jkl.htmlを実行してみましょう。yahoo.html同様,入力したキーワードに対応するサイト検索の結果が表示されれば成功です。

まとめ

 以上,全9回を通じて,Ajaxプログラミングのごく基本的な事項を学んできました。もっとも,Ajax技術を利用するうえでは知っておかなければならないことはまだまだ多くあります。特に最後に扱ったAjax対応ライブラリなどは種類も利用環境も様々で,興味深いトピックスも豊富なところです。「基本のキ」という本連載のテーマからは外れてしまいますので,次の機会に改めて紹介できればと思っています。本連載が,Ajaxの基本を理解したい皆さんの取っ掛かりとなれば幸いです。

 なお,本連載で紹介したサンプルは,著者サポートサイトの以下のページからオンラインで確認することができます(表1)。お試しください。

表1●オンラインで確認できるサンプル
連載の回 サンプル(リンクをクリックすると該当ページにジャンプします)
第2回 書籍検索(PHP版)
第2回 書籍検索(Ajax版)
第4回 書籍検索(Ajax[POST対応版])
第6回 Yahoo! ウェブ検索
第9回 Yahoo! ウェブ検索(JKL.Hina対応)


*1 JKL.ParseXMLライブラリは同期通信にも対応しています。同期通信を行うには,asyncメソッドを呼び出さずに直接parseメソッドを呼び出します。同期通信によるサーバーサイドからの応答結果はparseメソッドの戻り値として取得できます。

山田祥寛(やまだ よしひろ)

Microsoft MVP for ASP/ASP .NET。執筆コミュニティ「WINGSプロジェクト 」の代表でもある。主な近著に「XMLデータベース入門」「PEAR入門」「Smarty入門」「10日でおぼえる入門教室シリーズ(Jakarta・JSP/サーブレット・PHP・XML)」(以上,翔泳社),「今日からつかえるサンプル集シリーズ(JSP&サーブレット・PHP5・ASP・XML)」(以上,秀和システム),「書き込み式 SQLのドリル」(ソシム),「JSP/PHP/ASPサーバーサイドプログラミング徹底比較」(技術評論社)など。最近では,IT関連技術の取材,講演,監修まで広く手がける毎日。