Ext.grid.EditorGridPanelの使い方
ダウンロードページより、アーカイブ(Ext JS 2.1 SDK)をダウンロードして解凍してください。20080623時点のバージョンは ext-2.1 です。
今日は、ExtJSのEditor Grid Exampleを解説してみたいと思います。
ワタシが作ってみたEditorGridは、上記リンクのサンプルのようにプルダウンやチェックボックスは装備しておりません。EditorGridそのものは非常にシンプルに作った代わりに、編集されたセルを検出するボタンを追加してみました。Gridをフォームとしてどこかへポストしたいといった時に、有効かもしれません。あと、いきなりEditorGridPanelとか言われても・・と言う方にはここにExtJSのチュートリアルを簡単にまとめてみました。
まず、以下に今回解説するEditorGridPanelのソースを全て載せてみましたので、この実装方法とコンフィグを解説します。
動作サンプルとサンプルソース
Ext.onReady( function(){
var id = 0;
var reader = new Ext.data.ArrayReader( { id: 0 }, [
{ name: 'str', mapping: 1 },
{ name: 'num', mapping: 2 }
]);
var store = new Ext.data.Store({
reader: reader,
data:[
[ id++, 'hoge', 1 ],
[ id++, 'moge', 2 ],
[ id++, 'fuga', 3 ]
]
});
var clmnModel = new Ext.grid.ColumnModel([
{ header: "Title", width: 200, sortable: true, dataIndex: 'str', editor: new Ext.form.TextField() },
{ header: "Number", width: 100, sortable: true, dataIndex: 'num', editor: new Ext.form.NumberField() }
]);
var grid = new Ext.grid.EditorGridPanel({
store:store,
colModel:clmnModel,
renderTo:'renderTarget',
title:'simple-editorgrid',
stripeRows:true,
height:200,
width:320,
frame:true,
clicksToEdit:1,
tbar:[
{ text: 'touch', handler:function(){
grid.getStore().each( function( targetObj ){
var touchField = targetObj.getChanges();
for( name in touchField ){
alert(
"index : [ " + targetObj.id + " ]\n" +
"fieldName : [ " + name + " ]\n" +
"value : [ " + touchField[ name ] +" ]\n"
);
}
targetObj.commit();
});
}}]
});
});
【Ext.grid.EditorGridPanelの解説】
それではEditorGridPanelを見ていきたいと思います。普通のGridPanelの使い方はこちらを参照ください。EditorGridPanel
var grid = new Ext.grid.EditorGridPanel({
という箇所がエディターグリッドパネルそのものになります。GridPanelと違うところはコンフィグオプションの
clicksToEdit:1,
という個所と、カラムモデルにeditorというコンフィグオプションを適用しているところだけです。clicksToEditのAPIDocをみると
The number of clicks on a cell required to display the cell's editor (defaults to 2)とありまして、セルが編集可能になるクリック数みたいなことが書いてありますが、なんかあんまり関係ないような気がします。(値がいくつでもダブルクリックで編集可能になった)このコンフィグオプションがなくても編集可能になりました。
で、実際に編集可能にするためにはカラムモデルにeditorという設定をしなければならないようです。
var clmnModel = new Ext.grid.ColumnModel([{
header: "title",
width: 200,
dataIndex: 'str',
editor: new Ext.form.TextField() // <-コレ
},
ここのeditorにformパッケージのクラスでnewしてあげると、編集時にそのクラスで動くようになります。例えばComboBoxでnewしてあげるとプルダウンできるようになります。(適宜ComboBoxのコンフィグは必要になります)これでEditorGridPanelが完成しました。
編集セルの特定
冒頭で記述しましたようにEditorGridの編集個所が特定できないと、どこかのページに値をポストしようにも出来ませんので、この解説をしたいと思います。ポストの前にとりあえず、gridのデータをどこかに渡すためには、- どのレコードの、
- どのフィールドで
- どんな値に
tbar:[
{ text: 'touch', handler:function(){
grid.getStore().each( function( targetObj ){
var touchField = targetObj.getChanges();
for( name in touchField ){
alert(
"index : [ " + targetObj.id + " ]\n" +
"fieldName : [ " + name + " ]\n" +
"value : [ " + touchField[ name ] +" ]\n"
);
}
targetObj.commit();
});
}}]
というわけで、実装の解説を進めていきますが、tbarというコンフィグオプションは前回のTreePanelのときに解説しましたツールバーです。今回はツールバーにtouchというボタンを与えてあげて、そこにハンドラとして編集セルを見るメソッドを用意しました。まず、gridが用意しているgetStore()メソッドを呼び出して、データストアを取得します。次に返ってきたstoreで持っているeachメソッドを使って、レコード単位に全てのオブジェクトを拾いあげます。
grid.getStore().each( function( targetObj ){
パラメータのtargetObjはExt.data.Recordのオブジェクトが入ってきますので、このオブジェクトに変更があったかどうかを聞きます。
var touchField = targetObj.getChanges();getChanges()メソッドはAPIDocに以下のような説明がありました。
Gets a hash of only the fields that have been modified since this Record was created or commited.「レコードが作られたか、あるいは、コミットされた後に編集されたフィールドをハッシュ(オブジェクト)で返すよー」と言っているみたいです。なるほど。便利。編集されてなければ返されたオブジェクトはプロパティを持たないようです。ですので、for~inで調べてみました。これで、編集されたフィールドと値を取得することが出来ます。
ちなみに、targetObjの実態はExt.data.Recordですので、idを持っていて自分がどのレコードかを知っているのですが、今回の実装はストアを作るときに明示的にidを振っています。
var id = 0;
var reader = new Ext.data.ArrayReader( { id: 0 }, [
{ name: 'str', mapping: 1 },
{ name: 'num', mapping: 2 }
]);
var store = new Ext.data.Store({
reader: reader,
data:[
[ id++, 'hoge', 1 ],
[ id++, 'moge', 2 ],
[ id++, 'fuga', 3 ]
]
});
前回作ったGridはSimpleStoreを使って簡単にデータストアを構築しましたが、今回はレコードのidも見たかったのでちょっと構築方法が違います。ArrayReaderのコンストラクタの第1パラメータで、「レコードのidは扱うデータ(配列)の0番目ですよ」と明示的に指定しています。さらに第2引数でレコードのnameと扱うデータ(配列)の何番目かをmappingで指定しています。マッピングをずらすと、grid内にidを表示することも出来ます。idの生成やその一意性は実装依存ですが、自ら生成しなくとも勝手に割り当てられるようです。ただ、一意に割り当ててあげないとバインド出来ませんね。
これでソートしてレコードの位置が変わってもidでバインドできるようになりました。ちなみにレコードが上から何番目か?ってのを知りたい場合は、
grid.getStore().indexOf( targetObj )というstoreのindexOfでそのレコードが上から何番目に位置するのか聞けます。
で、最後にtargetObj.commit();で編集をコミットしてあげています。
というわけで、EditorGridPanelの解説をしてみました。ワタシの理解を多分に含めておりますので、誤った情報である可能性がありますのでご注意ください。