View Full Version : GridPanel-Relative column width

22 Apr 2014, 6:30 AM
I have two gridpanels in my ‘fieldset’ and both displays the marks of students for a test.
Chris attended all the exams whereas Raj was not able to attend Chemistry and English (the dotted lines)
After the render, Raj should not be displaying the columns for the exams which he didn’t appear for. Doing so, the column width should still be the same and should match the column width of Chris’s results. It should not stretch to the end.

Desired Result

Current One


I declared both the panels with the same columns and dataIndex and used hidden: true property on the columns I wanted to hide but then it stretched the displayed columns to fit the size of the fieldset.

Please help.

22 Apr 2014, 7:03 AM
You're probably using flex on some columns. Try to use absolute widths on all columns

22 Apr 2014, 7:59 AM

Are you suggesting a fixed width to the columns inside the grid?

If we give a fixed width to the columns won't it create problems when the page is minimized or when the page is viewed in different resolutions?

22 Apr 2014, 12:30 PM
The different resolutions should not be problem. flex in grid column configuration causes that that column expands to the maximal possible width.

22 Apr 2014, 12:51 PM
The fieldset is part of the main layout in my page, show below

Right now, my code looks like this

xtype : 'fieldset',
title : 'Batch Summary',
layout : {
type : 'fit'
items : [

I added static column width to each columns inside the grid, but part of the grid is getting hidden when the browser is shrinked or the resolution is changed.

On what basis I should be arriving upon the value for each column width inside the datagrid?

Not sure if I am doing something wrong.

22 Apr 2014, 10:57 PM
As I understand it you're looking to use flex widths on the first grid and then use the calculated widths for the other grid?

I think you'll have to listen for a suitable layout event on the first grid and then the set fixed widths on the columns. You can't automatically pass on layout-derived values from one grid to another.

You're also misusing fit layout. I suspect you want vbox.

22 Apr 2014, 11:15 PM
I'm looking at your sketch and thinking if you really need grids. If you're gonna to have just a header row plus one-row of marks without need of columns D&D, sorting, editing, etc., you can very well go with a simple XTemplate.

23 Apr 2014, 11:03 AM
Thank you Skirtle and Saki for the pointers.

@Skirtle, can you please give me more details about the layout event. Is it same as listening to the render function?
Also, how can I set the same width to all the columns of a gridpanel. Is there something like setAllWidth() ;) ?

23 Apr 2014, 12:15 PM
I assume you mean listening to the render event, it isn't possible to listen to the render function. Anyway, rendering isn't the right stage for this.

Rendering is creating the HTML markup and only happens once for each component.

Layout is sizing and positioning for the component. It can happen multiple times, whenever sizes or positions need to change.

I suspect the afterlayout event would be your best bet.

To set the width you'd just call setWidth on each column. You can grab all the columns with a CQ down from the grid. You should suspend layouts while you're doing it so that the second grid only performs a single layout.

23 Apr 2014, 1:47 PM
On the second grid, I am going to add the following listener for afterlayout

listeners: {
afterlayout: function(me, layout, eOpts) {
var parentWidth = //get the width of the first gridpanel component
var kidColWidth = //calculate the column width for the second gridpanel from the parentWidth

var cols = //find all the columns of the secind grid
for (var i=0;i<cols.length;i++){
//???not sure how to stop the event propagation here

Am I doing it the right way? Can you please explain the part where you mentioned about suspend layouts?

23 Apr 2014, 9:53 PM
Hmmm, not really.

It's the first grid's afterlayout that you should be listening to. The point is that after the layout has run its columns will be the correct width, so you can read them off and copy them to the second grid. What you've got may also work but its more of a coincidence, because all the afterlayout events will fire at roughly the same time.

Suspending layouts is a standard technique. Layouts run automatically so when making batch updates like this its necessary to prevent them running till the end.


// loop through columns and set widths


24 Apr 2014, 5:25 AM

I put the logic on the of the afterlayout event of the first grid. But, the page is taking a whole lot of time to load and also after a while it throws the following exception in my console.
Uncaught RangeError: Maximum call stack size exceeded

I think the afterlayout event is getting called recursively in the loop. Is there a way to prevent this from happening?

24 Apr 2014, 5:49 AM
Yeah, that makes sense. It'll depend on exactly how you have the other layouts configured, configuring those column widths shouldn't really be causing a layout on the other grid. My guess is you're lacking some configuration for the parent layout so it's doing some auto or shrink-wrap sizing based on the grid sizes, which will need to re-layout after the grids layout. The ExtJS page analyser may be able to give you some indication where the problem is.

The boxready event is another possibility. It'll only fire the first time the layouts run. Problem with that is you probably want to update the column widths on every layout.

Possibly the easiest way is just to set a flag in your listener that ensures it doesn't try to set the widths recursively.

if (!this.settingWidths) {
this.settingWidths = true;

// suspend layouts, set widths, resume layouts

this.settingWidths = false;

24 Apr 2014, 7:07 AM
That worked!!! =D>

Thanks a lot skirtle