Search code examples
extjsextjs3

Adding link against each row in grid


I need to display a 'Delete' link against each row in a editorgridpanel.
How do I create this link;as it is not mapped to any particular column in the store?
I tried the following but it does not display the link against the added records:

 var sampleRecord = new Ext.data.Record.create([
        {mapping: 'organizationId',name:'organizationId', type:'int'},
        {mapping: 'name',name:'name', type:'string'},
        {mapping: 'address',name:'address' , type:'int'}
        ]);

    var s_grid= new Ext.grid.EditorGridPanel ({
        .........
            columns: [
                  {header: 'id', width: 120, sortable: false, dataIndex: 'organizationId'},
                  {header: 'name',width: 120, sortable: false, dataIndex: 'name'},
                  {header: 'address', sortable: false,width: 45, dataIndex: 'address'},
                  {header: '',width: 50, sortable: false, renderer:this.delRenderer }
             ],
            .....
,
            delRenderer:function (val, meta, rec, rowIdx) {
                var tempStr="<div onclick=\"javascript:Ext.getCmp('" +"s_grid" + "').deAllocate(" + rowIdx + ");\" class='pointer'><span style='color:#0000FF'><u>Delete</u></span></div>";
                return tempStr ;
            },
            deAllocate:function (rowIdx ) {
                Ext.getCmp('s_grid').getStore().removeAt(rowIdx);
                Ext.getCmp('s_grid').getView().refresh();
            }

            });

Help is appreciated.


Solution

  • You'd be better off using an ActionColumn. Anyway, you can also wrap a solution around custom element (link...) with the cellclick event. Here's an example showing both methods:

    var grid = new Ext.grid.GridPanel({
        renderTo: Ext.getBody()
        ,height: 300
    
        ,store: new Ext.data.JsonStore({
            fields: ['id', 'name']
            ,data: [
                {id: 1, name: 'Foo'}
                ,{id: 2, name: 'Bar'}
                ,{id: 3, name: 'Baz'}
            ]
        })
    
        ,columns: [
            {dataIndex: 'name'}
            ,{
                xtype: 'actioncolumn'
                ,icon: 'http://images.agoramedia.com/everydayhealth/gcms/icon_delete_16px.gif'
                ,handler: function(grid, row) {
                    grid.store.removeAt(row);
                }
            }
            ,{
                renderer: function(value, md, record, row, col, store) {
                    return '<a class="delete-link" href="#delete-record-' + record.id + '">Delete</a>';
                }
            }
        ]
    
        ,listeners: {
            cellclick: function(grid, row, col, e) {
                var el = e.getTarget('a.delete-link');
                if (el) {
                    e.preventDefault();
                    grid.store.removeAt(row);
                }
            }
        }
    });
    
    var lastId = 3;    
    setInterval(function() {
        var store = grid.store,
            record = new store.recordType({id: ++lastId, name: 'New record #' + lastId}, lastId);
        store.add(record);
    }, 3000);
    

    Update

    And just because I may be completely off topic on your question, I think your code is not working because when you call this:

    renderer: this.delRenderer
    

    Your not in a scope where this points to your grid (since it has not even been created at this point...). What you want to do is rather something like this:

    var s_grid = new Ext.grid.EditorGridPanel ({
        ...
        columns: [..., {
            ...
            renderer: delRenderer
        }]
    });
    
    function delRenderer() {
        // FYI, `this` will be the column here
        ...
    }
    

    Or put the function inline in the grid definition...