PDA

View Full Version : GridPanel dont displays scroll bars



cristianomaddog
8 Jul 2009, 11:03 AM
Hello everybody,

I have a very commom problem, as I could see in the forum.

When I load the store of a grid, with data thats overflows its height, the scrollbar doesn't appears.

The only way to make it work properly is to load the data to the Store when the grid's tab is the activate.
Another way to make the scrollbar to apear is to click on the sort options of the column.

I thing it is something related to the size that the grid have. If instead of reloading the store I set the GridPanel size again, it will make the scrollbar to apear. I guess it fires some method that draws the grid properly.

I am using the EXTJS 3.0.

I wrote an example, based on the array-grid example, to demonstrates what is happening:

html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Array Grid Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->

<script type="text/javascript" src="../../ext-all.js"></script>
<script type="text/javascript" src="my-array-grid.js"></script>

</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script>
<div id="grid-example"></div>
</body>
</html>js

/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){

// NOTE: This is an example showing simple state management. During development,
// it is generally best to disable state management as dynamically-generated ids
// can change across page loads, leading to unpredictable results. The developer
// should ensure that stable state ids are set for stateful components in real apps.
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
];

// example of custom renderer function
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}

// example of custom renderer function
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// create the data store
var store = new Ext.data.ArrayStore({
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
]
});
store.loadData(myData);

// create the Grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
{header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
{header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
{header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
],
stripeRows: true,
autoExpandColumn: 'company',
border: true,
height:350,
width:600
});

var fsOtherStuff = new Ext.form.FieldSet({
title: 'Other Stuff',
height: 40,
width: 622,
});

var fsGrid = new Ext.form.FieldSet({
title: 'My Field Set',
height: 374,
width: 622,
items: grid
});

var panelItens = new Ext.Panel({
title: 'Pannel',
bodyStyle:'padding:8px;',
border: true,
height: 496,
width: 640,
items: [fsOtherStuff, fsGrid]
});

var firstPanel = new Ext.Panel({
title: 'First',
bodyStyle:'padding:8px;',
height: 496,
width: 640,
border: true,
});

var tabPanel = new Ext.TabPanel({
activeTab:0,
deferredRender:false,
height: 516,
width: 644,
items: [firstPanel,panelItens],
tbar:['->',
{
text: 'Reload Data'
,
scope: this
,
handler: function() {
store.loadData(myData);
}
}]
});

tabPanel.render('grid-example');
});

I know that add a grid inside other containers is not a good thing to do, but I need to build a screen like these for my application.

Thanks for the help

cristianomaddog
8 Jul 2009, 12:29 PM
Reading the Ext.TabPanel (http://extjs.com/deploy/ext-3.0-rc1.1/docs/) API I discovered something:

Note: It is advisable to configure all child items of a TabPanel (and any Container which uses a CardLayout) with hideMode:'offsets' to avoid rendering errors in child components hidden using the CSS display style.

I added:
hideMode:'offsets' to all the children and it worked!

Now I just need to resize it to fit better!

Thanks

Animal
8 Jul 2009, 1:05 PM
var panelItens = new Ext.Panel({
title: 'Pannel',
bodyStyle:'padding:8px;',
border: true,
height: 496,
width: 640,
items: [fsOtherStuff, fsGrid]
});


How are you hoping that panelItems is going to size and position its two child items?

Give it a layout!

The docs DO actually emphasize te need to do this.

Animal
8 Jul 2009, 1:06 PM
And the size configs it won't have an effect.

A TabPanel uses layout: 'card' which sizes child items to fit exactly inside itself.

cristianomaddog
9 Jul 2009, 5:05 AM
Thanks for the Help Animal,

It helps a lot setting the layouts :)

I used the anchor layout.

Do you have a better suggestion?

Thanks for the help Animal!

Animal
9 Jul 2009, 5:46 AM
And how did you anchor thw two child Components?

I assume that you anchored them to be 100% of the Container width?

Animal
9 Jul 2009, 5:48 AM
var fsGrid = new Ext.form.FieldSet({
title: 'My Field Set',
height: 374,
width: 622,
items: grid
});


Again, explicit size. Why? Allow its parent Container's layout to size it!

But also, it has no layout, and so WILL NOT SIZE THE GRID!

cristianomaddog
9 Jul 2009, 6:15 AM
Hello Animal,

I thing I should have posted the modifications I did in the code.

I removed the explicit size definitions when possible.

I just keeped it to define the height of the components.

The modificated part are these:



var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
{header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
{header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
{header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
],
stripeRows: true,
autoExpandColumn: 'company',
border: true
});

var fsOtherStuff = new Ext.form.FieldSet({
title: 'Other Stuff',
height: 40,
anchor: '100%'
});

Var fsGrid = new Ext.form.FieldSet({
title: 'My Field Set',
layout: 'fit',
height: 390,
anchor: '100%',
items: grid
});

var panelItens = new Ext.Panel({
title: 'Pannel',
bodyStyle:'padding:8px;',
hideMode:'offsets',
layout: 'anchor',
border: true,
items: [fsOtherStuff, fsGrid]
});

var firstPanel = new Ext.Panel({
title: 'First',
bodyStyle:'padding:8px;',
layout: 'anchor',
hideMode:'offsets',
border: true,
});
I'm setting the height becouse i don't whant the component to become bigger then they are.

Now I'm triyng to fix the code of my application. If I do like I did in the example the bottom and right borders of the gridPanel doesn't show. It seems that they are under the fieldSet padding.

The difference is that in my application The tab pannel is child of a Window. I also added thys config to the fieldSet:

cls: 'myfieldsetBorder',whitch is defined in a CSS file

.myfieldsetBorder{
padding:5px;
margin-bottom:5px;
}

Animal
9 Jul 2009, 7:20 AM
var panelItens = new Ext.Panel({
title: 'Pannel',
bodyStyle:'padding:8px;',
hideMode:'offsets',
layout: 'anchor',
border: true,
items: [fsOtherStuff, fsGrid]
});


OK, I see. Looks OK.

You could experiment with layout: 'vbox' for this:



var panelItens = new Ext.Panel({
title: 'Pannel',
bodyStyle: 'padding:8px;',
hideMode :'offsets',
layout: 'vbox',
layoutConfig: {
stretch: true
},
border: true,
items: [Ext.apply(fsOtherStuff, {
flex: 0.5
}), Ext.apply(fsGrid, {
flex: 0.5
})
]
});


Each will be 0.5 of the height, but stretched to wit the width.

cristianomaddog
9 Jul 2009, 11:58 AM
Hello Animal

Thanks for the help!

Now using the VBox layout is mutch better! I have tried to use it once without sucess.

Now the example is working well but I'm still triyng to find the solution to my application.

Now the gridPanel's bottom and right border are not being displayed. I'll check if there is something different from the example.

Thanks for the help!

Animal
9 Jul 2009, 12:05 PM
Post code. You have overnested in a no layout Panel somewhere.

cristianomaddog
9 Jul 2009, 12:28 PM
So, here is the code:




var gridItensDoPedido = new Ext.grid.GridPanel({
store: dsGridDoPedido,
border: true,
sm: new Ext.grid.RowSelectionModel({
singleSelect:true
}),
enableColumnResize: false,
autoExpandColumn: 'descricao',
columns : [{...},{...}...],
listeners: {...}
}

});

var fsItensDoPedido = new Ext.form.FieldSet({
title: 'Itens do Pedido',
cls: 'myfieldsetBorder',
layout: 'fit',
items: gridItensDoPedido
});

var panelItens = new Ext.Panel({
title: 'Itens',
layout: 'vbox',
layoutConfig: {
align: 'stretch'
},
hideMode:'offsets',
border: false,
items: [Ext.apply(fsDadosItem, {
flex: 0,
margins: '4 8 0 8'
}), Ext.apply(fsItensDoPedido, {
flex: 1,
margins: '4 8 4 8'
})
],
tbar:['->',{...},{...}]
});

var tabPanel = new Ext.TabPanel({
activeTab:0,
deferredRender:false,
height:335,
//width:748,
border:false,
items: [panelPedido, panelItens, panelFechamento],
listeners:{...}
});

var formFSTotais = new Ext.form.FormPanel({
layout: 'absolute',
border: false,
items: [...]
});

var fsTotais = new Ext.form.FieldSet({
title: 'Totais',
cls: 'myfieldsetBorder',
layout: 'fit',
items: formFSTotais
});

var totalPanel = new Ext.Panel({
layout:'vbox',
layoutConfig: {
align: 'stretch'
},
//bodyStyle: 'background:gray',
border: false,
items: Ext.apply(fsTotais, {
flex: 0.15,
margins: '0 8 6 8'
})
});

var window = new Ext.Window({
title: 'Pedido',
width:762,
height:420,
resizable: true,
layout:'vbox',
layoutConfig: {
align: 'stretch'
},
closeAction: 'hide',
bodyStyle: 'background:white',
modal: true,
items: [Ext.apply(tabPanel, {
flex: 0
}), Ext.apply(totalPanel, {
flex: 0.15
})
]
});



PS. Everethyng is inside a window, I'm also having problems with the totalPanel, if is done in another way the fields and labels won't appear.
Now revising these part of the code I had the idea of using a hbox for the formFieldSetTotais insted of the absulute layout.

Thanks for the help.

Animal
9 Jul 2009, 1:01 PM
See, I just don';t know why you have wrapped this FieldSet in a Panel:



var fsTotais = new Ext.form.FieldSet({
title: 'Totais',
cls: 'myfieldsetBorder',
layout: 'fit',
items: formFSTotais
});

var totalPanel = new Ext.Panel({
layout:'vbox',
layoutConfig: {
align: 'stretch'
},
//bodyStyle: 'background:gray',
border: false,
items: Ext.apply(fsTotais, {
flex: 0.15,
margins: '0 8 6 8'
})
});



Why not just



var fsTotais = new Ext.form.FieldSet({
title: 'Totais',
cls: 'myfieldsetBorder',
layout: 'fit',
items: formFSTotais,
flex: 0.15,
margins: '0 8 6 8'
});


And then use that.

And why embed a FormPanel within it? Do you need to submit it? If not, just put the Fields directly into it.

cristianomaddog
10 Jul 2009, 3:18 AM
Thanks for the sugestion!

Now its like this:


var fsTotais = new Ext.form.FieldSet({
title: 'Totais',
cls: 'myfieldsetBorder',
layout: 'absolute',
items: [...]
});

var window = new Ext.Window({
title: 'Pedido',
width:762,
height:420,
resizable: true,
layout:'vbox',
layoutConfig: {
align: 'stretch'
},
closeAction: 'hide',
bodyStyle: 'background:white',
modal: true,
items: [Ext.apply(tabPanel, {
flex: 0
}), Ext.apply(fsTotais, {
flex: 0.15,
margins: '0 8 6 8'
})
]
});

But I still don't have right and bottom borders on the grid.

Condor
10 Jul 2009, 3:22 AM
Why did you switch from layout:'fit' to layout:'absolute' for fsTotais?

cristianomaddog
10 Jul 2009, 3:26 AM
Becouse I want to aling the Labels and TextFields side by side.

Before I had a formPanel with an absolute leyout inside the fieldSet. Now I removed the formPanel and added the items directly into the fieldSet, thats why I chanded the layout to absolute.

cristianomaddog
10 Jul 2009, 3:33 AM
Another thing,

The border appear normaly on IE.

When I try to define a Layout to the tabPanel this error occurs:

this.layout.setContainer is not a function

I leave it without a layout bacouse of it.

I'm trying to set the 'fit' layout.

Thanks for the help.

cristianomaddog
10 Jul 2009, 6:05 AM
I could make the borders of the grid appear, but not in a good way.

To make them appear I needed to remove the layout form the grid's field set and set a height to the gridPanel, so now the code looks like these:



var gridItensDoPedido = new Ext.grid.GridPanel({
store: dsGridDoPedido,
height: 145,
sm: new Ext.grid.RowSelectionModel({
singleSelect:true
}),
enableColumnResize: false,
autoExpandColumn: 'descricao',
columns : [...],
listeners: {...}
});

var fsItensDoPedido = new Ext.form.FieldSet({
title: 'Itens do Pedido',
cls: 'myfieldsetBorder',
items: gridItensDoPedido
});
I know It's not a good thing to leave a conteiner without a layout, but it is the way I found to make it work.

The problem is that it only works for Firefox now.

Any other suggestion?

Thanks for the help!