I always learn a lot reading other people’s code. (Admittedly the lesson is sometimes to run in the opposite direction as fast as possible.) This morning I was looking at Basecamp’s file upload interface which is lovely and clean.
In each file’s form’s onsubmit handler I noticed a call to closeKeepAlive(). Here’s what it looks like:
/* A pretty little hack to make uploads not hang in Safari. Just call this
* immediately before the upload is submitted. This does an Ajax call to
* the server, which returns an empty document with the "Connection: close"
* header, telling Safari to close the active connection. A hack, but
* effective. */
function closeKeepAlive() {
if (/AppleWebKit|MSIE/.test(navigator.userAgent)) {
new Ajax.Request("/ping/close", { asynchronous:false });
}
}
Nice.
I installed this workaround and I noticed that I was still seeing the Safari/Webkit 'hang problem'. After a bit of investigation I think I've found the problem.
I had a disable_with value set on my submit tag which itself calls this.form.submit() which appears to override any other onsubmit handler you define.
For now I have removed the disabled_with tag but I'd be interested in a solution which would allow me to keep the disabled behaviour.
I suggest overriding the FormTagHelper's submit_tag method, or perhaps writing your own helper method based on that one, to give you the behaviour you want.
You could have it recognise a :keep_alive option and do the right thing.
Andy Stewart • 24 October 2007As of changeset 6134 a form using :disable_with will trigger its onsubmit handler if available.
Rather than having your :disable_with value call this.form.submit(), wouldn't it be better to let the form take care of it as per 6134?
Thanks!
I added these lines to my admin.js file to automatically make forms with uploads use this hack/patch:
var Document = {
initialize: function(){
$$('form[enctype="multipart/form-data" ]').each(function(uploadForm) {
uploadForm.observe('submit', closeKeepAlive);
});
}
}
Event.observe(document, 'dom:loaded', Document.initialize);
Martin S • 4 June 2009
Thank you so much for the solution!
Ales • 9 July 2009Pretty interesting. I recently met that problem on safari 4. Fix for that looks way more weird (using yui2):
YAHOO.util.Event.addListener("singleformUpload", "submit", function closeKeepAlive() {
if (/Version\\/4\\..+\\sSafari/.test(navigator.userAgent)) {
throw "Error";
}
});
demee • 14 April 2010
Thank you very much!
Olly • 22 August 2007