DOMプログラミングを使って、コンボボックスから取得したソートキーで動的にリストのソートを行うテクニックを紹介します。ソート自体の処理はXSLTの機能を使います。DOM+XSLT+JavaScriptの処理となります。
XMLフォーマットを採用する理由の1つに、データとレイアウトが分離しているので「データの多角的な利用が容易である」という点が挙げられます。
例えば、本稿で取り上げるデータのソートが代表的な例です。従来、HTMLでソート機能を実現するには、面倒なDynamic HTMLの記述を必要としました。しかし、XSLTはデフォルトでソート機能を持っています。DOMから動的にソートキーの部分だけ入れ替えてやることで、ダイナミックなソーティングをクライアント上で実現できます。
本稿では、別稿「よく使う属性値をまとめて定義する」で使用したarticle.xslを改良して、「公開日」「タイトル」「ステータス」でソートキーを自由に切り替えられるようにしてみます。画面上部のコンボボックスからソートキーを変更すると、変更されたキーに基づいてリストの並び(昇順)がダイナミックに切り替わります。なお、元となるXML文書は「よく使う属性値をまとめて定義する」で使用したarticle.xmlをそのまま使用するものとします。
[article.xsl]
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:attribute-set name="img_size">
<xsl:attribute name="width">40</xsl:attribute>
<xsl:attribute name="height">60</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="img" />
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="title" />
</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<html>
<head>
<title>@IT公開記事一覧</title>
<script language="JavaScript">
<![CDATA[
var objXml=document.XMLDocument;
var objXsl=document.XSLDocument;
var nodSrt=objXsl.selectSingleNode("//xsl:sort");
function sort(key){
nodSrt.setAttribute("select",key);
sortList.innerHTML=
objXml.documentElement.transformNode(objXsl);
}
]]>
</script>
</head>
<body>
<h1>@IT公開記事一覧</h1>
<hr />
<form>
<select name="srt" onchange="sort(this.value)">
<option value="begin">公開日</option>
<option value="title">タイトル</option>
<option value="status">ステータス</option>
</select>
</form>
<div id="sortList">
<xsl:apply-templates select="articles" />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="articles">
<xsl:for-each select="article">
<xsl:sort select="begin"
data-type="text" order="ascending" />
<table border="0">
<tr>
<td valign="top">
<img xsl:use-attribute-sets="img_size" />
</td>
<td valign="top">
<div style="font-weight:bold;">
<xsl:element
name="a">
<xsl:attribute
name="href">
<xsl:value-of
select="url" /></xsl:attribute>
<xsl:value-of
select="title" />
</xsl:element>
</div>
(<xsl:value-of
select="begin" />開始)
...<xsl:value-of
select="status" />...
</td>
</tr>
</table>
<hr />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet> |
図 コンボボックスの指定に従って、ソート順が切り替わる
ポイントとなるのは、JavaScriptで記述された以下の部分です。
var objXml=document.XMLDocument;
var objXsl=document.XSLDocument;
var nodSrt=objXsl.selectSingleNode("//xsl:sort");
function sort(key){
nodSrt.setAttribute("select",key);
sortList.innerHTML=
objXml.documentElement.transformNode(objXsl);
} |
XMLDocument、XSLDocumentメソッドは、それぞれ現在の表示ドキュメントで使用されているXML文書とXSLTスタイルシートをDOMDocumentオブジェクトとして返します。ここで取得したDOMDocumentオブジェクトを介して、XML文書、XSLTスタイルシートへのアクセスが可能となります。JavaScriptでXML、XSLTを操作する場合の定石的な手段でもありますので、覚えておくとよいでしょう。
DOMDocument.selectSingleNodeメソッドは、引数として与えられたXPath式に合致する最初のノードを返します。この場合、XSLTスタイルシートarticle.xsl内の<xsl:sort>要素を抽出します。
<xsl:sort>要素を取得してしまえば、あとはsetAttributeメソッドでselect属性にソートキーをセットするだけです。変数keyには、コンボボックスの内容が変更されたタイミング(onchangeイベント)で、オプション値がセットされます。
編集が完了したXSLTスタイルシートをXML文書に再適用するのは、transformNodeメソッドの役割です。transformNodeメソッドの戻り値として返された結果文字列を、innerHTMLプロパティで<div id="sortList">要素の個所に埋め込めば完了です。
なお、本サンプルではソートキーのみを動的に変更していますが、もちろん、order(昇順/降順)、data-type(データ型)を操作する場合もまったく同じ要領で可能です。コードはやや冗長になりますが、余力のある方は挑戦してみるとよいでしょう。