I’ve got a data grid in one of my applications that is paginated because the underlying data set is over 9700 records in size. As I’ve said in previous articles, pagination is an annoying design pattern, but a necessary evil nonetheless.

To make it easier on my users, I put a Ext.form.ComboBox in the toolbar of the grid which can be used by the users to search for records. The problem I was having was twofold:

  1. The ComboBox has one Ext.data.Store and the data grid has another one that is used to display the default, first 100 records in the table.
  2. The ComboBox displays its results in a list beneath itself by default, but I wanted the results displayed in the grid.

The second problem was easy enough to solve. When the list is shown it raises the expand event, so I capture that and immediately close it again with the collapse() method.

However, having the data grid, in essence, be able to display the contents of two different Stores was a bit more problematic since Ext.grid.GridPanel doesn’t have a setStore() method (which, I suppose, I could have implemented). My solution was to copy the contents of the search results into the store used by the GridPanel. This way, the user can still page the entire data set if she so wishes, but search results will override the Store when it is done.

// Create the data store for all things found with the search bar with each row represented by a Thing
var ProviderSearchStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({url: 'liveQueries/searchForStuff.cfm'}),
    reader: new Ext.data.JsonReader({ root:'data',totalProperty:'recordcount'}, Thing)
});

// Since the grid is using the ProviderStore, when the store for the
// search feature is populated, clear out the grid's store and populate
// it with the records retrieved in the search
SearchStore.on('load',
    function()
    {
        var allRecords = SearchStore.getRange();
        DefaultStore.removeAll();
        DefaultStore.add(allRecords);
    });

/*
 * When the list of results is shown, immediately collapse it since we're
 * showing the results in the grid
 */
combo.on('expand', function(){ combo.collapse(); });

// Create the data store for all insurers with each row represented by an Insurer
var DefaultStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({url: 'liveQueries/getStuff.cfm'}),
    reader: new Ext.data.JsonReader({ root:'data', totalProperty:'totalRecords' }, Thing)
});

// Create the grid to show insurers
var grid = new Ext.grid.GridPanel({
    store: DefaultStore,
    renderTo: 'grid-div',
    title:'Stuff',
    frame:true,
	bbar: PagingBar,
	tbar:[
            {text:'Search for insurer'},
            new Ext.Toolbar.Spacer(),
	    ProviderSearch
    ]
});

Here’s what the final control looks like. As you see, I searched for ‘ZA’, which returned only one result, which is now shown in the grid. Below, you can see that the original data set is still being stored in the paging toolbar’s data store, so just by clicking the refresh button, the first 100 rows in the table will be displayed again.

image