HOME > ブログ > ExtJS入門その13『Ext.grid.GridPanel』

ExtJS入門その13『Ext.grid.GridPanel』

前回前々回において「Ext.data.Store」でデータを取得してExtJS内で使用できるところまで、を見てきました。
で、自然な流れとして次は表示となるわけですが、表示手法のひとつとして人気の高いUIグリッドパネルを見ていきましょう。

IBMでExt JS 入門者の最初の壁という記事があるぐらいですから難しいのは確かでしょう。
なのでまたいつものごとく泥臭くひとつずつ確認していきたいと思います。


データ(ストア)は取得し変数MyDataStoreに格納されload()されているものとします。
データとしては前回前々回で使ったものと同じデータです。

グリッド表示は「Ext.grid.GridPanel」を使います。
必須コンフィグオプションは「store」と「colModel」ですのでとりあえず最低ラインから色々付け足したり、置き換えたりしていってみましょう。

[デモ]
var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: new Ext.grid.ColumnModel([
		{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	])
});
さくっと表示されました。最初は出た時はほんと感動しますよねーこれ。
「colModel:」は省略形のエイリアスである「cm:」という表記でもOKです。

「colModel: 」を変数においてみます。
var MyGridcolModel = new Ext.grid.ColumnModel([
	{
		header: '名前',
		width: 100,
		dataIndex: 'name'
	},{
		header: '性別',
		width: 50,
		dataIndex: 'gender'
	},{
		header: '電話番号',
		width: 120,
		dataIndex: 'tel'
	},{
		header: 'メール',
		width: 150,
		dataIndex: 'mail'
	},{
		header: '備考',
		width: 250,
		dataIndex: 'info'
	}
]);

var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: MyGridcolModel
});
当然表示されます。ですがぶっちゃけ表示されるだけでは何の役にも立ちません。色々できて初めて価値が出てきます。
おっと焦ってはいけませんね。ひとつずつひとつずつ、です。

確認しておきますが、このほとんどデフォルトの状態で何ができるあるいはグリッドはどんな状態になっているでしょうか。ちょっと羅列しておきます。
・データセル行上にマウスオーバーすると背景が薄グレーになる
・データセル行をクリックすると何も起こらないが背景が薄水色になり、同じ行をCtrlを押しながらクリックすると元に戻る
・データセル行をCtrlを押しながらクリックしていくと複数選択でき背景が薄水色になる。Shiftを使うと複数選択が一気にできる
・ヘッダー部分にマウスオーバーすると背景が薄水色になり、右端に▼ボタンが出る
・その▼ボタンをおすと昇順、降順(この時点では反転して選択できない)、カラム(項目の表示・非表示チェックボックス)
 といった機能がさわれる
・全てのカラムが表示・非表示できるが、最後のひとつは非表示にできない、すなわち全ての表示を消すことはできない
・ヘッダー部分をクリックしてもなにもおきない。
・ヘッダー部分をクリックしてドラッグすると位置を変更することができる
・ヘッダー部分の項目の間にマウスを置くと「←→」がでてカラムの幅を変更することができる
など。
デスクトップアプリケーションとほぼ同じ挙動をすることが確認できると思います。
さっきは何の役にもたたないと言いましたが、javascriptでこの機能が実装されていることを考えるとやっぱりすごいですね。

で、なんでこんなことを確認したのかというと、恐らくここで確認できたことはほとんどすべてカスタマイズできるだろうなということです。
コンフィグオプションやらなんやらで。
デフォルトはあくまでデフォルトでそうなるように設定値が決まっているということです。最初の状態を把握しておくことはどのコンフィグを触ってどのコンフィグを触らないでいいかの一助になるでしょう。

enableHdMenu:Boolean デフォルト:true
ヘッダーのドロップダウンメニューの表示有無。falseで非表示になる。

enableColumnHide:Boolean デフォルト:true
ヘッダーのドロップダウンメニュー内のカラム表示有無。falseで非表示になる。

enableColumnMove:Boolean デフォルト:true
ドラッグ&ドロップによるカラム移動の有効有無。falseで無効になる。すなわち移動不可。

enableColumnResize:Boolean デフォルト:true
グリッド間のカラムリサイズの有効有無。falseで無効になる。すなわちリサイズできなくなる。ただし無効にしても「←→」は出たままであるがリサイズできないという状態となる。

stripeRows:Boolean デフォルト:false
既定CSSによる行の縞々模様(ストライプ)表示有無。trueで有効になる。すなわち縞々模様になる。
ちなみにこの既定のCSSは背景色の指定のみで色は「#fafafa」となっている。
ついでなのでカラムや行の既定CSSをおさえておく。これらCSSは「ext-all.css」に書かれておりデフォルトで色などが決められているので変更したければ自分で上書き設定すればよいというわけ。基本的に背景色のみ変更可で文字色は不可。
  セルのCSS : x-grid3-cell-inner(※colorで文字色も変更できる)
  行のCSS : x-grid3-row
  行選択時のCSS : x-grid3-row-selected(※これだけは優先度の!importantを指定しないと有効にならないので注意)
  ストライプ設定時の行のCSS : x-grid3-row-alt
  マウスオーバー時の行のCSS : x-grid3-row-over

hideHeaders:Boolean デフォルト:false
ヘッダー部の表示有無。falseで非表示になる。


さて、グリッドパネルの肝のひとつでもある「Ext.grid.ColumnModel」いわゆるカラムモデルをじっくり見ていきます。
カラムモデルはstoreしたデータをグリッドでどのように表示するかというのを決める役割を果たします。
とりあえず設定できる
○header…タイトルの表示文字列

○width…カラムの幅(ピクセル)。%でも指定できるが変更する時はシングルクォーテーションでくくるのをお忘れなく

○dataIndex…storeのレコード部で指定した「name:」を指定。必須。

○sortable…昇順・降順でソートできるかどうか。tureでソート可能になる。デフォルトはfalse。

○id…任意のIDをつけることができる。

○renderer…データを改変してブラウザにレンダリングする。(※下の方で説明)

○align…セル中での表示位置。HTMLと同じでleft、center、rightが指定できる。多分だがヘッダー部とデータ部で違う指定はできないと思う。

○hidden…カラムの表示有無。trueで非表示になる。初回表示時に非表示になるだけでヘッダー部ドロップダウンメニュー内のカラムで表示にすることができる。

○hideable…カラムをヘッダー部ドロップダウンメニュー内のカラムで表示・非表示にできるかどうかを指定。falseにすると非表示にすることができない。正確にいえばチェックボックス自体が出てこなくなる。
ちなみに「hidden:true」+「hideable:false」と組み合わせると、表示もしないし表示させることもできなくなって完全に隠すことができる。そんな意味あんのん?と思うが、今思いつくのでは名前順でソートしておきたいけど漢字では正確にならばないからふりがなでソートさせるとうまくいく。けどふりがなの項目は表示させたくないっといた時とかに。

○resizable…カラム幅のリサイズ有効有無。falseでリサイズ無効となる。無効にすると→もでなくなる。
ちなみに親のグリッドパネルのコンフィグである「enableColumnResize:」で無効にしている場合はここで有効にしてリサイズできるようにはならない。

○menuDisabled…ヘッダー部ドロップダウンメニューの表示有無。trueで非表示になる。▼ボタン自体が出なくなる。

○tooltip…ヘッダー部にマウスオーバーした時に任意文字列のツールチップを表示。

○css…CSSを適用することができる。例えば「css: 'color: #FF0000;'」とするとヘッダーを除くデータ部のみが赤文字になる。


ぜひ面倒臭がらずに一度でいいから色々設定したりして実際の挙動を確かめてみることをおすすめします。
そうすることでここらへんのコンフィグはその気になったら調べてできるな、と思えるようになりますし、ある程度どういったことができるのか把握することができるでしょう。


これら設定値は基本カラム毎の設定になりますが、カラム数が結構多い時に全てソートOKにしたりする場合とかは面倒臭いですし、それだけソースも多くなりますよね。
そんな時に共通で値を設定することができるようです。

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true,
		width: 100
	},
	columns: [{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
こんな感じで。
「defaults:」で全共通が設定され個別で設定した値が適応されます。例えば

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true,
		width: 100
	},
	columns: [{
			header: '名前',
			width: 100,
			dataIndex: 'name',
			sortable: false
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
とすれば、「header: '名前'」のカラムだけソート不可になって、その他はソート可となります。
また
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true,
		width: 100
	},
	columns: [{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaultSortable : true,
	defaultWidth : 100,
	columns: [{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
は同じ意味となります。ちなみにデフォルトでwidthは100らしい。


また表なので連番(行番号)カラムを挿入することもできます。

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true
	},
	columns: [
		new Ext.grid.RowNumberer(),
		{
			id: 'name',
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
こうすると左端に行番号が出る。
「Ext.grid.RowNumberer」にもコンフィグオプションがあって、「columns:」と同じように「header:」と「width:」が指定できる。

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true
	},
	columns: [
		new Ext.grid.RowNumberer({header:'No',width:50}),
		{
			id: 'name',
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
こうするとヘッダー部に「No」という文字列がついた幅50のカラムが出現する。(デフォルトのwidthは23)



カラムモデルコンフィグのひとつrendererはデータをブラウザにレンダリングする前にデータに手を加えることができます。
例えばデータの中にメールのカラムがありますが、上記までのソースだとブラウザにはただの文字列が表示されるだけです。
HTMLなのでメールにリンクをつけてメーラーを開くという挙動をつけたいという時にこのrendererを使います。

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true
	},
	columns: [
		new Ext.grid.RowNumberer({header:'No',width:50}),
		{
			id: 'name',
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail',
			renderer: function(value){
				return '<a href="mailto:'+value+'">'+value+'</a>';
			}
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});
rendererのやり方には3通りのやり方があるとAPIドキュメントには書かれていますが、その一つです。
データをfunctionに投げてHTMLソースを返してもらうというとてもシンプルでわかりやすい方法です。
上記のように匿名関数でもOKですし、関数を別で定義してそれを指定するというやり方でももちろんOKです。
使う状況で言えば、メールの他にリンクだったり内容によって色分けしたりとかが多いんではないでしょうか…




個々のカラムはwidthで幅を指定できるが突き抜けてスクロールバーが出たり足りなかって中のテキストが途中で切れたりする場合も多い。
そこでこうする。

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true
	},
	columns: [
		new Ext.grid.RowNumberer({header:'No',width:32}),
		{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			id: 'info',
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});

var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: MyGridcolModel,
	autoExpandColumn: 'info'
});
このデータの中では備考が一番多い情報量でかつ長短だから、この備考に「id: 'info'」とIDを振ってやり、グリッドの方で「autoExpandColumn:」でそのIDを指定してやると、このカラムで幅を自動調整してくれる。
どうですか?この自動調整はなかなかいい感じでしょう?
またこれはひとつのカラムを指定して自動調整するというものだが、

[デモ]
var MyGridcolModel = new Ext.grid.ColumnModel({
	defaults: {
		sortable: true
	},
	columns: [
		new Ext.grid.RowNumberer({header:'No',width:32}),
		{
			header: '名前',
			width: 100,
			dataIndex: 'name'
		},{
			header: '性別',
			width: 50,
			dataIndex: 'gender'
		},{
			header: '電話番号',
			width: 120,
			dataIndex: 'tel'
		},{
			header: 'メール',
			width: 150,
			dataIndex: 'mail'
		},{
			header: '備考',
			width: 250,
			dataIndex: 'info'
		}
	]
});

var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: MyGridcolModel,
	viewConfig: {
		forceFit: true
	}
});
と書くと全てのカラムを対象にまんべんなく自動調整してくれる。
上記は
var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: MyGridcolModel,
	viewConfig: new Ext.grid.GridView({
		forceFit: true
	})
});
こうも書けるし
var MyGridviewConfig = new Ext.grid.GridView({
	forceFit: true
});

var MyGridPanel = new Ext.grid.GridPanel({
	title: 'グリッドパネル',
	renderTo: 'displayPanel',
	height: 300,
	store: MyDataStore,
	colModel: MyGridcolModel,
	viewConfig: MyGridviewConfig
});
こうやっても書いてもOK。

う〜ん「Ext.grid.GridView」のAPIドキュメントを見ていると結構な数のコンフィグオプションがあるみたいで色々設定できそうですね。
○columnsText…ヘッダー部ドロップダウンメニュー内の「カラム」という文字列を指定。

○headersDisabled…ヘッダー部において「クリックでソート機能」、「メニューの▼表示」の有効有無。trueでそれらを無効にする。デフォルトはfalse

○sortAscText…ヘッダー部ドロップダウンメニュー内の「昇順」という文字列を指定。

○sortDescText…ヘッダー部ドロップダウンメニュー内の「降順」という文字列を指定。
| ExtJS | Comment:0 |
コメント投稿












画像リロード
*半角の小英字、数字で構成されています