elCarda
elCarda

Reputation: 197

How to call an action of controller from grids action column

I have an action column in my grid which is needed to perform lots of non-trivial operations after click on it. I don't want to use the handler method only to avoid duplicity in my code. I want to handle the click event from the controller method which can be called from more sides.

Here is my definition of action column:

{
    header: translator.translate('actions'),
    xtype: 'actioncolumn',
    width: 50,
    items:[{
        id     : 'detailContactPerson',
        icon   : '/resources/images/pencil.png',
        tooltip: translator.translate('show_detail')
    }]
},

But now I don't know how to write the Component query definition to set up listener.

 init: function() {
    this.control({
       'detailContactPerson': {
           click: function(obj) {
                 var contactPerson = obj.up('container').contactPerson;
                 this.detail(contactPerson);
            }
         },

Second way I've tried is to call the method of controller directly from handler method. It looks like this:

  {
    header: translator.translate('actions'),
    xtype: 'actioncolumn',
    width: 50,
    items:[{
        id     : 'detailContactPerson',
        icon   : '/resources/images/pencil.png',
        handler: function(contactPerson){
            Project.controller.contactPerson.detail(contactPerson);
        },
        tooltip: translator.translate('show_detail')
    }

But unfortunately it isn't supported way to call controller method (No method exception raised).

Could someone help me to construct working Component query, or show some example how to call controller method from outside?

Upvotes: 9

Views: 29996

Answers (5)

user1636522
user1636522

Reputation:

Here is a way to avoid declaring the handler (no need to use addEvents, ExtJS 4.1.1) :

Ext.grid.column.Action override :

Ext.grid.column.Action.override({
    constructor: function () {
        this.callParent(arguments);
        Ext.each(this.items, function () {
            var handler;
            if (this.action) {
                handler = this.handler; // save configured handler
                this.handler = function (view, rowIdx, colIdx, item, e, record) {
                    view.up('grid').fireEvent(item.action, record);
                    handler && handler.apply(this, arguments);
                };
            }
        });
    }
});

Action column config :

{
    xtype: 'actioncolumn',
    items: [{
        icon: 'edit.png',
        action: 'edit'
    }]
}

Controller :

this.control({
    'grid': {
        edit: function (record) {}
    }
});

Upvotes: 1

Oniram
Oniram

Reputation: 166

I have a better way: add new events on your view where are presents the actioncolumns:

    {
                xtype:'actioncolumn',
                align:'center',
                items:[
                    {
                        tooltip:'info',
                        handler:function (grid, rowIndex, colIndex) {
                            var rec = grid.getStore().getAt(rowIndex);
                            //this is the view now
                            this.fireEvent('edit', this, rec);
                        },
                        scope:me
                    },
    .... 
    me.callParent(arguments);
    me.addEvents('edit')

then on your controller:

 .....
 this.control({
         'cmp_elenco':{
                'edit':function(view,record){//your operations here}
 ....

Upvotes: 8

catalinux
catalinux

Reputation: 1452

You can also follow this example http://onephuong.wordpress.com/2011/09/15/data-grid-action-column-in-extjs-4/.

Upvotes: 0

LittleTreeX
LittleTreeX

Reputation: 1239

I too wanted to handle logic for the actioncolumn in a controller. I am not certain if this is better or worse than simply using one of the other plugins mentioned, however this is how I was able to get it to work.

Things to note:

  • the id config property in the items array of the actioncolumn does nothing at all, the icons will still receive a generated id
  • the items are NOT components, they are simply img elements
  • you can add an id to the actioncolumn itself to target a specific instance of actioncolumn
  • each icon (or item in the actioncolumn) is given a class of x-action-col-# where # is an index beginning with 0.

For example, in the columns definition of my grid I have:

    header: 'ACTION',
    xtype: 'actioncolumn',
    id: 'myActionId',
    width: 50,
    items: [{
        icon: 'resources/icons/doThisIcon.png',
        tooltip: 'Do THIS'
      },{
        icon: 'resources/icons/doThatIcon.png',
        tooltip: 'Do THAT'
      }
    ]

and in the controller:

    init: function(){
    this.control({
        'actioncolumn#myActionId': {
           click: function(grid,cell,row,col,e){
               var rec = grid.getStore().getAt(row);
               var action = e.target.getAttribute('class');
               if (action.indexOf("x-action-col-0") != -1) {
                   console.log('You chose to do THIS to ' + rec.get('id')); //where id is the name of a dataIndex
               }
               else if (action.indexOf("x-action-col-1") != -1) {
                   console.log('You chose to do THAT to ' + rec.get('id'));
               }
           }
        }
    }

Using this method, you can place all logic for any given action column in the controller.

Upvotes: 4

atian25
atian25

Reputation: 4256

try actioncolumn#detailContactPerson

or you can listene to actioncolumn 's click event

see this: http://www.sencha.com/forum/showthread.php?131299-FIXED-EXTJSIV-1767-B3-ActionColumn-bug-and-issues

init: function() {
        this.control({
            'contact button[action=add]':{
                click: this.addRecord 
            },
            'contact button[action=delete]':{
                click: function(){this.deleteRecord()} 
            },
            'contact actioncolumn':{
                click: this.onAction
            }
        });
    },
    onAction: function(view,cell,row,col,e){
        //console.log(this.getActioncolumn(),arguments, e.getTarget())
        var m = e.getTarget().className.match(/\bicon-(\w+)\b/)
        if(m){
            //选择该列
            this.getGrid().getView().getSelectionModel().select(row,false)
            switch(m[1]){
                case 'edit':
                    this.getGrid().getPlugin('rowediting').startEdit({colIdx:col,rowIdx:row})
                    break;
                case 'delete':
                    var record = this.getGrid().store.getAt(row)
                    this.deleteRecord([record])
                    break;
            }
        }
    }

BTW.I prefer to use these to instead of AcionColumn

Upvotes: 10

Related Questions