PDA

View Full Version : Grid auto-size column?



tmancini
25 Jan 2016, 1:49 PM
I don't love the idea of having to hard code column widths due to variable data lengths. I also don't love the look of filling the grid entirely since it creates a lot of wasted space for each column. Is there a simple way to have columns auto-size based on the data contained in the columns? The header should also be taken into account.

gishmo
26 Jan 2016, 2:06 AM
One way that works is, to define a suitable size for every column and define one column as the one which could be auto expanded using:


grid.getView()
.setAutoExpandColumn([yourColumn])

Don't konw if there is another way to do this.

ktp
17 Oct 2016, 12:25 AM
I know this comes a little bit late....

I tried this on ExtJS 4.2 with my originally posted code. For ExtJS 6.2 I cleaned it up a little bit, separated the code for autosizing columns and autogrowing the last column to fit the view width and made autosizing buffered. Seems to work nice. Below is the original code for 4.2 and below that the code for 6.2:

Code for 4.2:


Ext.override(Ext.grid.Panel,
{
autoSizeColumns: function()
{
var grid = this;
if (grid.reconfiguring) return;
var gridview = grid.view;
var visCols = gridview.getHeaderCt().getVisibleGridColumns();
var visCount = visCols.length;
var w = gridview.getHeaderCt().getWidth();
if (gridview.getHeight() <= parseFloat(gridview.getEl().dom.children[0].scrollHeight))
{
w = w - Ext.getScrollbarSize().width;
}

Ext.each(visCols, function(column)
{
var colNum = column.getVisibleIndex() + 1;
column.autoSize();
// fix for empty columns autoSize() making column too small for header text
var pad = column.textEl.getX() - column.getX();
var minw = column.textEl.getComputedWidth()+column.triggerEl.getComputedWidth()+(pad*2);
if (column.maxGrow)
{
if (column.maxGrow < column.getWidth()) column.setWidth(column.maxGrow);
}
if (column.getWidth() < minw) column.setWidth(minw);
if (colNum == visCount && w > column.getWidth()) column.setWidth(w);
w = w - column.getWidth();
})

gridview.updateLayout();
},

initComponent: function()
{
var me = this;

me.callParent(arguments);

var view = me.getView();

// resize headers on refresh and resize
me.mon(view, {
//refresh: function(){Ext.defer(me.autoSizeColumns, 100, me)},
refresh: me.autoSizeColumns,
itemupdate: me.autoSizeColumns,
scope: me
});

// resize headers on column changes
me.mon(me, {
columnmove: me.autoSizeColumns,
columnshow: me.autoSizeColumns,
columnhide: me.autoSizeColumns,
groupchange: me.autoSizeColumns,
sortchange: me.autoSizeColumns,
scope: me
});
},

onViewReady: function()
{
this.fireEvent('viewready', this);

var me = this;
var view = me.getView();

// resize headers on refresh and resize
me.mon(view, {
resize: me.autoSizeColumns,
scope: me
});
}
});


Cleaned up Code for 6.2 (could work for lower Versions - did not test it though)


Ext.override(Ext.view.Table,
{
// override for auto grow on last column
autoSizeColumn: function(header) {
if (Ext.isNumber(header)) {
header = this.getGridColumns()[header];
}
if (header) {
if (header.isGroupHeader) {
header.autoSize();
return;
}
delete header.flex;

// store value for later use in iteration for auto grow last column
header.computedMaxWidth = this.getMaxContentWidth(header);

// get view width and respect scrollbar
var w = this.getHeaderCt().getWidth();
if (this.getHeight() <= parseFloat(this.getEl().dom.children[0].scrollHeight)){
w = w - Ext.getScrollbarSize().width;
}

// get visible columns info
var visCols = this.getHeaderCt().getVisibleGridColumns();
var visCount = visCols.length;
var headerNum = header.getVisibleIndex() + 1;

// only used for auto grow last column
if (w > 0 && headerNum === visCount)
{
// var for addition of column widths
var wcols = 0;

// iterate trough visible columns
Ext.each(visCols, function(column)
{
// index of iterated column
var colNum = column.getVisibleIndex() + 1;
if (colNum != visCount) wcols = wcols + column.computedMaxWidth;
});

// only grow last column if there is space left in the view
if (w - wcols > header.computedMaxWidth) header.computedMaxWidth = w - wcols;
}

// set width for column
header.setWidth(header.computedMaxWidth);
}
}
});


Ext.override(Ext.grid.Panel,
{
// override for binding autosize columns on misc events after view is ready
// onViewReady is defined in parent, so call parent and add own code
onViewReady: function()
{
var me = this;

me.callParent(arguments);

var view = me.getView();

// new buffered function for auto size of all visible columns
me.autoSizeColumns = Ext.Function.createBuffered(function()
{
var grid = this;
if (grid.reconfiguring) return;

var visCols = grid.view.getHeaderCt().getVisibleGridColumns();

Ext.each(visCols, function(column)
{
// dirty fix for column headersize too small
column.textEl.setStyle('padding-right', '6px');
// autosize
column.autoSize();
});
}, 200, me);

// resize headers on refresh and resize
me.mon(view, {
resize: function(){me.autoSizeColumns()},
refresh: function(){me.autoSizeColumns()},
itemupdate: function(){me.autoSizeColumns()},
scope: me
});

// resize headers on column changes
me.mon(me, {
columnmove: function(){me.autoSizeColumns()},
columnshow: function(){me.autoSizeColumns()},
columnhide: function(){me.autoSizeColumns()},
groupchange: function(){me.autoSizeColumns()},
sortchange: function(){me.autoSizeColumns()},
scope: me
});
}
});

thanhquisencha
22 Feb 2017, 8:38 PM
I agree with your comments :)