当社Webサイト

カテゴリー

Amazonサーチ

  • 01/12
    ExtJS, JavaScript post by 笹山 昭秀 @ 2010 年 1 月 12 日 10:20

    遅くなりましたが、明けましておめでとうございます。
    笹山です。

    前回の記事から更新が滞ってしまいました。(気づいたら2010年!)
    記事用の時刻表ExtJSソースは準備していたのですが更新を怠けておりました。
    (怠けている間にExt JS 3.1.0がリリースされておりました)
    ですので必死で思い出しながら書きます。(本当に完全に忘れている・・・やばい。)

    今回はExtJS3.0を用いて時刻表を作成する完結編です。
    前回は、

    • ページング機能
    • Gridの高さ変更
    • Grid内のツールチップ表示

    について書きましたが、やはり検索機能や飛行機の情報なんかも欲しくなるわけです。
    今回は検索機能、飛行機の情報表示を実装してオレオレ時刻表の作成を終わりたいと思います。

    検索機能の実装

    検索機能の実装も難しくはありません。
    実はExt.ux.data.PagingMemoryProxyのdoRequestメソッドにはすでにfiltering機能が備わっています。
    前回Ext.ux.data.PagingMemoryProxyを使用したソートで問題があったので、オーバーライドしてoverride-paging-memory-proxy.jsを作成しました。
    ですからoverride-paging-memory-proxy.jsを使用して検索機能を実装します。

    • override-paging-memory-proxy.js(フィルタリング部分)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    Ext.override(Ext.ux.data.PagingMemoryProxy,{
        doRequest: function(action, rs, params, reader, callback, scope, options){
     
    ~ 省略 ~
     
            // filtering
            if (params.filter !== undefined) {
                result.records = result.records.filter(function(el){
                    if (typeof(el) == 'object') {
                        var att = params.filterCol || 0;
                        return String(el.data[att]).match(params.filter) ? true : false;
                    }
                    else {
                        return String(el).match(params.filter) ? true : false;
                    }
                });
                result.totalRecords = result.records.length;
            }
     
    ~ 省略 ~

    これを見るとリクエストパラメータに、「filterCol」と「filter」を指定すれば良いことが分かります。
    filterColでGridのカラム位置を指定して、「Gird要素内容」と「filter」をmatchメソッドを用いて検索を行っています。

    それでは、Gridのカラムと検索文字列を指定して、Grid内のデータから検索ができるようにしてみます。
    「カラムを指定するためのComboBox」と「検索文字列を入力するFiled」をGridトップツールバーに作成します。
    前回grid-timetable.jsを編集して追加していきます。

    カラム指定のためのComboBox作成(Ext.form.ComboBox)

    まずは「検索カラムを指定するためのComboBox」をgrid-timetable.jsに作成します。

    • grid-timetable.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    Ext.onReady(function(){
     
        Ext.QuickTips.init();
     
        //
        // カラムを指定するためのComboBox
        //
        var filterColCombo = new Ext.form.ComboBox({
            id: 'filtercol_combo_id',
            width: 100,
            triggerAction: 'all',
            valueField: 'value',
            displayField : 'view',
            value: 'flightName',
            editable: false,
            mode: 'local',
            store: new Ext.data.ArrayStore({
                fields: ['view','value'],
                data: [
                    ['対象空港', 'destination'],
                    ['航空会社', 'airline'],
                    ['便名', 'flightName'],
                    ['機種', 'model'],
                    ['伊丹空港時間', 'itamiTime'],
                    ['対象空港時間', 'objectTime'],
                    ['出発/到着種別', 'type']
                ]
            }),
            listeners: {
                'select': {
                    fn: function(combo, record, index) {
                        store.baseParams = {
                            sort: 'itamiTime',
                            dir: 'ASC',
                            filterCol: record.data.value,
                        };
                    }
                },
                'afterrender': {
                    fn: function(combo) {
                        store.baseParams = {
                            sort: 'itamiTime',
                            dir: 'ASC',
                            filterCol: combo.value,
                        };
                     }
                }
            }
        });
     
    ~ 省略 ~

    詳細はExtJS3.0のAPIドキュメント(日本語)も出たことですし、そちらを見ていただくとして、今回はポイントだけを書きます。

    • ComboBoxのValue値がGridカラムのdataIndex値と一致するようにComboBoxを作成します。これによりフィルタリング時にGridカラムから値を取り出すことが可能になります。
    • ComboBoxのイベント処理「select」で、ComboBoxが選択された後にリクエストパラメータを設定します。ComboBoxの選択値「record.data.value」をfilterColに設定、同時にソートフィールド、ソート方向も設定しています。
    • ComboBoxのイベント処理「afterrender」で、ComboBoxがレンダリングされた後にリクエストパラメータを設定します。ComboBoxの初期値「combo.value」をfilterColに設定、同時にソートフィールド、ソート方向も設定しています。

    検索文字列を入力するFiled作成(Ext.ux.form.SearchField)

    次に検索文字列を入力するFiledをgrid-timetable.jsに作成します。
    すでにExt.ux.form.SearchFieldという便利なコンポーネントが用意されています。

    • grid-timetable.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    Ext.onReady(function(){
     
        Ext.QuickTips.init();
     
        var filterColCombo = new Ext.form.ComboBox({
     
    ~ 省略 ~
     
        var store = new Ext.data.Store({
     
    ~ 省略 ~
     
        //
      // 検索文字列を入力するFiled
        //
        var searchField = new Ext.ux.form.SearchField({
            store: store,
            width: 200,
            paramName: 'filter'
        });
     
    ~ 省略 ~
    • 検索時のデータソースとして使用するstoreには、Gridで使用するものと同じstoreを指定します。
    • Ext.ux.form.SearchFieldのデフォルトのリクエストパラメータは「query」となっているため、「filter」に変更します。これでリクエストパラメータが「filter」となり、override-paging-memory-proxy.js(フィルタリング部分)で使用できるようになります。

    Gridトップツールバーへ追加

    先ほど作成した「カラムを指定するためのComboBox」と「検索文字列を入力するFiled」をGridトップツールバーに追加します。

    • grid-timetable.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    Ext.onReady(function(){
     
        Ext.QuickTips.init();
     
    ~ 省略 ~
     
        var grid = new Ext.grid.GridPanel({
     
    ~ 省略 ~
     
            //
            // Gridトップツールバー
            //
            tbar: [
                filterColCombo,
                searchField
            ],
     
    ~ 省略 ~
    • GridPanelのトップツールバー(tbar)に、先ほど作成したfilterColComboとsearchFieldを指定します。

    たったこれだけで検索機能は完成です。

    検索カラム指定ComboBoxと検索文字列入力Field

    検索カラム指定ComboBoxと検索文字列入力Field



    便名指定からの検索結果

    便名指定からの検索結果

    Grid内に画像付きの飛行機情報を表示する

    Gridに表示されている機種は「どんな飛行機なんだろう?」と思ったりしませんか?
    それでは、Ext.ux.grid.RowExpanderを使用して画像付きの簡単な機種情報が出るようにしてみようと思います。

    画像付きの飛行機情報表示機能作成(Ext.ux.grid.RowExpander)

    Ext.ux.grid.RowExpanderを使うと、Gridの各行に[+][-]アイコンを表示して、そのアイコンで行を伸縮し、付加情報を表示/非表示にすることができます。
    また表示する情報はExt.Templateを用いて自由にレイアウトすることができます。

    • grid-timetable.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    Ext.onReady(function(){
     
        Ext.QuickTips.init();
     
    ~ 省略 ~
     
        var expander = new Ext.ux.grid.RowExpander({
            tpl : new Ext.Template(
                '<table>',
                '    <tr>',
                '        <td>',
                '            <img src="../plainmodel/{airline}/{model}.jpg" alt="{model}">',
                '        </td>',
                '        <td>',
                '            <iframe src="../plainmodel/{airline}/{model}.html" width="500" height="100" frameborder="0"></iframe>',
                '        </td>',
                '    </tr>',
                '</table>'
            )
        });
     
    ~ 省略 ~
    • GridのColumns配列内にexpanderを作成するため、Ext.Template を使うことにより {キー名}の箇所がGrid dataIndexから取り出された値で置き換えられます。
    • {キー名}から取り出された値がフォルダ名、ファイル名となるようにしています。
      あらかじめ画像やHTMLが表示されるようにデータを準備して配置しています。
      (例){airline}キーの値がANA、{model}キーの値がB7の場合
      • img src=”../plainmodel/ANA/B7.jpg”
      • iframe src=”../plainmodel/ANA/B7.html”

    GridのColumns配列に追加

    先ほど作成したexpanderをGridのColumns配列に追加します。

    • grid-timetable.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    Ext.onReady(function(){
     
        Ext.QuickTips.init();
     
    ~ 省略 ~
     
        var grid = new Ext.grid.GridPanel({
            title: '時刻表',
            frame: true,
            height: 350,
            width: 750,
            renderTo: 'grid-timetable',
            stripeRows: true,
            trackMouseOver:true,
            store: store,
                columns: [
             //
                    // 画像付きの飛行機情報を表示Expander
                    //
                    expander,  //← ここ
                   {
                      header: '対象空港',
                      sortable: true,
                      dataIndex: 'destination',
                      renderer: function(v, params) {
                          params.attr = getQtipAttr("対象空港", v, 100);
                          return v;
                      }
                  },
     
    ~ 省略 ~

    たったこれだけで、こんなにリッチになります。どうですか?

    Grid Expander 画像付きの飛行機情報を表示する

    Grid Expander 画像付きの飛行機情報を表示する

    今回のソースとデモ

    ※Grid中の飛行機画像は私が趣味で撮影した画像です。

    最後に

    時刻表の完成です。
    これでエアーバンドを聞きながら検索をかけて、しかも飛行機情報まで表示してくれます。
    ずいぶんと私好みの自己中心的な時刻表になってしまいました。

    ExtJSで、ごりごり実装することもなく簡単にリッチなテーブルができることがお分かりいただけたと思います。
    余裕があるときに改造して「おれおれ時刻表」をパワーアップしていけたらと思っています。

    参考リンク

    あわせて読みたい

    Tags: , , , , ,