さて、連載Vol.2ですが、今回はFlexのようなDateGridのような「CFGRID」についてお話します。
「CFGRID」はバージョン8以前から存在し、「format」属性を「Flash」にしたFlex 1.5 ベースのDataGridが良く使用されているのではないでしょうか。しかし、ご存知のようにFlex
1.5 は非常に処理が重く、高スペックのサーバーを必要としました。バージョン8からAjaxベースのグリッドが使用できるようになりました。「format」属性は「html」です。Ajaxですのでサーバーのリソースはさほど必要としませんが、ブラウザ側でのグリッドのレンダリングに若干パフォーマンスを必要とします。
あまりこだわりを持たなければ簡単に実装することができますが、「もう少し」凝ったことをしたいという要求が出るとさ〜大変です。CFの長所である"お手軽"はどこかへ消し飛んでしまい、高度なJavaScriptのスキルが必要になります。技術力さえあれば何だってできるのですが、それではCFを利用する意味が薄れてしまいます。仮に高度なスキルでCFGRIDを拡張して実装したとしましょう。この部分に関してはメーカーサポート外になりますし、最悪の場合にはCFのバージョンアップするとその拡張したコードが動かなくなる可能性もあります。もちろん、拡張した部分であってもサポートや機能修正は発生する場合があります。その時は高度なスキルを有した人材が必要になります。プロジェクトの全体的な工数とその"手間"を天秤にかけてうまく見定める必要があるでしょう。
(ただ、メーカーサポートと言っても「本国に問い合わせました」ではお話にならないのですが...)
見た目だけの話をするとCFGRIDは「TABLE」タグです。なので、デザイナーさんに依頼すればCFGRIDより優れた見た目をさくっと作成してくれるのではないでしょうか。では、CFGRIDの良さと言えば何でしょうか?
それは...
・Ajaxで非同期にデータを表示できる
・「データ」と「見た目」を切り離してコーディングできる
・表示だけでなく、編集/削除の機能も付いている
・ページ遷移の機能も付いている
上記以外にちょっと微妙な機能としては
・列(カラム)をドラッグ&ドロップで移動できる
これ、どれくらいニーズがあるのでしょうか?
・ソート機能が付いている
とは言え、実際のデータのソートはサーバーサイドでコーディングする必要があります。
バージョン8で追加されたAjax系機能全般に言えることですが、メーカーでサポートされているJavaScriptやイベントが極端に少ないことです。CFGRIDに関係する関数はわずか3つ。
・ColdFusion.Grid.getGridObject
・ColdFusion.Grid.refresh
・ColdFusion.Grid.sort
どれも今一つの関数です。「getGridObject」で取得できるオブジェクトは「Ext.grid.Grid」、もしくは「Ext.grid.EditableGrid」です。違いは表示だけのグリッドか、編集できるグリッドかです。但し、どちらの場合も「ここから先はご自分でどうぞ」ということになります。つまり、「Ext JS のドキュメントを調べて"自分の責任"で実装してください」ということです。
Ext JS というのはYUI(Yahoo! UI Library)をさらに拡張したJavaScriptのライブラリです。Gridに関して言えば、Ext.grid は YAHOO.util.DataTable に相当するのかもしれません。しかし、微妙にオブジェクトの構造が違い、YUIには存在しない属性も存在します。で、Ext JS のドキュメントで調べざるおえないのですが、APIすべてが網羅されていないようなのです。これには著者も苦労しました。掲載されていないAPIについてどうしたかと言うと、オブジェクトを自作のJavaScriptでダンプしてコツコツ調べたわけです。著者はJavaScriptの達人ではないので非常に時間がかかりました。
まずはこちらをご覧ください。とりあえずデータを表示するだけのサンプルです(図1)。
図1:サンプル1におけるCFGRIDのコード
※クリックすると大きな画像が表示されます
お気づきになったと思いますがCFGRIDを使用する場合は必ず「CFFORM」で囲む必要があります。また、たったこれだけであのUIが実現できるのもすばらしいと思います。サーバーサイドのCFCのコードはと言いますと、図2をご覧ください。
図2:サンプル1用のCFCの一部
※クリックすると大きな画像が表示されます
やっていることは単純に
Step1.クエリーオブジェクトを生成
Step2.引数に応じた順序を設定
Step3.「QueryConvertForGrid」関数でクエリーオブジェクトをAjax用データに変換
という作業です。ここで注意点として、サンプルでは必ず全データ(1,000件)を毎回メモリに展開していることです。実際のシステム開発などではこのようなことはしてはいけません。データベースから必要な1ページのデータ分を取得するべきでしょう。つまり、UI側にページ制御のボタンが用意されていますが、結局データの取得に関しては自分でパフォーマンスを考慮して実装する必要があるということになります。
まずはこちらをご覧ください。データの編集/削除ができるサンプルです(図3)。
図3:サンプル2におけるCFGRIDのコード
※クリックすると大きな画像が表示されます
前述の図1と違うのは4箇所。
・「selectmode」が「edit」
CFGRIDに表示されているデータを編集できるようになります。
・「delete」が「true」
CFGRIDに表示されているデータを削除できるようになります。
そのボタンは下部のページ制御がある部分にあります。
・「deletebutton」が「Remove」
前述の削除機能用ボタンのラベルを指定できます。
・「onChange」の記述がある
編集/削除が発生した場合に実行するサーバーサイドのURL/CFC、又はJavaScriptを指定できます。
注意点があります。「onChange」で指定されたサーバーサイドのロジックにエラーが発生してデータベースのデータを更新できなかった場合でも、クライアントサイドのデータは編集された状態になり、左上に赤い三角印が表示されます。この場合、もちろんリロードやページ遷移などをするとクライアント側の表示はサーバーサイドから取得したデータに反映されます。この仕様、いかがなものなのでしょうか?
システム開発では「無し」だと思います。現実的(?)な方法としてパッと思いつくのは「onChange」でいきなりサーバーサイドを呼び出すのではなく、JavaScript関数を起動(onChange="JavaScript:hoge")し、「cfajaxproxy」を使用して自前でサーバーに問い合わせる方法です。ちょっと、手間ですがこうすることでユーザーにエラー(データが更新されなかった)ことを通知できるので安全だと思います。
もし、社内にJavaScriptの達人がいるならCFGRIDを使わずともExt JS の最新のバージョン(2.0)を実装するほうが良いかもしれません。もし、社内にFlex2での開発経験がある人がいるならFlex2のDataGridを使用することをお勧めします。もし、どちらの場合でも無い場合はとりあえずCFGRIDで簡単にできることで我慢したほうが良さそうです。著者の個人的な意見ですとデバッグのし易さや軽さを考慮するとCFGRIDよりはFlex2のDataGrid+FlashRemoting
の方が良いと思います。
以上で【FlexのDataGridのような「CFGRID」】は終了です。