ExtJS の DataGrid で行選択時のイベント処理やフィルタリング処理を実装してみる

Ext JS の DataGrid を使って以下の機能を実装してみた。

  • 行選択のイベント処理
  • 表示データにフィルターを適用

サンプルコード

<html>
<head>
<link rel="stylesheet" type="text/css" href="ext-2.0/resources/css/ext-all.css" />
<script type="text/javascript" src="ext-2.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-2.0/ext-all.js"></script>
<script type="text/javascript" src="ext-2.0/adapter/jquery/jquery.js"></script>

<script type="text/javascript">
    Ext.BLANK_IMAGE_URL = "ext-2.0/resources/images/default/s.gif";

    Ext.onReady(function() {

        var data = [
            ['test1', 1000.10, '2007/12/1', 'id:1'],
            ['a', 50.1, '2007/12/27', 'id:2'],
            ['チェックデータ', -10, '2008/1/1', 'id:3']
        ];

        var store = new Ext.data.SimpleStore({
            fields: [
                {name: 'title'},
                {name: 'point', type: 'float'},
                {name: 'date', type: 'date'},
                {name: 'id'}
            ]
        });

        store.loadData(data);

        var grid = new Ext.grid.GridPanel({
            columns: [
                {id: 'title', width: 200, header: 'Title', sortable: true, dataIndex: 'title'},
                {header: 'Point', width: 50, sortable: true, dataIndex: 'point'},
                {header: 'Date', sortable: true, dataIndex: 'date', renderer: Ext.util.Format.dateRenderer('Y/m/d')}
            ],
            store: store,
            width: 600,
            height: 200,
            stripeRows: true,
            autoExpandColumn: 'title'
        });

        //行選択時のイベント処理を実装
        grid.addListener('rowclick', function(thisGrid, rowIndex, e) {
            var list = thisGrid.selModel.getSelections();

            alert("click rowIndex: " + rowIndex);

            for(var i = 0; i < list.length; i++) {
                alert("selected : " + list[i].get('id') + ", " + list[i].get('title') + " ---- index :" + thisGrid.getStore().indexOf(list[i]));
            }
            thisGrid.setWidth(800);
        });

        grid.render('grid-sample');
        grid.getSelectionModel().selectFirstRow();

        //フィルター機能の実装
        $("#filter").bind('blur', function(e) {
            var filterString = $("#filter").val().trim();

            if (filterString == "") {
                //フィルターの設定をクリア
                grid.getStore().clearFilter(false);
            }
            else {
                //フィルターを設定
                grid.getStore().filterBy(function(obj) {
                    if (obj.get('title').indexOf(filterString) > -1) {
                        return true;
                    }
                    return false;
                });
            }
        });

    });
</script>

</head>
<body>
<h1>ExtJS DataGrid Sample</h1>

<div id="grid-sample"></div>
filter: <input type="text" id="filter"></input>

</body>
</html>

行選択のイベント処理

GridPanel の on や addListener のメソッドの第一引数に 'rowclick'、第二引数にイベント処理の実装を設定すれば、行のクリック時にイベント処理が実行される。

GridPanel の selModel で Ext.grid.RowSelectionModel を取得し、getSelections() メソッドを呼び出すことで、選択状態にある行を表現するレコードオブジェクト Ext.data.Record が "選択された順で" 配列化されたものが取得できる。

ここで、GridPanel から getStore() で Ext.data.Store オブジェクトを取得し、indexOf に Ext.data.Record オブジェクトを渡すことで表示上のインデックス値を取得することも可能。

また、Ext.data.Record の get メソッドで指定項目の値を取得する事ができる。

<script type="text/javascript">
    ・・・
        grid.addListener('rowclick', function(thisGrid, rowIndex, e) {
            var list = thisGrid.selModel.getSelections();

            alert("click rowIndex: " + rowIndex);

            for(var i = 0; i < list.length; i++) {

                alert("selected : " + list[i].get('id') + ", " + list[i].get('title') + " ---- index :" + thisGrid.getStore().indexOf(list[i]));
            }
            thisGrid.setWidth(800);
        });
    ・・・
</script>

表示データにフィルターを適用

Ext.data.Store クラスの clearFilter メソッドでフィルターを無効化、filterBy で自作のフィルターを設定する事が可能。

なお、clearFilter に false を指定すると自動的に再描画を行ってくれる。

<script type="text/javascript">
    ・・・
        $("#filter").bind('blur', function(e) {
            var filterString = $("#filter").val().trim();

            if (filterString == "") {
                //フィルターの設定をクリア
                grid.getStore().clearFilter(false);
            }
            else {
                //フィルターを設定
                grid.getStore().filterBy(function(obj) {
                    if (obj.get('title').indexOf(filterString) > -1) {
                        return true;
                    }
                    return false;
                });
            }
        });
    ・・・
</script>