PDA

View Full Version : UpdateManager.formUpdate



Animal
15 Feb 2007, 4:35 AM
The version at http://www.jackslocum.com/deploy/ext-1.0-alpha/source/UpdateManager.js still has the problem where the upload success handler is not fired because YAHOO use a different property of the callback object for file upload success.

My override looks like this:



YAHOO.ext.UpdateManager.prototype.formUpdate = function(form, url, reset, userCallback){
formEl = YAHOO.util.Dom.get(form);
if(this.beforeUpdate.fireDirect(this.el, formEl, url) !== false){
this.showLoading();
var isUpload = false;
var enctype = formEl.getAttribute('enctype');
if(enctype && enctype.toLowerCase() == 'multipart/form-data'){
isUpload = true;
}
if(typeof url == 'function'){
url = url();
}
if(typeof params == 'function'){
params = params();
}
url = url || formEl.action;
var callback = {
failure: this.failureDelegate,
timeout: (this.timeout*1000),
argument: {'url': url, 'form': formEl, 'callback': userCallback, 'reset': reset}
};
callback[isUpload ? "upload" : "success"] = this.successDelegate;
YAHOO.util.Connect.setForm(form, isUpload, this.sslBlankUrl);
this.transaction = YAHOO.util.Connect.asyncRequest('POST', url, callback);
}
};

jack.slocum
15 Feb 2007, 4:41 AM
Here's my latest code, is the fix in there? (I'm not sure which one you are refering to)


formUpdate : function(form, url, reset, callback){
if(this.fireEvent('beforeupdate', this.el, form, url) !== false){
formEl = YAHOO.util.Dom.get(form);
if(typeof url == 'function'){
url = url.call(this);
}
if(typeof params == 'function'){
params = params();
}
url = url || formEl.action;
var cb = {
success: this.successDelegate,
failure: this.failureDelegate,
timeout: (this.timeout*1000),
argument: {'url': url, 'form': formEl, 'callback': callback, 'reset': reset}
};
var isUpload = false;
var enctype = formEl.getAttribute('enctype');
if(enctype && enctype.toLowerCase() == 'multipart/form-data'){
isUpload = true;
cb.upload = this.successDelegate;
}
YAHOO.util.Connect.setForm(form, isUpload, this.sslBlankUrl);
this.transaction = YAHOO.util.Connect.asyncRequest('POST', url, cb);
this.showLoading.defer(1, this);
}
}

jack.slocum
15 Feb 2007, 4:42 AM
BTW, moving showLoading to the end prevents internal forms from getting blown away before getting processed.

Animal
15 Feb 2007, 4:57 AM
No. The problem is that when uploading, the callback that YAHOO places into the iframe's onload calls calback.upload() not callback.success()

So you need to set the success handler up using array notation and a conditional index depending on whether isUpload is set.

Animal
15 Feb 2007, 5:02 AM
Also, unlike most Ext methods, that takes an HtmlElement or a Strinng.

I think for consistency, it should take an Ext.Element too usnig "formEl = getEl(form)", store the Element in "formEl", and use "formEl.dom" when a DOM node is required.

Animal
16 Feb 2007, 8:21 AM
OK, I missed:




cb.upload = this.successDelegate;



But there's still a missing "params" parameter... and it might be an object needing to be converted to a string

And we should be able to pass an object containing the parameters just like update.

The end result will be almost identical to update.

Perhaps the two could be merged to avoid this kind of divergence.

They could be merged into an doUpdate() method and have both update and formUpdate create a config object that the unified doUpdate operates upon.

Animal
16 Feb 2007, 8:50 AM
This?



formUpdate: function(form, url, reset, callback, params) {
var formEl = getEl(form);
if(this.fireEvent('beforeupdate', this.el, this.formEl, url, params) !== false){
var enctype = formEl.getAttribute('enctype');
this.doUpdate((typeof url == 'object') ? url : {
form: formEl.dom,
isUpload: (enctype && enctype.toLowerCase() == 'multipart/form-data'),
url: cfg.url || formEl.dom.action,
reset: reset,
callback: callback,
params: params
});
}
},

update: function(url, params, callback, discardUrl) {
if(this.fireEvent('beforeupdate', this.el, url, params) !== false){
this.doUpdate((typeof url == 'object') ? url : {
url: url,
params: params,
callback: callback,
discardUrl: discardUrl
});
}
},

doUpdate : function(cfg) {
if(cfg.callback && cfg.scope){
cfg.callback = callback.createDelegate(cfg.scope);
}
if(typeof cfg.nocache != 'undefined'){this.disableCaching = cfg.nocache};
if(typeof cfg.text != 'undefined'){this.indicatorText = '<div class="loading-indicator">'+cfg.text+'</div>'};
if(typeof cfg.scripts != 'undefined'){this.loadScripts = cfg.scripts};
if(typeof cfg.timeout != 'undefined'){this.timeout = cfg.timeout};
if(!cfg.discardUrl){
this.defaultUrl = cfg.url;
}
if(typeof cfg.url == 'function'){
cfg.url = cfg.url.call(this);
}
if(typeof cfg.params == 'function'){
cfg.params = cfg.params();
}
if(cfg.params && typeof cfg.params != 'string'){ // must be object
var buf = [];
for(var key in cfg.params){
if(typeof cfg.params[key] != 'function'){
buf.push(encodeURIComponent(key), '=', encodeURIComponent(cfg.params[key]), '&');
}
}
delete buf[buf.length-1];
cfg.params = buf.join('');
}
var cb = {
success: this.successDelegate,
failure: this.failureDelegate,
timeout: (this.timeout*1000),
argument: {'url': cfg.url, 'form': cfg.form, 'callback': cfg.callback, 'reset': cfg.reset}
};
if (cfg.form) {
YAHOO.util.Connect.setForm(cfg.form, cfg.isUpload, this.sslBlankUrl);
if (cfg.isUpload) {
cb.upload = this.successDelegate;
}
}
this.transaction = YAHOO.util.Connect.asyncRequest(cfg.method || "POST", cfg.url, cb, cfg.params);
this.showLoading.defer(1, this);
}
}

jack.slocum
16 Feb 2007, 9:18 AM
Did phpbb mess up your post? Just glancing at it I can see a few problems.

Unless it's rock solid (did you do some testing in your app?) I would prefer to avoid too many changes so close to a release (even if it is a beta). If you say it's rock solid, I will drop it in, otherwise we should wait for beta 2.

Animal
16 Feb 2007, 11:48 PM
Nooooo not rock solid! It's last thing on a Friday night code! I'll have to test it in all my application situations on Monday. I just posted it as an idea of the of unification of the two methods.

If you think the idea is good, I'll develop it to be a little more efficient, and actually work!

jack.slocum
17 Feb 2007, 12:33 AM
I like the idea for sure. Let me know when it is ready. We will have to pop it in for beta 2.

Animal
19 Feb 2007, 4:22 AM
OK, here's the version I've been running with this morning:



formUpdate: function(form, url, reset, callback, params) {
var formEl = getEl(form);
if(this.fireEvent('beforeupdate', this.el, this.formEl, url, params) !== false) {
this.doUpdate((typeof url == 'object') ? url : {
form: formEl,
discardUrl: true, // retain old behaviour
url: url || formEl.dom.action,
reset: reset,
callback: callback,
params: params
});
}
},

update: function(url, params, callback, discardUrl) {
if(this.fireEvent('beforeupdate', this.el, url, params) !== false){
this.doUpdate((typeof url == 'object') ? url : {
url: url,
params: params,
callback: callback,
discardUrl: discardUrl
});
}
},

/** @private */
doUpdate : function(cfg) {
if (typeof cfg.nocache != 'undefined') {this.disableCaching = cfg.nocache};
if (typeof cfg.text != 'undefined') {this.indicatorText = '<div class="loading-indicator">'+cfg.text+'</div>'};
if (typeof cfg.scripts != 'undefined') {this.loadScripts = cfg.scripts};
if (typeof cfg.timeout != 'undefined') {this.timeout = cfg.timeout};

if (!cfg.discardUrl) {this.defaultUrl = cfg.url;}
var url = (typeof cfg.url == 'function') ? cfg.url.call(this) : cfg.url;
var params = (typeof cfg.params == 'function') ? cfg.params() : cfg.params;
var callback = cfg.scope ? cfg.callback.createDelegate(cfg.scope) : cfg.callback;
if(params && typeof params != 'string') { // must be object
var buf = [];
for(var key in params){
if(typeof params[key] == 'function') {
buf.push(encodeURIComponent(key), '=', encodeURIComponent(params[key]()), '&'); // Should this be called with .call(this)?
} else {
buf.push(encodeURIComponent(key), '=', encodeURIComponent(params[key]), '&');
}
}
delete buf[buf.length-1];
params = buf.join('');
}
var cb = {
success: this.successDelegate,
failure: this.failureDelegate,
timeout: (this.timeout*1000),
argument: {'url': url, 'callback': callback, 'reset': cfg.reset, 'params': params}
};
if (cfg.form) { // form will always be an Ext.Element when called through formUpdate
cb.form = cfg.form.dom;
var enctype = cfg.form.getAttribute('enctype');
var isUpload = (enctype && enctype.toLowerCase() == 'multipart/form-data')
YAHOO.util.Connect.setForm(cfg.form.dom, isUpload, this.sslBlankUrl);
if (isUpload) {
cb.upload = this.successDelegate;
}
}
this.transaction = YAHOO.util.Connect.asyncRequest(cfg.method || "POST", url, cb, params);
this.showLoading.defer(1, this);
}

jack.slocum
19 Feb 2007, 4:27 AM
I would have loved to get this in, but I think it should have round of testing. Lets target the second pre-release (next week?).