PDA

View Full Version : LoadMask in GridPanel not centering



sk199067
17 Aug 2009, 5:24 AM
After extensively searching the forums and trying out some of the suggestions in some of the threads, I still can't get the LoadMask of the GridPanel to center. The GridPanel belongs to a Window. My Window has a FormPanel in the north region and this GridPanel in the center region.

In Firefox 3.0.3, the LoadMask displays in the upper left hand corner of the GridPanel. In IE 7, the LoadMask displays down and to the right of center.

Does anyone one have a solution to this problem? Again, I've tried most of the suggestions in past posts, but all failed to resolve this problem.



Below is the javascript code to build the window and it's components:


Ext.onReady(function(){

Ext.QuickTips.init();

// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';

var button = Ext.get('show-btn');

button.on('click', function(){

var fiterPanel = new Ext.FormPanel({
layout: 'form',
margins:'3 3 3 3',
//labelAlign: 'right',
labelWidth: 125, // label settings here cascade unless overridden
url:'filter-response-grid-data.php',
frame:true,
region: 'north',
split: false,
title: 'Filter',
bodyStyle:'padding:3px 3px 0px',
collapsible: true,
width: 'auto',
autoHeight: true,
//defaults: {width: 230},
defaultType: 'textfield',
waitMsgTarget: true,

items: [{
fieldLabel: 'Template Code',
name: 'code',
anchor:'40%',
allowBlank:false
},{
fieldLabel: 'Template Description',
anchor:'75%',
name: 'description'
},{
xtype: 'radiogroup',
fieldLabel: 'Sort By',
columns: [125, 150],
items: [
{boxLabel: 'Template Code', name: 'sortBy', inputValue: 'code', checked: true},
{boxLabel: 'Template Description', name: 'sortBy', inputValue: 'description'}
]
},{
xtype: 'radiogroup',
fieldLabel: 'Sort Order',
columns: [100, 100],
items: [
{boxLabel: 'Ascending', name: 'sortOrder', inputValue: 'asc', checked: true},
{boxLabel: 'Descending', name: 'sortOrder', inputValue: 'desc'}
]
}
]
});

// add the reset and filter buttons to FromPanel
var resetBtn = fiterPanel.addButton({
text: 'Reset',
disabled:true,
handler: function() {
fiterPanel.getForm().reset();
}
});

var filterBtn = fiterPanel.addButton({
text: 'Filter',
disabled:true,
handler: function(){
if(fiterPanel.getForm().isValid()){
//Ext.Msg.alert('Submitted Values', 'The following will be sent to the server: <br />' +
// fiterPanel.getForm().getValues(true).replace(/&/g,', '));

filterBtn.disable();
resetBtn.disable();

fiterPanel.getForm().submit({
url:'filter-response-grid-data.php',
waitMsg:'Retrieving Data...',
success: function(form, action) {
//Ext.Msg.alert('Success', action.result.msg);
grid.getStore().loadData(action.result);
},
failure: function(form, action) {
switch (action.failureType) {
case Ext.form.Action.CLIENT_INVALID:
Ext.Msg.alert('Failure', 'Form fields may not be submitted with invalid values');
break;
case Ext.form.Action.CONNECT_FAILURE:
Ext.Msg.alert('Failure', 'Ajax communication failed');
break;
case Ext.form.Action.SERVER_INVALID:
Ext.Msg.alert('Failure', action.result.msg);
}
}
});
}
}
});




// renderer for change column
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;
}

// renderer for pct change column
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 grid data store
var store = new Ext.data.JsonStore({
autoDestroy: true,
autoLoad: true,
url: 'initial-grid-data.php',
storeId: 'gridStore',
root: 'data',
idProperty: 'company',
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.addListener('load', function() {
filterBtn.enable();
resetBtn.enable();
});

//store.load({});


// create the GridPanel
var grid = new Ext.grid.GridPanel({
region: 'center',
id: 'tgrid',
margins:'3 3 3 3',
viewConfig: { emptyText : 'No records found.' },
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',
height:350,
//width:600,
loadMask: {msg: 'Loading data, please wait...'},
title:'Templates'
});



// Create window and add FormPanel and GridPanel
var win = new Ext.Window({
title: 'Template Selection',
closable:true,
width: 600,
height: 500,
//border: false,
plain: true,
modal: true,
layout: 'border',

items: [grid, fiterPanel]
});

win.show(this);

});
});

17 Aug 2009, 5:26 AM
There is a timing issue between the gridpanel's render and the store's load.

To fix this, setup a 'render' event handler for the grid which calls the store's load method.

17 Aug 2009, 5:26 AM
... And please use code tags in the future.

sk199067
17 Aug 2009, 6:31 AM
Thanks for the quick response. My apologies on the lack of code tags; this is my first post.

Your suggestion is one that I have attempted before. What happens with your suggestion is that the LoadMask doesn't display at all in both IE and Firefox.

I modified the code to include the following when creating the GridPanel and set autoLoad to false when creating the store:



listeners: {
render: function(grid) {
store.load();
}
}

sk199067
17 Aug 2009, 6:39 AM
I also deferred the store.load



store.load.defer(20,store);


This makes the LoadMask appear again, but, again, it's not centering.

Condor
17 Aug 2009, 6:47 AM
I think the render event is still called to early. Try again with the afterlayout event:

listeners: {
afterlayout: {
fn: function(){
store.load();
},
single: true
}
}

17 Aug 2009, 6:49 AM
Condor is right. I guess on my machines, calling load on render works perfectly.

17 Aug 2009, 8:47 AM
I've got another question.

So, if I want call the store.load statement externally in another store's onLoad event, the "load" statement can no longer place in the render event. In this case what can I do?

Since one of my store's result is depending on another store's return, I cannot put the "store.load" in the render event :(

thanks in advance.

17 Aug 2009, 8:49 AM
yup. it would load twice.

17 Aug 2009, 8:50 AM
You could defer the creation of the grid panel until that store loads.

17 Aug 2009, 8:53 AM
I've got another question.

So, if I want call the store.load statement externally in another store's onLoad event, the "load" statement can no longer place in the render event. In this case what can I do?

Since one of my store's result is depending on another store's return, I cannot put the "store.load" in the render event :(

thanks in advance.

Btw, we prefer you ask questions in a separate thread.

sk199067
17 Aug 2009, 9:15 AM
Condor,

I tried your suggestion of using the afterLayout handler but it's not being called. I'm not getting any javascript errors, it's just not getting called.

sk199067
17 Aug 2009, 9:24 AM
OK, instead of using the afterlayout handler, I used the afterrender handler and this actually starting displaying the loadMask, but it's still off-centered (down and left of center) in both IE 7 and Firefox 3.0.3 this time.

file:///C:/DOCUME%7E1/pb04130/LOCALS%7E1/Temp/moz-screenshot.jpg

sk199067
20 Aug 2009, 4:37 AM
I just wanted to post some further findings that I came across on this topic.

The LoadMask centers just find when you render a GridPanel to a div tag, but things start to go awry with the LoadMask when the grid is placed in other components, in my case it's a Window set with border layout.

My window contains two components, a GridPanel in the center region and a FormPanel in the north region.

Since my window is using border layout the grid takes up any remaining space in the window that's not usedj. So setting the height and width on the GridPanel have no real impact to the size of the grid, from what I can tell, but what it does impact is the positioning of the LoadMask. I had to play around with the height & width of the GridPanel in order to center the LoadMask.

If anybody can shed some light on this behavior as to why the height & width of the GridPanel effects the positioning of the LoadMask when the GridPanel is embedded in another component using the BorderLayout, that would be great.

20 Aug 2009, 4:39 AM
The problem is that the grid panel is not rendered and completely layed out when the load mask is applied.

You just need to ensure that *after* the grid is rendered and layed out that the store's load method is fired.

sk199067
20 Aug 2009, 4:58 AM
Actually, I do wait to load the store until after the GridPanel is rendered by using the afterrender handler. This is the only way I can get the LoadMask to display in the GridPanel, but it wont center the LoadMask. I have to play around with the GridPanels height & width to center it. Adjusting the height & width of the GridPanel to center the LoadMask is odd. This is what has me puzzled, and would like to understand what's happening.



var grid = new Ext.grid.GridPanel({
region: 'center',
layout: 'fit',
id: 'tgrid',
margins:'3 3 3 3',
viewConfig: { emptyText : 'No records found.' },
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',
height:250,
width:580,
loadMask: {msg: 'Retrieving data, please wait...'},
title:'Templates',
listeners: {
afterrender: {
fn: function(grid, layout) {
store.load();
},
single: true
}
}

20 Aug 2009, 5:09 AM
give that a buffer, see if that helps.