ExtJSで楽しくRIA業務アプリ開発

株式会社sus4 開発チーム

ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック)

3件のコメントがあります

このエントリーを含むはてなブックマークはてなブックマーク - ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック) この記事をクリップ!Livedoorクリップ - ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック) Yahoo!ブックマークに登録 BuzzurlにブックマークBuzzurlにブックマーク このエントリをつぶやくこのWebページのtweets Share on Tumblr FC2ブックマークへ追加 newsing it! この記事をChoix! Googleブックマークに追加 Bookmark this on Delicious Digg This

前回はツールバーでグリッドの情報を取得し、ポップアップで表示しました。今回はグリッドのダブルクリックと右クリックのイベントで詳細を表示する処理を実行します。

グリッドのダブルクリックと右クリック(コンテクストメニュー)で処理を実装することで、より直感的なグリッドの操作が可能になります。
サンプルは前回のExJS入門21 グリッド・セレクション・モデルをベースにイベントの処理を追加しています。

右クリックメニュー

右クリックメニュー

グリッドパネル関連の過去の記事はこちらからです。

リファレンスはこちらから
今回はExt.menu.Menuクラスを右クリックに仕込んでいます。

ExtJS -3.0 日本語APIドキュメント – Ext.grid.GridPanelクラス
http://extdocs.xenophy.com/?class=Ext.grid.GridPanel

ExtJS -3.0 日本語APIドキュメント – Ext.menu.Menuクラス
http://extdocs.xenophy.com/?class=Ext.menu.Menu

PHP:


<?php
    $limit = $_POST['limit'];
    $start = $_POST['start'];

    $name = $_POST['name'];

    //全データ
    $data = array(
        array(
            'id'=>1,
            'rank'=>1,
            'name'=>'IE',
            'percentage'=>62.69,
            'url' => 'http://www.microsoft.com/japan/windows/products/winfamily/ie/default.mspx',
            'img' => '../img/ie64.png'
        ),
        array(
            'id'=>2,
            'rank'=>2,
            'name'=>'Firefox',
            'percentage'=>24.61,
            'url' =>'http://mozilla.jp/firefox/',
            'img' => '../img/firefox64.png'
        ),
        array(
            'id'=>3,
            'rank'=>3,
            'name'=>'Chrome',
            'percentage'=>4.63,
            'url' => 'http://www.google.com/chrome/',
            'img' => '../img/chrome64.png'
        ),
        array(
            'id'=>4,
            'rank'=>4,
            'name'=>'Safari',
            'percentage'=>4.46,
            'url'=> 'http://www.apple.com/jp/safari/',
            'img' => '../img/safari64.png'
        ),
        array(
            'id'=>5,
            'rank'=>5,
            'name'=>'Opera',
            'percentage'=>2.40,
            'url' => 'http://jp.opera.com/',
            'img' => '../img/opera64.png'
        ),
        array(
            'id'=>6,
            'rank'=>6,
            'name'=>'Opera Mini',
            'percentage'=>0.53,
            'url' => 'http://jp.opera.com/',
            'img' => '../img/opera64.png'
        )
    );

    if ($name) {
        $newData = array();
        foreach($data as $val){
            if(stristr($val['name'],$name)) {
                $newData[] = $val;
            }
        }
        $data = $newData;
    }

    if ($limit &amp;&amp; $start + $limit <= count($data)) {
        //ページング用
        $rows = array_slice($data,$start,$limit);
    }else {
        //ページングしない
        $rows = $data;
    }

    $res = array(
        'success' => true,
        'total' => 6,
        'rows' => $rows
    );

    header("Content-Type: text/javascript; charset=utf-8");
    echo json_encode($res);

    die();

HTML:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ExtJS名古屋勉強会 クリックイベント</title>

    <!--Ext JS CSS-->
    <link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
    <!--Ext JS-->
    <script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>

    <script type="text/javascript" src="../js/ext/ext-all.js"></script>
    <script type="text/javascript" src="grid-click.js"></script>
    <style TYPE="text/css">
    <!--
        .info {background-image: url(../img/icon/information.png) !important;}
        .delete {background-image: url(../img/icon/delete.png) !important;}
    -->
    </style>
</head>
<body>
    <div style="width:500px;margin:0 auto;padding:15px;background-color:#D3E1F1;font-size:small;">
        <p style="font-weight:bold;padding:3px;margin-bottom:10px;">
            クリックイベントの処理を設定します。
        </p>

        <ul>
            <li>rowdblclick:行のダブルクリック</li>
            <li>rowcontextmenu:行の右クリック</li>
        </ul>
        <div id="grid"></div>
        <br/>
        Java Script:<a href="grid-click.js">grid-click.js</a><br/>

        PHP(JSONデータ):<a href="data.php">data.php</a><br />
    </div>
</body>
</html>

Java Script:


//グリッドイベント
Ext.onReady(function()
{
    //詳細表示処理
    //詳細表示イベント実行時にこの関数を呼ぶ。
    var showInfo = function(record) {
        if(!record) {return;};

        //表示するメッセージ
        var msg = new Ext.XTemplate(
            '<div style="width:200px; text-align:center;">',
            'ブラウザ名:{name}<br/>',
            '順位:{rank}<br/>',
            'シェア:{percentage}%<br />',
            '<a href="{url}" target="_blank">DOWNLOAD</a><br/>',
            '<img src="{img}" />',
            '</div>').apply(record.data);

        Ext.Msg.alert('選択中のブラウザ',msg);
    };

    //1.データを用意
    //今回はPHPでdata.phpでJSONを返しています。

    //2.データストアを用意
    var store = new Ext.data.JsonStore({
        url:'data.php',//php等が使えない場合はここをdata:'data.json'としてローカルファイルの取得してもよいです。
        root:'rows',            //実際のデータ位置(プロパティ名)
        totalProperty:'total',  //全件数を返すプロパティ名を指定
        fields:[
            {name:'id'},
            {name:'rank'},
            {name:'name'},
            {name:'percentage',type:'float'},
            {name:'url',type:'url'},
            {name:'img',type:'url'},
        ],
        autoLoad:true           //描写後に自動的に初回のリクエストをかける
    });

    //3.SelModelの設定
    //今回は一度に一つの行しか選択できないようにしている。
    var sm = new Ext.grid.RowSelectionModel({
        singleSelect:true
    });

    //4.カラムモデルを用意
    var column = new Ext.grid.ColumnModel([
        {
            id:'rank',
            header:'順位',
            dataIndex:'rank',
            width:50
        },
        {
            id:'name',
            header:'ブラウザ名',
            dataIndex:'name',
            width:100
        },
        {
            id:'percentage',
            header:'シェア',
            dataIndex:'percentage',
            width:80
        },
        {
            id:'id',
            header:'ID',
            dataIndex:'id',
            width:20
        }
    ]);

    var contextMenu = new Ext.menu.Menu({
        items: [
            {
                text:'詳細表示',
                iconCls:'info',
                scope:this,
                handler: function(btn){
                    var record = grid.selModel.getSelected();
                    showInfo(record);
                }
            },{
                text:'削除',
                iconCls:'delete',
                scope:this,
                handler:function(btn){
                    var record = grid.selModel.getSelected();
                    Ext.Msg.alert('選択中のブラウザの削除', '「' + record.get('name') + '」を削除しますか?');
                }
            }
        ]
    });

    //5.グリッドパネルの作成
    var grid = new Ext.grid.GridPanel({
        renderTo:'grid',
        id:'my-grid',
        autoExpandColumn:'name',
        title:'SingleSelectのグリッドパネル',
        height:210,
        width:400,
        cm:column,
        sm:sm,
        store:store,
        tbar:[
            {
                text:'詳細情報表示',
                iconCls:'info',
                handler:function(btn){
                    var record = grid.selModel.getSelected();
                    showInfo(record);
                }
            },
            {
                text:'削除',
                iconCls:'delete',
                handler:function(btn){
                    var record = grid.selModel.getSelected();
                    Ext.Msg.alert('選択中のブラウザの削除', '「' + record.get('name') + '」を削除しますか?');
                }
            }
        ],
        //イベントを設定する。
        /**
         *  今回はどちらのイベントも引数は同じ。
         *  rowdblclick:ダブルクリックイベント
         *  rowcontextmenu:ダブルクリックイベント
         *      grid:グリッド
         *      row:ダブルクリックした行のインデックス
         *      e:イベントオブジェクト
         *
         */
        listeners:{
            rowdblclick:function(grid, row, e){
                var record = grid.getStore().getAt(row);
                showInfo(record);
            },
            rowcontextmenu:function(grid, row, e){
                //右クリックでセレクト処理(セレクトしたものを後で右クリックメニューで取得する)
                grid.getSelectionModel().selectRow(row);

                //右クリックイベントを止める。ここで止めないとブラウザの右クリックメニューが表示されてしまう。
                e.stopEvent();

                //コンテクストメニューを表示
                contextMenu.showAt(e.getXY());
            }
        }
    });
});

実行結果:

右クリックメニュー

右クリックメニュー


詳細表示処理
削除処理

グリッドの部分は基本的に前回のサンプルのままです。
ExtJSのクラスに定義されているイベントを処理するときはコンフィグ・オプションのlistenersにイベントごとの処理を記述していきます。
今回はExt.grid.GridPanelクラスのrowdblclickイベントとrowcontextmenuイベントの処理を書いていきます。listenersコンフィグはオブジェクトで指定します。それぞれのイベントに対応するプロパティ名に処理を定義します。各イベントは違った引数を持ちます。ExtJSの標準クラスのイベントについては各クラスのAPIリファレンスのイベント項目に記載されています。
今回は偶然ですがrowdblclickとrowcontextmenuのイベントは同じ引数を持ちます。

  • 第1引数:対象のグリッド・オブジェクト
  • 第2引数:クリックした、行のインデックス
  • 第3引数:イベントオブジェクト
    • 第1引数のグリッドオブジェクトと第2引数のインデックスを使ってクリックした行に対応するストアのレコードを取り出すことができます。具体的には以下のようにstoreのgetAt()メソッドを使って取り出します。グリッドではグリッドのストアからrecordさえ取り出せれば後は自由に処理を実行できます。
      では実際にイベント処理を見ていきますrowdblclickは比較的シンプルですが、rowcontextmenuはほんの少しだけ複雑です。まずrowdblclickでイベント処理の感覚をつかむでおくと良いと思います。

      ・グリッドのダブルクリック (rowdblclickイベント)

      
      listeners:{
      	 rowdblclick:function(grid, row, e){
      		var record = grid.getStore().getAt(row);
      		/**
      		 * 上の処理はこう書いても同じです。
      		 * var store = grid.getStore();
      		 * var record = grid.getAt(row);
      		 */
      
      		showInfo(record);
      	}
      }
      

      イベント処理はこれだけです。イベントの引数にそれぞれ、grid,row,eを当てています。ダブルクリックした対象のrecordをストアから取得して、そのレコードをshowInfo()で処理しています。showinfo()は詳細をポップアップで表示する処理です。grid.getStore()でストアを取得して、getAt()でレコードを取得します。showInfo()関数は前回のサンプルでtbarのハンドラーに仕込んだ処理と全く同じです。
      意外と簡単ですね。次にrowcontextmenuのイベントを処理します。

      ExtJSでは独自の右クリックメニュー(コンテクストメニュー)を設定することができます。基本的な考え方としてはExtのMenuクラス(Ext.menu.Menuクラス等)を右クリックした位置に表示して、ブラウザの右クリックメニューをキャンセルさせることで、ExtJSで独自の右クリックメニューを表示させています。

      rowdblclickと同じでrowcontextmenuも基本的にストアからrecordを取り出すことが目標です。
      処理の大まかな流れは

      1.右クリックした行を選択する。
       ↓
      2.イベントを止める
       ↓
      3.メニューを表示
       ↓
      4.メニューの処理でrecordを取得

      になります

      実際にサンプルを見ていきます。

      
      listeners:{
      		rowcontextmenu:function(grid, row, e){
      
      			//右クリックでセレクト処理(セレクトしたものを後で右クリックメニューで取得する)
      			grid.getSelectionModel().selectRow(row);
      			//右クリックイベントを止める。ここで止めないとブラウザの右クリックメニューが表示されてしまう。
      			e.stopEvent();
      
      			//コンテクストメニューを表示
      			contextMenu.showAt(e.getXY());
      		}
      }
      

      コンテクストメニューの処理

      
        var contextMenu = new Ext.menu.Menu({
              items: [
                  {
                      text:'詳細表示',
                      iconCls:'info',
                      scope:this,
                      handler: function(btn){
                          var record = grid.selModel.getSelected();
                          showInfo(record);
                      }
                  },{
                      text:'削除',
                      iconCls:'delete',
                      scope:this,
                      handler:function(btn){
                          var record = grid.selModel.getSelected();
                          Ext.Msg.alert('選択中のブラウザの削除', '「' + record.get('name') + '」を削除しますか?');
                      }
                  }
              ]
          });
      

      右クリックした行を選択して、その後その行のレコードを取得して処理します。コンテクストメニューの処理は前回のtbarの記述とよく似ています。今回は詳細表示のほかに削除のメニューもつけています。削除の処理はまだダミーでポップアップが表示されるだけです。handlerの中が右クリックの実際の処理ですが、recordをセレクションモデルから取得しています。あとはrowdblclickと同じでshowInfow()に処理を渡しています。削除のほうも処理の内容はほぼ同じです。

      これでグリッドの各行に対応した右クリックを表示することができるようになりました。右クリックメニューはさらに階層を使ってアクションを沢山指定することもできます。詳しくはAPIリファセンスを参照してください。

      この2つのイベント以外にもグリッドには様々なイベントが定義されています。APIリファレンスのイベントの項目を見て、listenersに設定して試してみるとExtJSグリッドの多機能さが良く分かると思います。また独自のイベントを定義することもできます。イベントについてはまた別の機会に解説します。

      • Share/Bookmark


佐竹 裕行

1982年生まれ。滋賀→はこだて→名古屋→大垣→名古屋。
2006年名古屋学芸大学映像メディア学科卒、その後IAMAS卒(Studio2、6期生)。2009年にsus4に入社。学生時代はMax/MSP JitterやGainerばっかり使っていたが、現在社内では主にExtとモバイル開発、動画サービスのバックエンドを担当。知る人ぞ知るアノ鍵の人。

3 Responses to 'ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック)'

Subscribe to comments with RSS or TrackBack to 'ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック)'.

  1. [...] ExJS入門22 グリッドのイベント処理(ダブルクリック、右クリック) [...]

  2. [...] ExJS入門22 グリッドのイベント処理(ダブルクリック、右クリック) [...]

  3. [...] ExJS入門22 グリッドのイベント処理(ダブルクリック、右クリック) [...]

コメントを残す

Get Adobe Flash playerPlugin by wpburn.com wordpress themes