PDA

View Full Version : GridPanel: autoadjust column width to its content on headerdblclick



makana
29 Sep 2008, 2:07 AM
I want to autoadjust the column width in grid panels by double clicking between the two adjacent header cells (like you know from excel or windows explorer). In Ext, the cursor turns into a "col-resize", but there isn't a function, that provides autosizing by default.
Using only the "headerdblclick" event from Ext.grid.GridPanel to fire a custum function doesn't work, because there are two single click events, too, which respectively cause sorting of the data.
To prevent this, I overrode the onHeaderClick function in Ext.grid.GridView and added a onHeaderDblClick function that provides autosizing for the clicked column in all of my grids by default. The new width becomes the width of the largest content in the column (including margins, paddings...).
It's only testet and works well in FF3 and IE6 on WinXP.



Ext.override(Ext.grid.GridView, {
resizeIndex: -1,
// private
initUI : function(grid){
grid.on("headerclick", this.onHeaderClick, this);

// handle dblclick on header cells
grid.on("headerdblclick", this.onHeaderDblClick, this);

if(grid.trackMouseOver){
grid.on("mouseover", this.onRowOver, this);
grid.on("mouseout", this.onRowOut, this);
}
},

// override normal click handler on header cells
onHeaderClick : function(g, index, e){
if(this.headersDisabled){
return;
}
// reset
this.resizeIndex = -1;

// check if mouse is over the splitter
var resizeCursor = this.activeHd.style.cursor;
resizeCursor = (Ext.isAir && resizeCursor == 'move') || (Ext.isSafari && (resizeCursor == 'e-resize' || resizeCursor == 'w-resize')) || resizeCursor == 'col-resize';


if (resizeCursor) {
g.stopEditing(true);

this.resizeIndex = index;
// if cursor in next column header, use index of previous column
var cell = Ext.fly(g.getView().getHeaderCell(index));
if ((this.cm.getColumnWidth(index) / 2) + cell.getLeft() > e.getPageX()) this.resizeIndex--;
// ignore hidden columns
while (this.cm.isHidden(this.resizeIndex)) {
this.resizeIndex--;
if (this.resizeIndex < 0) break;
}
// handle normal header click (original function)
} else if (this.cm.isSortable(index)) {
g.stopEditing(true);
g.store.sort(this.cm.getDataIndex(index));
}
return;
},
// handle dblclick on header cells
onHeaderDblClick: function(g, index, e) {
e.stopEvent();
// check if resizeIndex exists (mouse over splitter)
if (this.resizeIndex >= 0 && g.getStore().getTotalCount() > 0) {
var sz = 0;
var el, w;
// check content width of each row
for (i = 0; i < g.getStore().getTotalCount(); i++) {
el = Ext.fly(this.getCell(i, this.resizeIndex)); // cell element <td>
w = el.getWidth(); // get cell width
el = el.first('div.x-grid3-cell-inner'); // inner cell element <td><div>
w -= el.getWidth(true); // subtract inner cell width, content only (keep borders, margins, paddings... from cell and inner cell elements)
w += el.getTextWidth(Ext.util.Format.stripTags(el.innerHTML)); // add width of content
if (w > sz) sz = w; // use biggest value
}
// set biggest value as width of the column
g.getColumnModel().setColumnWidth(this.resizeIndex, sz);
g.fireEvent('columnresize', this.resizeIndex, sz);
}
}

});

mjlecomte
29 Sep 2008, 5:29 AM
http://extjs.com/learn/Ext_FAQ_Grid#.22Auto_size.22_columns_to_the_largest_element_in_them

makana
29 Sep 2008, 7:01 AM
Ok, thanks! :) I have not found this before.
This is an easier way to calculate and set the width of a column.
But my main problem was to fire such an autoSizeColumn function on a headerdblclick event (if the cursor is between two columns and the cursor has turned into a "col-resize", same as in excel or windows explorer) and not on load event or so on...
By default clicking on a header causes sorting of the clicked column. This also appears if the cursor is between two columns and has turned into such a "col-resize". Therfore double clicking a header causes double sorting of the column :-?
With my overridden onHeaderClick function I want to prevent this behaviour. If there is an easier way, too, I would be very glad to have other suggestions!!

mjlecomte
29 Sep 2008, 7:13 AM
I understand better your goals...always good to update your first post with relevant info if the thread gets longer.

One of the problems with click vs. doubleclick is you have to deal with the fact that double clicks are inherently two single clicks. One way you might circumvent the problem might be to qualify the click behavior with the addition of a shift, control, alt key, etc.

You also might be interested in this:
http://extjs.com/blog/2008/09/23/keyboard-handling/

makana
29 Sep 2008, 7:49 AM
Thanks.
Key mapping is an alternative solution, but I'm used to do auto sizing just with one double click (and most of the other users are, too), so I tried to do this without key mapping.
I'll update my first post to better represent my goals. Sorry for that little information.

LoBe
29 Nov 2008, 1:51 PM
Thank you for posting it!