PDA

View Full Version : [3.0] Ext.ux.plugins.ColumnAutoResizer (resize grid column to content width)



makana
22 Jul 2009, 7:04 AM
Hi everyone.

I wrote a plugin which you should add to a Ext.grid.GridPanel if you want the columns to resize to the maximum content width by doubleclicking on the grid header split (space between two columns).



Ext.ns('Ext.ux.plugins');
/**
* Plugin to autosize grid columns to the width of the widest content by dblclicking the header split
*/
Ext.ux.plugins.ColumnAutoResizer = Ext.extend(Ext.util.Observable, {
init: function(grid) {
this.grid = grid;
this.view = grid.getView();
this.cm = grid.getColumnModel();
grid.on('render', this.initEvents, this);
},
initEvents: function() {
// remove default headerclick listener
this.grid.un("headerclick", this.view.onHeaderClick, this.view);
// create an interceptor function to check whether the cursor is on split or not
var fn = this.view.onHeaderClick.createInterceptor(this.beforeHeaderClick, this);
// apply this as new headerclick listener
this.grid.on("headerclick", fn, this.view);
// add a listener for headerdblclick
this.grid.on("headerdblclick", this.onHeaderDblClick, this);
},
beforeHeaderClick: function() {
// return false if headers aren't enabled or the cursor is on header split
// this prevents sorting of the current column
return !(this.view.headerDisabled || this.isResizeCursor());
},
isResizeCursor: function() {
// return true if the cursor is on header split
return this.view.activeHd.style.cursor == (Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize');
},
// fires on headerdblclick
onHeaderDblClick: function(g, index, e) {
// stop and return if headers ar disabled, the cursor isn't on header split or the view has no rows
if (this.view.headerDisabled || !this.isResizeCursor() || !this.view.hasRows()) return;

e.stopEvent();
// stop editing in editor grid
g.stopEditing(true);

// check whether the cursor is on beginning of the next column
var hw = this.view.splitHandleWidth || 5;
var r = this.view.activeHdRegion;
var x = e.getPageX();
// if so, set index to previous column
if (x - r.left <= hw) index--;
// skip hidden columns
while (index > 0 && this.cm.isHidden(index)) index--;
// resize column to width of widest content
if (this.cm.isResizable(index)) this.resize(index);
},
// resize column width of the specified column to its widest content
resize: function(index) {
var r = this.view.getRows().length; // get rowcount
var c, w, s = 0;
// looping through the rows
for (var i = 0; i < r; i++) {
c = Ext.fly(this.view.getCell(i, index)); // get cell element
w = c.getPadding('lr'); // add padding to content width
c = c.first('.x-grid3-cell-inner'); // get inner cell element
// add margins, padding and textwidth to content width
w += c.getMargins('lr') + c.getPadding('lr') + c.getTextWidth(Ext.util.Format.stripTags(c.innerHTML));
// find maximum
s = Math.max(s, w);
}
// set the column width to maximum
this.view.onColumnSplitterMoved(index, s);
}
});


And this is, how you use it:


new Ext.grid.GridPanel({
plugins: [
new Ext.ux.plugins.ColumnAutoResizer()
],
...
});


Comments and improvements are welcome!

You can find an example in the zip. It's the array grid example, which I modified by adding the plugin.
Just unzip it in your ext directory. It gets stored in the examples/grid directory.

Greets
makana

galdaka
23 Jul 2009, 10:46 AM
Have you test with



autoFit: true;


Greetings,

makana
23 Jul 2009, 9:56 PM
What is autoFit?
Do you mean

forceFit: true

I updated the post above and set the last line to

this.view.onColumnSplitterMoved(index, s);
so it updates all column widths and handles events correctly.
It should work now with forceFit: true.

Condor
23 Jul 2009, 11:08 PM
Isn't using getTextWidth really slow?

This method (http://extjs.com/forum/showthread.php?p=272706#post272706) is probably faster.