さまざまな技術が互いにつながりを持っていることはよくあります。そのため、ある技術での知識が別の技術を習得する上で役立つこともよくあります。この記事では Dojo Grid の主な機能を MVC (Model-View-Controller) デザイン・パターンの観点から紹介します。MVC の観点から Dojo Grid を捉えることで、これまで使用したことがなくても、簡単に Dojo Grid を理解してマスターできることを知ってください。

Luo Ling (luol@cn.ibm.com), Software Engineer, IBM  

Photo of Luo LingLuo Ling は Dojo 開発とアクセシビリティー技術のエキスパートです。



Jin Pan, Staff Software Engineer, IBM  

2006年から IBM China Development Lab に勤務している Jin Pan は、これまでいくつもの J2EE プロジェクトに参加するとともに、プロジェクトを先導してきました。彼女は、Dojo や Web 2.0 などの新しい Web 技術に興味を持っています。Fudan University でコンピューター・サイエンスの理学士号、理学修士号を取得したのは、それぞれ 2003年、2006年です。



Qiangguo Tong, Staff Software Engineer, IBM

Qiang Guo Tong は、Web 開発で 5 年以上の経験を持つスタッフ・ソフトウェア・エンジニアです。彼は、IBM で使用されている複数の国際化対応ツールの技術リーダーを務めています。



Dan Wang,

Photo of Dan WangDan Wang は 2006年から IBM China Development Lab に勤務しており、これまで複数の J2EE プロジェクトに参加してきました。彼が興味を持つ分野は、Dojo や Web 2.0 などの新しい Web 技術です。



2009年 11月 03日

はじめに

Dojo は、リッチ・クライアント Web アプリケーションを素早く作成できるようにするための、移植可能なオープンソースの JavaScript ツールキットです。Dojo には応答性に優れたアプリケーションを作成するためのユーティリティーが豊富に揃っているだけでなく、Dojo をすぐに使い始められるように事前にパッケージ化された一連のウィジェットも用意されています。しかし Dojo には、各ウィジェットの使用方法を詳しく説明しているドキュメントが用意されていません。その一例が Dojo Grid です。Dojo Grid は Web ページに表示することのできる、小さなスプレッドシートのようなウィジェットです。この記事では Dojo Grid の主な機能を、MVC (Model-View-Controller) デザイン・パターンの観点から紹介します。MVC の観点から Dojo Grid を捉えることで、これまで使用したことがないとしても、簡単に Dojo Grid を理解してマスターすることができます。

MVC はソフトウェア・エンジニアリングで使用されているアーキテクチャー・パターンです。MVC デザイン・パターンを上手く使用することで、ビジネス・ロジックをユーザー・インターフェースから切り離し、ビジネス・ロジックとユーザー・インターフェースのそれぞれを、互いに影響を与えることなく自由に変更できるようになります。MVC デザイン・パターンでは、コントローラーがユーザー・インターフェースからの入力イベントを処理し、裏でモデルの変更をトリガーします。そしてモデルがアプリケーション・データを操作し、ビューがモデルを使用して結果をユーザーに表示します。このパターンは、Microsoft® MFC、Java™ Swing、Java Enterprise Edition をはじめ、多くのフレームワークで使用されているものです。以降のセクションでは、この MVC に従って分類した Dojo Grid の機能を紹介します。


モデル

加工されていないそのままのデータと UI 用に見やすく加工された表示用のデータとを区別するため、Dojo Grid では加工されていないすべてのデータを保管するデータ・モデルを維持します。グリッドが操作するのは、このデータ・モデルに保管されたデータです。例えば、日付/時刻タイプのデータは通常、人間が読みやすいように「2009-7-22」のようなフォーマットで保管されるのではなく、ミリ秒数として保管されます。このようなデータのほうが、構成するにも、別の種類のデータ・オブジェクトに変換するにも容易に扱うことができます。

すべての MVC ウィジェットと同様、グリッドにも固有のデータ・モデルがあります。それが、データ・ストアです。Dojo では、データ・ストアを認識するほとんどすべてのウィジェットが関数を使用して ItemFileReadStoreItemFileWriteStore などの共通データ・ストアにアクセスできるため、それぞれのデータに固有の新しい API を学ぶ必要はありません。

ItemFileReadStore は、JSON データの特定フォーマットを読み取るために使用するデータ・ストアです。DojoX プロジェクトではこの他にも、XmlStoreCsvStoreOpmlStore などのストアを提供しています。これらのストアはそれぞれ、XML、CSV、OPML フォーマットでデータを出力可能なサーバーと連動するために使用されます。

Dojo Grid やその他多くの MVC ウィジェットでは、データ・ストア内のすべてのデータは項目あるいは項目の属性として操作されるのが通常です。そのため、データには標準的な方法でアクセスすることも、複数のウィジェットで同時に使用することもできます。リスト 1 に、この記事で使用するデータ・ストア構造の一例を記載します。

リスト 1. 単純なデータ・ストア構造の例
{
    identifier: 'id',
    label:'name',
    items: [
{id:0, name: 'Alex', manager: true, sex: 'Male', age:30, date: 1097990400000, 
annualLeaveTotal: 15, annualLeaveTaken:2},
{id:1, name: 'Jack', manager: false, sex: 'Male', age:26, date: 1184995200000,
annualLeaveTotal: 10, annualLeaveTaken:3},
{id:2, name: 'Rose', manager: true, sex: 'Female', age:40, date: 894604800000, 
annualLeaveTotal: 20, annualLeaveTaken:4},
{id:3, name: 'Wang', manager: true, sex: 'Male', age:44, date: 836630400000, 
annualLeaveTotal: 20, annualLeaveTaken:5},
…..
}

この例の内容は以下のとおりです。

  • 各項目には 8 つの属性があります。
  • id 属性は、一意でなければならない識別子です。

データ・ストアを作成するには、マークアップ・タグとして宣言する方法、またはプログラムによって作成する方法の 2 つがあります。

マークアップ・タグによるデータ・ストアの作成

マークアップ・タグを使用してデータ・ストアを作成するには、まず、すべてのデータを編成して保管する JSON ファイルが必要です (リスト 2 を参照)。この記事では、data.json という名前のファイルを使用します。JSON ファイルが用意できたら、リスト 2 のマークアップを HTML ファイルに書き込みます。

リスト 2. HTML でのデータ・ストアの宣言
<span dojoType="dojo.data.ItemFileWriteStore" jsId="myStore"
      url="data.json"></span>

次に、このデータ・ストアをグリッドに指定します (リスト 3 を参照)。

リスト 3. グリッド・データ・ストアの指定
<table id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" store="myStore"
 rowSelector="10px">
	<thead>
  		 ...
	<thead>
<table>

これで、Dojo が HTML コードを構文解析してこのグリッドを作成すると、Dojo ストア・オブジェクトが作成され、このオブジェクトによって data.json ファイルからデータが取得されて、グリッド・ストアが「myStore」に設定されることになります。作成されるグリッドの一例を図 1 に示します。

図 1. 作成後の単純なグリッド
従業員に関する情報の表を表示するデータ・グリッド。スプレッドシートのように、各従業員のデータが複数の行にわたって一覧にされています。

マークアップ・タグを使用してグリッド・ストアを作成する方法は、非常にわかりやすく、使用するのも簡単です。けれどもデータがサーバーから提供され、動的に編成される場合は、プログラムによってグリッドとそのストアを作成する必要があります。

プログラムによるデータ・ストアの作成

グリッドのストアをサーバー・サイドのレスポンスと連動して動的に作成し、変更するには、以下のようにしなければなりません。

  • JavaScript を使用して受信データをプログラムによって再編成し、Dojo が扱いやすいデータにします。
  • Dojo ストアを作成します。
  • Dojo ストアがグリッドになるように設定します。

リスト 4 のコードは、データ・ストアとしてのフォーマットを設定した JSON オブジェクトを作成します。

リスト 4. データの再編成
generateStoreData: function(/*JSON array*/itemList){
var data = {};
var items = [];
for (var i = 0; i < itemList.length; i++) {
	var item = {};
	item["id"]     = itemList[i].id;
	item["name"]   = itemList[i].name;
	item["manger"] = itemList[i].isManger;
	item["sex"]    = itemList[i].sex;
	item["age"]    = itemList[i].age;
	item["date"]   = itemList[i].date;
	item["annualLeaveTotal"] = itemList[i].altotal;
	item["annualLeaveTaken"] = itemList[i].altaken;
	items.push(item);
       }
data["identifier"] = "id";
data["label"] = "name";
data["items"] = items;
return data;    
}

続いてストアを作成し、そのストアがグリッドになるように設定します。

リスト 5. グリッド・ストアの作成および設定
   dijit.byId("grid").store = new dojo.data.ItemFileReadStore({
                  data: this.generateStoreData(itemList)
     });

以上のステップが完了すると、図 1 に示したグリッドと同じグリッドが完成します。

データ・ストアに対するクエリーの実行

通常、Dojo Grid はデータ・ソース全体をデータ・モデルに保管しますが、データのサイズが大きくなってくると、この保管方法ではパフォーマンスに問題が出てきます。実際、Dojo Grid ストア内の項目が一定の数を超え、それぞれの項目に多数の属性がある場合、ソートや検索、レンダリングなどのグリッド操作のパフォーマンスが著しく低下します。

ただし、パフォーマンスを向上させる方法はあります。例えば、サーバーがブラウザーに送信できるデータを制限し、それらのデータをグリッド・データ・ストアのなかで構成するためのコードを作成するという方法です。あるいは、DojoX プロジェクトが提供する QueryReadStore をそのまま使用するか、または拡張して、サーバーから動的にデータをロードするという方法もあります。この方法を使用すれば、サーバー上の巨大なデータ・ストアから、データをチャンクで取得することができます。

リスト 6. ストアに対してクエリーを使用することによる大量のデータの処理
<div dojoType="dojox.data.QueryReadStore" jsId="store" url="../someServlet"
 requestMethod="post"></div>
	
<div dojoType="dojox.grid.data.DojoData" jsId="model" store="store"
 sortFields="[{attribute: 'name', descending: true}]" rowsPerPage="30"> </div>
		
<div id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" model="model" structure="layout"
 rowSelector="10px"><div>

DojoX プロジェクトでは、他にもさまざまな用途に応じた多数のデータ・ストアを用意しています。表 1 に、現在 Dojo で使用できるストアとその用途を記載します。

表 1. Dojo で使用可能なストア
Dojo ストア用途
dojo.data.ItemFileReadStoreJSON データの読み取り専用ストア
dojo.data.ItemFileWriteStoreJSON データの読み取り/書き込み用ストア
dojox.data.CsvStoreCSV (Comma-Separated Variable) フォーマット・データの読み取り専用ストア
dojox.data.OpmlStoreOPML (Outline Processor Markup Language) の読み取り専用ストア
dojox.data.HtmlTableStoreHTML フォーマットの表に保持されるデータの読み取り専用ストア
dojox.data.XmlStore基本的な XML データの読み取り/書き込み用ストア
dojox.data.FlickrStoreflickr.com に対するクエリー用の読み取り用ストア。Web サービス用データ・ストアの好例です。
dojox.data.FlickrRestStoreflickr.com に対するクエリー用の読み取り用ストア。Web サービス用データ・ストアの好例で、FlickrStore が進化したバージョンです。
dojox.data.QueryReadStoreJSON データの読み取り専用ストア。ItemFileReadStore と同様ですが、リクエストのたびにサーバーに対してクエリーを実行します。
dojox.data.AtomReadStoreAtom XML 文書の読み取り用ストア

Dojo データ・ストアのカスタマイズ

Dojo.data API によって、カスタマイズしたデータ・ストアを作成することもできます。この場合に必要なのは、データ・アクセスを複数のパーツに分割すること、そしてデータ・ストアが適切な API を使用して各パーツを実装することです。

  • dojo.data.api.Read は、データ項目やその属性を読み取るための機能です。この API には、データ項目の検索、ソート、フィルタリングの機能も備わっています。
  • dojo.data.api.Write は、データ項目やその属性を作成、削除、および更新するための機能です。すべてのバックエンド・サービスがデータ項目を変更できるわけではありません。実際、Flikr や Delicious、そして Google マップなどのほとんどの公開サービスは、主として読み取りベースのデータ・プロバイダーです。
  • dojo.data.api.Identity は、項目に一意の識別子が設定されている場合、その識別子を基準に項目を検索、参照するための機能です。ただし、すべてのデータ・フォーマットに、データ項目の参照に使用できる一意の識別子があるわけではありません。
  • dojo.data.api.Notification は、ストア内で発生したデータ項目の変更イベントをリスナーに通知するための機能です。項目の基本的な変更イベントは、作成、削除、更新です。これらのイベントは、特にデータ・ストアがデータを最新の状態に更新するために、定期的にバックエンドのサービスをポーリングする場合に役立ちます。

ビュー

MVC デザイン・パターンでのビューは、モデルからアプリケーション・データを取得してユーザーに表示するという役割を持ちます。ユーザーへの表示は、グリッドに用意された多数の関数を使って簡単に変更することができます。以降のセクションでは典型的なビューの使用方法を紹介し、ビューの観点から、グリッドに備わっている強力な機能について説明します。

マークアップ・タグによるグリッドのレイアウト定義

大まかに分類すると、グリッドを定義する方法としては、HTML マークアップを使用した宣言型の方法や、JavaScript でのプログラムによる方法を使用することができます。リスト 7 にマークアップ・タグを使用した上位レベルの構造定義を記載し、この定義によって生成される表示を図 2 に示します。

リスト 7. マークアップでレイアウトを定義する JavaScript コード
<table id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" store="myStore" 
     rowSelector="10px">
<thead>
	<tr>                				
		<th field="id" width="10px">ID</th>
		<th field="name">Name</th>
		<th field="manager" with="50px">Is manager</th>	
		<th field="sex" width="50px">Sex</th>
		<th field="age" width="50px">Age</th>
		<th field="date" width="100px">On Board date</th>
	</tr>
	<tr>
		<th field="annualLeaveTotal" colspan="3">
                        		Total annual leave days
               	</th>
		<th field="annualLeaveTaken" colspan="3">
			Annual leave days already taken 
	             </th>
	</tr>
</thead>
</table>
図 2. マークアップによってレイアウトが定義されたグリッド
先頭行に並ぶラベルの下に、さまざまな従業員のデータが表示されたスプレッドシート・スタイルのグリッド

プログラムによるグリッドのレイアウト定義

表の構造は、プログラムによって設定することもできます。セル構造を定義するオブジェクトを指定できるのは、structure という属性です。

リスト 8. プログラムによってレイアウトを定義する JavaScript コード
var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
	 name: 'Is manager',
	 field:'manager',
	width:'100px'
	}, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            },{
                name: 'On Board date',
                field: 'date',
                width: '100px'
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
               	field: 'annualLeaveTaken',
                width: '100px'
	}];

var grid = new dojox.grid.DataGrid({
            id: 'grid',
            store: myStore,
            structure: layout
        }, dojo.byId('grid'));

横スクロールに対する列のロック

一部の列だけを横にスクロールできないようにロックし、他の列は引き続きスクロールできるようにすることも可能です。それには 2 つの構造を使用し、一方の構造で noscroll 属性を true に設定します。

例えばリスト 9 で宣言する 2 つの構造のうち、一方の構造では ID 列と Name 列に対して noscroll 属性を true に設定します。このように設定した上で、配列を使用して 2 つの構造を結合し、1 つのレイアウト構造にします。

リスト 9. ID 列と Name 列をロックする JavaScript コード
var fixlayout = {
                noscroll: true,
                cells: [{
                    name: 'ID',
                    field: 'id',
                    width: '10px'
		             
                }, {
                    name: 'Name',
                    field: 'name',
                    width: '50px'
                }]
            };

var mainlayout = {
                onBeforeRow: beforerow,
                onAfterRow: afterrow,
                cells: [{
                    name: 'Is manager',
                    field: 'manager',
                    width: '200px'
                }, {
                    name: 'Sex',
                    field: 'sex',
                    width: '50px'
                }, {
                    name: 'Age',
                    field: 'age',
                    width: '50px'
                }, {
                    name: 'On Board date',
                    field: 'date',
                    width: '100px',
                }, {
                    name: 'Total annual leave days',
                    field: 'annualLeaveTotal',
                    width: '100px'
                }, {
                    name: 'Annual leave days already taken',
                    field: 'annualLeaveTaken',
                    width: '100px'
                }]
            };

var layout = [fixlayout, mainlayout];

図 3 では、ID 列と Name 列はロックされていますが、その他の列は横にスクロールすることができます。

図 3. 一部の列が固定されたグリッド
図 2 と同じデータを使用したグリッドですが、横スクロール・バーは ID 列および Name 列の右側にある列しかスクロールしないようになっています。

複数の行が含まれる行

グリッドでは、1 つの論理行に、複数のデータ行を含めることができます。その場合に使用するのは colSpan 属性です。この属性をレイアウト定義に追加します (リスト 10 を参照)。

リスト 10. 複数の行が含まれる行を定義する JavaScript コード
var layout = [[{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
	  name: 'Is manager',
	  field:'manager',
	  width:'100px'
 }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            },{
                name: 'On Board date',
                field: 'date',
                width: '100px'
            }], [ {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                colSpan: '2'
            }, {
                name: 'Annual leave days already taken',
               	field: 'annualLeaveTaken',
                colSpan: '2'
            }]];

Total annual leave days (年間有給休暇数) と Annual leave days already taken (有給休暇取得数) という 2 つの列は、他の列と同じ論理行に含まれています。

図 4. 複数の行からなるグリッド
同じグリッドですが、Total annual leave days (年間有給休暇数) は ID と Name という 2 つの列の下にまたがっており、Annual leave days already taken (有給休暇取得数) は Is manager と Sex という 2 つの列の下にまたがっています。

グリッドのデータのフォーマット設定

グリッドのフォーマット設定機能を使用して、データ・ストア内のデータの表示を変更することができます。これは MVC の中核的な概念の 1 つであり、この機能では日付などのデータをユーザーのロケールに合わせたフォーマットに設定したり、さらにはチェック・ボックスなどの HTML コンポーネントを作成したりすることもできます。リスト 11 に一例を示します。

リスト 11. グリッドのデータをフォーマット設定する JavaScript コード
var dateFormatter = function(data, rowIndex){
                return dojo.date.locale.format(new Date(data), {
                    datePattern: "dd MMM yyyy",
                    selector: "date",
                    locale: "en"
                });
            };

var managerFormatter = function(data, rowIndex){
                if (data) {
                    return "<input type='checkbox' checked />";
                }
                else {
                    return "<input type='checkbox'  />";
                    
                }
            };

var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
                name: 'Is manager',
                field: 'manager',
                formatter: managerFormatter,
                width: '100px'
            }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            }, {
                name: 'On Board date',
                field: 'date',
                width: '100px',
                formatter: dateFormatter
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
                field: 'annualLeaveTaken',
                width: '100px'
            }];
図 5. グリッドのデータのフォーマット設定
同じグリッドですが、「On Board Date」は DD-MMM-YYYY のフォーマットに設定されていて、「Is manager」には true/false ではなくチェック・ボックスが表示されています。

get interface の使用

get interface を使用すると、データ・ストア外部に追加の列を定義し、その値を動的に取得することができます。上記の例には Total annual leave days (年間有給休暇数) と Annual leave days already taken (有給休暇取得数) という 2 つの列があります。例えば、有給休暇 (annual leave days) があと何日残っているのかを知りたい場合、この 2 つの列を基に日数を計算し、get interface を使用すれば、有給休暇の残数を動的に取得することができます。

リスト 12 で、Annual leave days left (有給休暇残数) という名前の新しい列を追加します。この列の値は、Total annual leave days (年間有給休暇数) の値から Annual leave days already taken (有給休暇取得数) の値を引くことによって計算します。

リスト 12. get interface を使用した JavaScript コード
function getLeftDays(rowIndex, item){
                if (item != null) {
                    return item.annualLeaveTotal - item.annualLeaveTaken;
                }
            }


var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
                name: 'Is manager',
                field: 'manager',
                formatter: managerFormatter,
                width: '100px'
            }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            }, {
                name: 'On Board date',
                field: 'date',
                width: '100px',
                formatter: dateFormatter
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
                field: 'annualLeaveTaken',
                width: '100px'
            }, {
                name: 'Annual leave days left',
                get: getLeftDays,
                width: '100px'
            }];
図 6. get interface の使用
Annual leave days left (有給休暇残数) 列が新しく追加されたグリッド。この列には、Total annual leave days (年間有給休暇数) から Annual leave days already taken (有給休暇取得数) を引いた計算値が表示されています。

コントローラー

MVC デザイン・パターンでは、コントローラーがイベント (通常はユーザー・アクション) を処理して応答し、モデルでの変更を間接的に呼び出すこともできます。Dojo Grid でのコントローラーは非常に強力で、例えばイベントの処理方法、データのソート方法、データのフィルタリング方法などのグリッドの振る舞いをカスタマイズする手法をさまざまに用意しています。

以降のセクションでは、Dojo Grid でコントローラーを使用し、カスタマイズする方法を説明します。

イベント処理

Dojo Grid に備わっている強力なイベント処理メカニズムは、各種の Grid 要素とイベント・タイプに応じたイベント呼び出しインターフェースを提供しています。このインターフェースは、例えば行またはセルでの click イベントに応答することも、mouseover イベントに応答することもできます。そのため、これらのイベント処理をカスタマイズして特定のタスクを実行するには極めて重宝します。

イベント処理の例として、onCellClick を用いて独自のハンドラーを Dojo Grid に追加する方法を説明します。ここではこのメソッドを、セルの値、列および行のインデックスを表示するという目的でカスタマイズします (リスト 13 を参照)。

リスト 13. Grid の onCellClick イベント・ハンドラーをカスタマイズする Javascript コード
<script>
var showDetail = function(e){
                               var value = e.cellNode.firstChild.data;
     alert('value:' + value + " column:" + e.cellIndex + " row:" + e.rowIndex);
            }
            
            dojo.addOnLoad(function(){
                              dojo.connect(grid, "onCellClick", showDetail);
}
</script>

上記のコードでは、まずセルの詳細情報 (値、列インデックス、行インデックス) を表示するイベント・ハンドラー、showDetail を定義しています。次に dojo.connect を使用して、カスタマイズしたハンドラーを onCellClick イベントに接続します。この接続は dojo.addOnLoad でも行わなければなりません。このメソッドを実行することによって、すべての Dojo ウィジェットが初期化を完了し、使用できる状態になっていることを確実にするためです。

以上のカスタマイズにより、ユーザーがグリッドのセルをクリックすると、アプリケーションがアラート・ウィンドウを表示するようになります。図 7 に結果を示します。

図 7. カスタマイズ後の Grid のイベント・ハンドラー
カスタマイズの結果、バックグラウンドに表示されたグリッドの上に、「value:40 column:4 row:2」と表示するダイアログ・ボックスが重ねて表示されています。

ソートのカスタマイズ

Dojo Grid には、列のデータ型を基準とした基本的なソート機能が提供されています。例えば、サンプル・アプリケーションの ID 列は番号順にソートされ、名前の列はアルファベット順にソートされるといった具合です。

Dojo Grid のソート機能も同じくカスタマイズすることが可能で、カスタマイズした振る舞いを定義することも、特定の列をユーザーがソートできないようにすることもできます。ユーザーが特定の列をソートできないようにするには、Dojo Grid の canSort 属性を使用して、ソート可能な列を指定します。

リスト 14 に、ID 列のソート機能を無効にする JavaScript コードを記載します。

リスト 14. ソート可能な列を指定する Javascript コード
<script> 
            dojo.addOnLoad(function(){
            		grid.canSort = function(index) {  
			if(index == 1) return false;
			return true;
		};
	}
</script>

index パラメーターは、1 から始まるグリッドの列インデックスです。canSort 関数が false を返した場合、列のソート機能は無効になります。

ソート可能な列を指定できるだけでなく、列のソート方法を指定することもできます。ここではサンプル・アプリケーションの Name 列を例に説明します。まず、図 8 に Dojo Grid のデフォルトによるソートの振る舞いを示します。

図 8. Dojo Grid のデフォルトによるソートの振る舞い
同じグリッドですが、Name 列を基準に ASCII の降順でソートされています。ヘッダーに表示されている三角形をクリックすると、ソート順を変更することができます。

Name 列は降順でソートされています。最後の 3 行が、Victor、Wang、vicky の順になっていることに注目してください。グリッドでのソートはデフォルトで大文字と小文字を区別し、ASCII コード順でソートを行います。そのため、小文字は大文字の後に配置されるというわけです。けれどもこの振る舞いは、ソフトウェア国際化対応の標準には準拠していません。そのためこの例の場合には、国際化に対応したソートをサポートするようにソート機能をカスタマイズする必要があります。

リスト 15 の JavaScript コードを見ると、Dojo Grid のソート機能をカスタマイズする方法がわかります。

リスト 15. Dojo Grid のソート機能のカスタマイズ
<script>
            dojo.addOnLoad(function(){
            		myStore.comparatorMap = {};
		myStore.comparatorMap["name"] = function (a, b) {  
			return a.localeCompare(b);
		}
	}
</script>

データ・ストア・オブジェクトにはソートの振る舞いを変更できるように comparatorMap というフィールドがあります。上記のカスタマイズの例では、Name 列に比較メソッドを定義し、localeCompare を使って国際化に対応したソートをサポートしています。図 9 に、ソートをカスタマイズした後の結果を示します。

図 9. カスタマイズ後の Dojo Grid のソート振る舞い
このグリッドには図 8 と同じ従業員情報が表示されていますが、Name 列は名前の大文字小文字を無視したアルファベットの降順でソートされています。

フィルター

Dojo Grid には、クライアント・サイドでデータをフィルタリングする非常に便利な方法が用意されています。フィルタリング条件は、1 つの列に対して定義することができます。リスト 16 に、グリッドをフィルタリングして A の文字で始まる名前だけを表示する方法を示します。

リスト 16. Name 列でのフィルタリング
<div dojoType="dijit.form.Button">filter name
	<script type="dojo/method" event="onClick" args="evt">
	// Filter the name from the data store:
		grid.filter({name: "A*"});
	</script>
</div>

filter name ボタンをクリックすると、図 10 に示すようなフィルタリングされた結果が表示されます。

図 10. フィルタリング後のグリッド
同じデータセットを表示するグリッドですが、下部に filter name というボタンがあり、グリッドに表示されているのは Alex と Alio という 2 つの名前の行のみです。

まとめ

この記事では、MVC デザイン・パターンに沿って Dojo Grid の機能を説明しました。一般に、1 つの機能を実装するにはさまざまな方法を使えます。例えばグリッドで日付を表示するには、データ・ストア内の日付を表すストリングを使用することも、long 型を宣言して、最終的な表示に適した正しいフォーマットを設定することもできます。最初は前者の選択肢のほうが簡単なように思えますが、グリッドが国際化に対応しなければならない場合には、後者のほうが適切です。Dojo Grid プロジェクトにはぜひ、MVC デザイン・パターンを使用してみてください。それによって、新しいレベルのコードの堅牢性と再利用性がもたらされるはずです。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=449877
ArticleTitle=MVC デザイン・パターンを使用した Dojo Grid
publish-date=11032009