ExtJS 5.0 – Using a custom component in a grid column

Sencha

You may or may not be familiar with ExtJS 5.0’s action column functionality. It basically lets you put a number of static images in a column with click handlers for performing certain tasks. Unfortunately their implementation is severely limiting in almost all aspects. I’ve decided that I *may* use it for grids that only have 1-3 possible actions but for anything more I prefer to stick a menu button in the column instead.

Problems with the stock implementation

These are the issues / quirks I’ve experienced trying to use the official actioncolumn implementation.

  1. No support for glyphs
    You have to use a static image file for the icon. Which is terrible, or implement glyphs yourself.
  2. Weirdness with row expanders and row editor
    Had a variety of strange styling quirks when trying to use them in conjunction with these.
  3. Not very useful for a large number of icons
    Grids that already are packed with data and don’t have much real estate for icons are at a huge disadvantage here.

The alternative

The way that I’ve decided to continue with my action columns going forward is to create a menu button component in the renderer for the column instead of using the official actioncolumn implementation.

Your standard grid should have a columns property that looks something like this.
columns: {
items: [{
text: 'Column 1', dataIndex: 'col1', flex: 1, hidden: false
}, {
text: 'Column 2', dataIndex: 'col2', flex: 1, hidden: false
}]
}

If we modify this to include a new action column with a renderer we can add the new component.

columns: {
items: [{
text: 'Column 1', dataIndex: 'col1', flex: 1, hidden: false
}, {
text: 'Column 2', dataIndex: 'col2', flex: 1, hidden: false
}, {
text: 'Action', flex: 1, hidden: false, sortable: false,
renderer: function(value) {
var id = Ext.id();
setTimeout(function() {
var button = Ext.create('Ext.button.Button', {
glyph: 0xf013,
menu: [{
//glyph if you want it
text: 'Menu Item 1',
handler: function(grid, rowIndex, colIndex) {
var row = Ext.getCmp("").getSelectionModel().getSelection().shift().getData();
// row will have all of the rows data for your usage
}
}]
});
if (Ext.get(id)) {
button.render(Ext.get(id));
}
}, 1);
return '

';
}
}]
}

In the above code you will see that we generate an ext id to assign to our new button object. We then wrap everything in a setTimeout so that it is ever so slightly delayed in it’s creation. Then we create the button object itself and if our id exists (it should exist in the page because of the delay we used) it calls render on the button. Since it’s a renderer all we return back is a simple div with the generated id. So we’re essentially echoing out an empty div with an id and at the same time queuing up the code that will render the button for each row.

There is one thing that I have found so far to keep in mind before choosing this method. The RowEditor does not play nice with this particular method, it has styling issues (the button is cut off and not centered). I would only use it on grids that do not have the RowEditor plugin.

Posted in Web Application Development Tagged with: , , , , , , , , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*