PDA

View Full Version : UpdateManager.updateForm callback when loadScripts=true



dbadke
12 Feb 2007, 11:13 AM
I had set
YAHOO.ext.UpdateManager.defaults.loadScripts = true; before creating any layouts.

One of my content panels has a form, which gets updated with:


collectBody.getUpdateManager().formUpdate(collectForm, url, false, this.saveCollectEnd.createDelegate(this));

If the XHR fails (eg: the URL is wrong and returns a 404), the callback function is called, with requestOK=false. If it succeeds, the callback is not called at all. Remove the loadScripts=true line, and the callback is called on success, with requestOK=true.

The problem seems to be in UpdateManager.js (processSuccess), where the callback is handled differently depending on loadScripts:


if(this.loadScripts){
this.renderer.render(this.el, response, this,
this.updateComplete.createDelegate(this, [response]));
}else{
this.renderer.render(this.el, response, this);
this.updateComplete(response);
}

I'm not sure why this fails, but I can confidently say that it does!

Animal
13 Feb 2007, 1:49 AM
It's not a file upload submit is it? Because the callback doesn't get called there - that's a known problem.

It could be that the scripts that are being evaluated are throwing errors. Step into the render function and see what's happening.

dbadke
13 Feb 2007, 8:51 AM
Not a file upload, just a call to a small PHP module. In this case there is no Javascript in the response, just an HTML fragment.

After some digging, I have found the solution.

If loadScripts=true, the callback function is just passed along to the UpdateManager.renderer, not executed directly as it is when loadScripts=false. If a custom renderer has been set, it is responsible for passing the callback along to the El.update call. I have just noticed (:oops:) in the documentation for BasicRenderer that this is implied, but I missed it.

So a custom renderer for an element that needs a callback and/or script processing has to be something like this one from my application:


this.render = function(el, response, updateMgr, callback) {
var packet = parseJSON(response.responseText);
if (packet) {
getEl('collect-body').update(packet.data, updateMgr.loadScripts, callback);
getEl('collect-status').update(packet.status, updateMgr.loadScripts, callback);
}
};

If the callback is not passed to El.update, it is never called. If loadScripts=true is not passed, scripts are not processed. BasicRenderer always does this and any custom renderer also has to do it.

Animal
13 Feb 2007, 9:08 AM
Heh! Well found.

Yes, perhaps this should be highlighted. That was the structure I came up with when collaborating with Jack on having the UpdateManager evaluate scripts. I wanted to have the callback called after the scripts have been evaluated, so that the page author could rely on things being set up in the content when his callback runs.

I'll add something to the Wiki since I was involved in this complex area...