plugin

Ext JS 4: Ext.ux.RowExpander Tweaks

I recently looked into a few issues we were experiencing with the Ext.ux.RowExpander plugin, which resulted in a few small tweaks to the plugin.

The setup: Grid with checkbox selection model using Ext.ux.RowExpander plugin.  An expanded row is a nested grid.  This was implemented following a pattern that can be found around the web about nesting grids in the expanded rowbody (http://stackoverflow.com/questions/8254113/nested-grid-with-extjs-4).

Issue 1: When the row expands to show the nested grid, the expanded row takes the full width of the grid, instead of aligning to the right of the checkbox column and the expand/collapse column.  This is actually logged as a bug, with pictures at http://www.sencha.com/forum/showthread.php?263231-Content-inside-RowExpander-doesn-t-take-all-width-of-a-row-if-grid-has-CheckboxModel.

The problem is that within the RowExpander plugin, the logic deciding the colspan of the expanded row body does not take into account any other grid features that might impact the columns.  I updated the plugin code to look at the parent grid selection model before determining how wide the colspan should be.

Issue 2: In my UI there is a search panel and then the grid with the search results.  The user can go through and expand various rows, but if the user runs a search again I want the search results to return and the grid refreshed with the results and all the rows collapsed.  What was happening was the grid was refreshed, all rows collapsed, but the expand/collapse icon was in the expanded state.

To fix this I added a method, clearExpanded to the RowExpander plugin.  It’s very straightforward and just clears out the rowsExpanded property the plugin maintains to track which rows are expanded.  Then, I listen for the refresh event on the parent grid’s view, and at that point, call clearExpanded on the plugin.  The refresh event handler on the grid view looks like this:

onMyGridRefresh: function() {
    var rowExpander = this.getSearchGrid().getPlugin('rowexpanderplugin');
    if (rowExpander) {
        rowExpander.clearExpanded();
    }
    this.destroyNestedGrids();
}

Remember, if you are creating nested grids in the manner described above, you need to destroy those grids manually!  Hence, the destroyNestedGrids() method in the code above.  It does a component query on the nested grid xtype and calls destroy on the returned components.

Solution: That’s great, where’s the code?

The updated plugin is at Gist https://gist.github.com/aghuddleston/25b19dfe10f7eb40e54c.   It’s a little long to directly include here.

Version Info: Ext JS 4.1.1

Ext JS 4: A Remote to Local QueryMode Hybrid ComboBox

I’ve needed this multiple times, an Ext JS combobox that is “remote”, but after loading all the combobox data on the first trigger click or when the user types in the combo field, it becomes “local”. Basically, I just don’t want the database hit unless the user actually uses the combobox.

Since this was my second or third time needing this, it’s time for a plugin. (gist 3659866)

And to use it, create the store for your combo box as having autoLoad set to false, and just put the plugin on the combobox.

// Define the model for a State
Ext.regModel('State', {
    fields: [
        {type: 'string', name: 'abbr'},
        {type: 'string', name: 'name'},
        {type: 'string', name: 'slogan'}
    ]
});

// The data store holding the states
var store = Ext.create('Ext.data.Store', {
    model: 'State',
	autoLoad: false,
	proxy: {
		type: 'ajax',
		url: '/states.json',
		reader: {
			type: 'json',
			root: 'states'
		}
	}
});

// Simple ComboBox using the data store
var simpleCombo = Ext.create('Ext.form.field.ComboBox', {
    fieldLabel: 'Select a single state',
    renderTo: 'simpleCombo',
    displayField: 'name',
    width: 500,
    labelWidth: 130,
    store: store,
    queryMode: 'remote',
    typeAhead: true,
    plugins: ['remotetolocalcombo']
});

Version Info: Ext JS 4.1.1

Ext JS 4 – Plugin to Add Icons to a Panel Header

Recently in my app I had multiple grid panels that needed icons added to the header, where the title goes. Instead of duplicating the code in multiple places, I created a simple plugin that I could use on any panel anywhere in my application.

Here is the code of the plugin. It’s really simple, but helps keep my grid/panel code cleaner. Gist can be found here Panel Header Extra Icons, version 1.

And example usage of a grid config with the plugin:

{
	xtype: 'grid',
	title: 'My Grid Title',
	columns : [
	],
	plugins: [{
		ptype: "headericons",
		headerButtons : [
			{
				xtype: 'button',
				iconCls: 'icon-page-white-excel',
				scope: this,
				handler: this.onExportToExcel
			}
		]
	}]
}

And here is a screenshot, that shows two different panel headers that I have. One with one icon and one with two.
Screenshot of Icons added to Panel Header

Updated 03/22/2013
Per comments, I updated the plugin a little bit. I also had my own changes that I hadn’t updated here… Here is the updated plugin. Feedback??? Gist can be found here https://gist.github.com/2770422.

Version Info: Ext JS 4.1.1