初心者のためのExtJS入門

ExtJSを使うので、ついでにまとめていきます

グリッドの機能:カラム(列)[classic]

チュートリアルの登録画面あたりに不具合があったので一部訂正しました。あまりテストしていなかったので・・・。

さて、今回はグリッド(Ext.grid.Panel)の使い方です(チュートリアルで作ったメモアプリを流用しています)。

何回かに分けてグリッドの機能を取り上げてみようと思っています。まずはカラムについてです。あと、classicに絞っています。modernはまた改めて・・・(ところでスマフォ表示でグリッドってそんなに使うのかな?)。

グリッドは、http://examples.sencha.com/extjs/6.2.0/examples/kitchensink/#array-gridにあるように表形式を表現するのに便利なビューコンポーネントです。

非常に多機能で、ソートや並べ替え、ページングなど色々なことができるので利用頻度が高いです。

とりあえず表示

グリッドパネルを表示させる最低限のコードは、↓になります。

storeとcolumnsを指定すれば、ひとまず表示はできます(データを出さなくても良いならcolumnsだけで表示できます)。

/**
 * メモ一覧グリッドクラス。
 *
 * @class Memo.view.list.Grid
 * @extend Ext.grid.Panel
 */
Ext.define('Memo.view.list.Grid', {
    extend: 'Ext.grid.Panel',
    xtype: 'list_grid',

    store: 'Memo',

    columns: [
        {
            dataIndex: 'title',
            text: 'タイトル',
            width: 250
        },
        {
            dataIndex: 'body',
            text: '本文',
            flex: 1
        }
    ]

});

f:id:sham-memo:20170201125954p:plain

データビューと同じようにstoreに使用するストアを設定します。

そして、columnsに列を定義します。上記コードだと、タイトルと本文の列が表示されます。タイトルは、width:250で幅を250ピクセルにしています。そして、本文に設定しているflex:1で、タイトル部以外に余っている横幅を埋めるように目一杯広げるようになります。パネルの幅が狭いときには、かなりつぶれて表示されることもあるので、最低限の幅を持たせたいならminWidthを付けておくと良いかもしれません。

これで表示はできました。このような最低限の状態でも、列見出し部分をクリックすれば並べ替えができたり、列の位置をドラッグ&ドロップで入れ替えたりできるようになっています。

カラム(列)

さきほどのコードにもありましたが、カラムの定義はcolumnsに設定します。カラムの機能を使って、さらに改良してみます。

/**
 * メモ一覧グリッドクラス。
 *
 * @class Memo.view.list.Grid
 * @extend Ext.grid.Panel
 */
Ext.define('Memo.view.list.Grid', {
    extend: 'Ext.grid.Panel',
    xtype: 'list_grid',

    requires: [
        'Ext.grid.column.Date'
    ],

    store: 'Memo',

    columns: [
        {
            dataIndex: 'id',
            text: 'ID',
            align: 'right',
            locked: true
        },
        {
            dataIndex: 'title',
            text: 'タイトル',
            width: 250,
            renderer: function (value) {
                return Ext.String.htmlEncode(value);
            }
        },
        {
            dataIndex: 'body',
            text: '本文',
            flex: 1,
            renderer: function (value) {
                value = Ext.String.htmlEncode(value);
                return value.replace(/\r?\n/g, '<br/>');
            }
        },
        {
            xtype: 'datecolumn',
            format: 'Y/m/d H:i:s',
            dataIndex: 'created',
            text: '登録日時',
            width: 200
        }
    ]

});

f:id:sham-memo:20170201140712p:plain

align、locked、rendererというプロパティと、Ext.grid.column.Dateというカラムの派生クラスを使ってみました。

alignを使うと表示位置を設定できます。これでIDを右寄せにしました。

lockedをtrueにすると、横スクロールがある場合に、列を固定することができます。Excelで列をロックするような感じになります。

rendererには表示内容を変換するための関数を設定できます。これで値に応じて表示を柔軟に変更できます。上記コードでは、第1引数の値しか使っていませんが、引数の数はもう少しあります(http://docs.sencha.com/extjs/6.2.1/classic/Ext.grid.column.Column.html#cfg-renderer)。よく使うのは第3引数のrecordぐらいまでです。

よく使うような機能はカラムの派生クラスとして用意されている場合があります。その一つがExt.grid.column.Dateです。これは日付項目のフォーマットに使えます。他にもExt.grid.column.NumberやExt.grid.column.Widgetなどがあります。

Ext.grid.column.Widgetを使ってみる

次はExt.grid.column.Widgetを試してみます。

このカラムを使うとグリッド内にいろいろなビューを埋め込むことができます(http://examples.sencha.com/extjs/6.2.0/examples/kitchensink/#widget-grid)。

ここではExt.grid.column.Widgetを使って削除ボタンを設置して1行のデータ削除をやってみました。

/**
 * メモ一覧グリッドクラス。
 *
 * @class Memo.view.list.Grid
 * @extend Ext.grid.Panel
 */
Ext.define('Memo.view.list.Grid', {
    extend: 'Ext.grid.Panel',
    xtype: 'list_grid',

    requires: [
        'Ext.grid.column.Date'
    ],

    store: 'Memo',

    columns: [
        {
            dataIndex: 'id',
            text: 'ID',
            align: 'right',
            locked: true
        },
        {
            dataIndex: 'title',
            text: 'タイトル',
            width: 250,
            renderer: function (value) {
                return Ext.String.htmlEncode(value);
            }
        },
        {
            dataIndex: 'body',
            text: '本文',
            flex: 1,
            renderer: function (value) {
                value = Ext.String.htmlEncode(value);
                return value.replace(/\r?\n/g, '<br/>');
            }
        },
        {
            xtype: 'datecolumn',
            format: 'Y/m/d H:i:s',
            dataIndex: 'created',
            text: '登録日時',
            width: 200
        },
        {
            xtype: 'widgetcolumn',
            width: 60,
            widget: {
                xtype: 'button',
                iconCls: 'x-fa fa-times',
                tooltip: '削除',
                handler: function (btn) {
                    var record = btn.getWidgetRecord(),
                        store = record.store;

                    Ext.Msg.confirm('確認', 'メモを1件削除します。よろしいですか?', function (btn) {
                        if (btn === 'yes') {
                            store.remove(record);
                            store.sync();
                        }
                    });
                }
            }
        }
    ]

});

f:id:sham-memo:20170201145036p:plain

widgetプロパティに表示したいコンポーネント設定します。ボタンを設置するのでxtype: 'button'となっています。

今回は例なので、handlerプロパティで直接ストアからデータを消すようにしています。Ext.grid.column.Widgetを使った場合、getWidgetRecordメソッドを使って対象行のモデルを取得できます。

おまけにExt.grid.column.Templateを使ってみる

このクラスは知らなかったので試してみました。たまに調べてみると見つけるんですよねw

/**
 * メモ一覧グリッドクラス。
 *
 * @class Memo.view.list.Grid
 * @extend Ext.grid.Panel
 */
Ext.define('Memo.view.list.Grid', {
    extend: 'Ext.grid.Panel',
    xtype: 'list_grid',

    requires: [
        'Ext.grid.column.Template',
        'Ext.grid.column.Date'
    ],

    store: 'Memo',

    columns: [
        {
            xtype: 'templatecolumn',
            tpl: '{id}:{[Ext.String.htmlEncode(values.title)]}',
            text: 'ID:タイトル',
            width: 250
        },
        {
            dataIndex: 'body',
            text: '本文',
            flex: 1,
            renderer: function (value) {
                value = Ext.String.htmlEncode(value);
                return value.replace(/\r?\n/g, '<br/>');
            }
        },
        {
            xtype: 'datecolumn',
            format: 'Y/m/d H:i:s',
            dataIndex: 'created',
            text: '登録日時',
            width: 200
        }
    ]
});

意味はないですが、IDとタイトルをExt.grid.column.Templateで出力するように変更してみました。複数項目をシンプルな形式で表示するのであれば、このクラスを使ったほうがスマートに書けそうです(今後は実務でも使っていこう)。

カラムの段組

columnsをネストすると、段組みできます。

/**
 * メモ一覧グリッドクラス。
 *
 * @class Memo.view.list.Grid
 * @extend Ext.grid.Panel
 */
Ext.define('Memo.view.list.Grid', {
    extend: 'Ext.grid.Panel',
    xtype: 'list_grid',

    requires: [
        'Ext.grid.column.Date'
    ],

    store: 'Memo',

    columns: [
        {
            dataIndex: 'id',
            text: 'ID',
            align: 'right',
            locked: true
        },
        {
            text: 'メモ',
            flex: 1,
            columns: [
                {
                    dataIndex: 'title',
                    text: 'タイトル',
                    width: 250,
                    renderer: function (value) {
                        return Ext.String.htmlEncode(value);
                    }
                },
                {
                    dataIndex: 'body',
                    text: '本文',
                    flex: 1,
                    renderer: function (value) {
                        value = Ext.String.htmlEncode(value);
                        return value.replace(/\r?\n/g, '<br/>');
                    }
                },
                {
                    xtype: 'datecolumn',
                    format: 'Y/m/d H:i:s',
                    dataIndex: 'created',
                    text: '登録日時',
                    width: 200
                },
                {
                    xtype: 'widgetcolumn',
                    width: 60,
                    widget: {
                        xtype: 'button',
                        iconCls: 'x-fa fa-times',
                        tooltip: '削除',
                        handler: function (btn) {
                            var record = btn.getWidgetRecord(),
                                store = record.store;

                            Ext.Msg.confirm('確認', 'メモを1件削除します。よろしいですか?', function (btn) {
                                if (btn === 'yes') {
                                    store.remove(record);
                                    store.sync();
                                }
                            });
                        }
                    }
                }
            ]
        }
    ]

});

f:id:sham-memo:20170201225639p:plain

カラムの標準機能のON/OFFを変更する

グリッドのカラムは最初から並べ替えや移動ができるのですが、列によっては使えないようにしたい場合があります。それには下記のプロパティを使います。

sortable ・・・ 並べ替えの設定

hideable ・・・ 非表示の設定

menuDisabled ・・・ カラム右側のメニューを無効にする設定

draggable ・・・ 移動の設定

 

 

 

 

 

しばらくは、このような感じでグリッドの機能を取り上げていく予定です。