PDA

View Full Version : Async Loading a Dialog -- won't refresh



Bobafart
19 May 2007, 9:09 AM
I have successfully created an editable grid where, if you click a specific column, a Layout Dialog pops up and async loads data based on the item clicked.

It works for the first click.

The problem is, it only works for the first click. The second, third and all future clicks still load the Layout Dialog but the data from the first click remains displayed -- the future clicks don't refresh the data.

I am clearly doing something wrong .. but I am not sure what. No errors are outputted.



<script type="text/javascript">

Ext.onReady(function(){

// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: 'php/armyExt.php'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'item',
id: 'troopId'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'troopId', mapping: 'itemAttribute > troopID'},
'troopName', 'troopHP', 'troopSquad', 'troopSpecialty', 'troopRank', 'troopCustomize'
])
});

var cm = new Ext.grid.ColumnModel([
{header: "SoldierID", hidden: true, dataIndex: 'troopId'},
{header: "Soldier", width: 120, dataIndex: 'troopName'},
{header: "HP", width: 60, dataIndex: 'troopHP'},
{header: "Squad",
width: 80,
dataIndex: 'troopSquad',
editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({
typeAhead: true,
editable: false,
triggerAction: 'all',
transform:'troopSquad',
lazyRender:true
}))
},
{header: "Specialty", width: 100, dataIndex: 'troopSpecialty'},
{header: "Rank", width: 100, dataIndex: 'troopRank'},
{header: "Customize", width: 60, dataIndex: 'troopCustomize'}
]);
cm.defaultSortable = true;

// create the grid
var grid = new Ext.grid.EditorGrid('armyGrid', {
ds: ds,
cm: cm,
selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
enableColLock:false,
loadMask: true
});
grid.render();
ds.load();

// open the Unit Detailed Information Dialog if Activated
var dialog;
function openDialog(grid, rowIndex, colIndex, e) {

var selectionModel = grid.getSelectionModel();
var record = selectionModel.getSelected();
var troopId = record.data['troopId'];
var troopName = record.data['troopName'];
// alert(troopId, troopName);
if(colIndex==6){
alert('you clicked unit id: '+troopId);

if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new Ext.LayoutDialog("soldierDetails", {
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
proxyDrag: true,
west: {
split:true,
initialSize: 150,
minSize: 100,
maxSize: 250,
titlebar: true,
collapsible: true,
animate: true
},
center: {
autoScroll:true,
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true
}
});

dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);

var layout = dialog.getLayout();

var dialogCenter = Ext.get('center');
dialogCenter.load({
url: "php/detailedInfo.php",
params: {id: troopId}, // or a URL encoded string
// callback: yourFunction,
// scope: yourObject, //(optional scope)
discardUrl: false,
nocache: false,
text: "Loading...",
timeout: 30
// scripts: false
});

layout.beginUpdate();

layout.add('west', new Ext.ContentPanel('west', {title: 'Inventory'}));
layout.add('center', new Ext.ContentPanel('center', {title: 'Unit Profile'}));
// generate some other tabs
layout.add('center', new Ext.ContentPanel('statistics', {
autoCreate:true, title: 'Unit Statistics', background:true}));
layout.add('center', new Ext.ContentPanel('skills', {
autoCreate:true, title: 'Unit Skills', closable:true, background:true}));
layout.endUpdate();

}

dialog.show();
}

}

grid.addListener('cellclick', openDialog, this);


});

</script>


Here is a live demo (click on the "Customize" column for the layout dialog to appear):
http://gabbr.com/c/departmentofdefense/army/indexExt5.php

Any help would be greatly appreciated.

jsakalos
19 May 2007, 9:24 AM
Just a hint after the first glance...

You're lazy creating the dialog in the if(!dialog){...}. It seems to me that loading is in this if condition so executed only once when dialog is created.

Sorry if I'm wrong; I haven't analyzed the code in detail.

Bobafart
19 May 2007, 9:51 AM
Hmm.. this is interesting.

I got rid of the lazy creation of the dialog to see what would happen:

http://gabbr.com/c/departmentofdefense/army/indexExt5.php

Unfortunately, the more dialogs you open the worse the rendering problem becomes -- it does dynamically load the content with each new click -- but now the dialog render is a mess.

jsakalos
19 May 2007, 10:16 AM
I mean: Leave lazy creation as it is, but remove loading from the if.

Bobafart
19 May 2007, 12:30 PM
thanks for the reply.

the dialog gets created/loaded in the following function:




function openDialog(grid, rowIndex, colIndex, e) { ... }


and the addListener calls the function:



grid.addListener('cellclick', openDialog, this);


so everytime the addListener is activated the function is referenced and the dialog is loaded. therefore it stands that the dialog should be created new from each cell click.

Bobafart
19 May 2007, 3:56 PM
anyone else have any ideas on this pulease?

JasonMichael
19 May 2007, 10:02 PM
One way or another, you have to use reload on the datastore, to get the grid's datastore to refresh with new data. Its the only way that's worked for me, but I didn't have the grid inside a panel. What I would do is have your grid's datastore referenced globally through another loaded object.. for example, I use the 'example' class, included with the examples in example.js

I have at the top of example.js:

var grid = this



Then, after creating the grid and setting any properties, I save it to be referenced by other classes, like this:



Ext.example.grid = grid;
Ext.example.ds = ds; // get the datastore also!!!


So if I need to do a reload or something, at some point, such as after a click, from another completely different class or function, I simply reference the datastore by doing this:



Ext.example.ds.reload({ params:{start: 0,limit: 120,action:'getdata',displaycols:'id'});
Ext.example.grid.getView().refresh();


And voila.... works like a charm. Hope it works for you with some simple modification.
I had to use a solution like this because I wanted to exchange data from one grid to another, on a screen, without having drag and drop capabilities... wanted to click an "add" button to add a selected row from one grid to another, by putting it into the database, and refreshing the grid.

Bobafart
20 May 2007, 4:42 PM
Hi Jason,

thanks for the reply.

the problem I am having isn't with refreshing of the grid -- it is refreshing of the dialog box.

correct me if I am wrong but your idea is references refresh problems with the grid.

i require a solution that refreshes the data load in the layout dialog when it is activated with a subsequent click.

kato
20 May 2007, 5:21 PM
have you tried this so your dialog doesn't cache the loaded content?


var dialogCenter = Ext.get('center');

dialogCenter.load({
url: "php/detailedInfo.php",
params: {id: troopId},
discardUrl: false,
nocache: true,
text: "Loading...",
timeout: 30
});

JasonMichael
21 May 2007, 2:39 PM
Ugh, you're right Bobafart... hmm, I'll have to experiment with this, myself and see if I can get it to refresh.... I'll get back with you later.

Bobafart
21 May 2007, 2:42 PM
thanks for the reply.. I have tried that as well and it doesn't refresh the dialog

I have pasted the nocache: true code here:

http://gabbr.com/c/departmentofdefense/army/indexExt5.php

jack.slocum
22 May 2007, 7:42 PM
Your load code:

dialogCenter.load({...

is within the lazy dialog init:

if(!dialog) {...

which means it will only be executed the first time, when the dialog is created.

Move it to after the

if(!dialog){

block ends and it will load each time as expected.

x5150
23 May 2007, 4:59 PM
I'm trying to do the exact same thing as you bobafart. I modified your code and did what Jack said and put the panel.load code outside the if (!dialog). Also had to set scripts: true in your load config. And also Whatever url page ur loading it with, do not include the Ext script source file links. The dialog works opening and closing however many times with no rendering problems, although my content panel title does not show up and the panel looks misaligned to the dialog.


http://www.imagestation.com/picture/sraid225/pbb54f2350e3a28b7a8db914d566f9615/e96327c6.jpg



var dialog;
function edit() {
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new Ext.LayoutDialog("edit_dlg", {
title: "File Editor",
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
proxyDrag: true,

center: {

//autoScroll:true,
//tabPosition: 'top',
//closeOnTab: true,
//alwaysShowTabs: true
}
});

dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);

var layout = dialog.getLayout();
layout.beginUpdate();
layout.add('center', new Ext.ContentPanel('center', {title: 'Edit file'}));
layout.endUpdate();
}
var cpanel = Ext.get('center');
cpanel.load({
url: "#",
params: {gfrm:"8"}, // or a URL encoded string
fitContainer: true,
title: "Content Title",
// callback: yourFunction,
// scope: yourObject, //(optional scope)
discardUrl: false,
nocache: false,
text: "Loading...",
timeout: 30,
scripts: true
});
dialog.show();
}