4
votes

I'm trying to create a dynamic grid using ExtJS. The grid is built and displayed when a click event is fired then an ajax request is sent to the server to fetch the columns, records and records definition a.k.a store fields.

Each node could have different grid structure and that depends on the level of the node in the tree.

The only way I came up with so far is :

function showGrid(response, request) {
    var jsonData = Ext.util.JSON.decode(response.responseText);
    var grid = Ext.getCmp('contentGrid' + request.params.owner);

    if (grid) {
        grid.destroy();
    }

    var store = new Ext.data.ArrayStore({
        id: 'arrayStore',
        fields: jsonData.recordFields,
        autoDestroy: true
    });

    grid = new Ext.grid.GridPanel({
        defaults: {
            sortable: true
        },
        id: 'contentGrid' + request.params.owner,
        store: store,
        columns: jsonData.columns,
        //width:540,
        //height:200,
        loadMask: true
    });


    store.loadData(jsonData.records);
    if (Ext.getCmp('tab-' + request.params.owner)) {
        Ext.getCmp('tab-' + request.params.owner).show();
    } else {
        grid.render('grid-div');
        Ext.getCmp('card-tabs-panel').add({
            id: 'tab-' + request.params.owner,
            title: request.params.text,
            iconCls: 'silk-tab',
            html: Ext.getDom('grid-div').innerHTML,
            closable: true
        }).show();
    }
}

The function above is called when a click event is fired

'click': function(node) {
    Ext.Ajax.request({
            url: 'showCtn',
            success: function(response, request) {
                alert('Success');
                showGrid(response, request);
            },
            failure: function(results, request) {
                alert('Error');
            },
            params: Ext.urlDecode(node.attributes.options);
        }
    });
}

The problem I'm getting with this code is that a new grid is displayed each time the showGrid function is called. The end user sees the old grids and the new one. To mitigate this problem, I tried destroying the grid and also removing the grid element on each request, and that seems to solve the problem only that records never get displayed this time.

if (grid) {
    grid.destroy(true);
}

The behaviour I'm looking for is to display the result of a grid within a tab and if that tab exists replaced the old grid.

Any help is appreciated.

2

2 Answers

3
votes

When you are trying to add your grid to the tab like this:

html:Ext.getDom('grid-div').innerHTML,

Ext is not aware of it being a valid grid component. Instead, you are simply adding HTML markup that just happens to look like a grid, but the TabPanel will not be aware that it is a grid component.

Instead you should add the grid itself as the tab (a GridPanel is a Panel and does not need to be nested into a parent panel). You can do so and also apply the needed tab configs like this:

Ext.getCmp('card-tabs-panel').add({
    Ext.apply(grid, {
        id: 'tab-' + request.params.owner,
        title: request.params.text,
        iconCls: 'silk-tab',
        closable: true
    });
}).show();

BTW, constantly creating and destroying grids is not an ideal strategy if you can avoid it. It might be better to simply hide and re-show grids (and reload their data) based on which type of grid is needed if that's possible (assuming the set of grid types is finite).

1
votes

A potential option is to use the metaData field on the JsonStore that allows dynamic reconfiguring of the grid columns as per new datasets.

From

One of the most helpful blog posts about this that Ive found is this one: http://blog.nextlogic.net/2009/04/dynamic-columns-in-ext-js-grid.html and the original info is well documented at http://docs.sencha.com/ext-js/3-4/#!/api/Ext.data.JsonReader