Is there any chance to handle when form submit finished(ok or error)? I want to upload images or mulitpart data without javascript libraries. For example, user clicks submit
button, after uploading data server responds with error
or success
response. Depending on that result I need to do something. Here is example form:
<form method="post" enctype="multipart/form-data" action="/upload_file">
<input type="file" name="upload_image" />
<input type="submit" value="Submit" />
</form>
Since I've not access to the server side, I need to solve this problem on the client side. That's why I couldn't use cookies.
I did these steps to achieve success (I used jQuery to create/bind element/events. I didn't use AJAX to send form data):
1. I have iframe in my HTML (pay attention, there is no iframe
in HTML):
<form id ="send_message_form" target="multipart_uploader_iframe"
method="post" enctype="multipart/form-data" action="/upload_file">
<input type="file" name="upload_image" />
<input type="submit" value="Submit" />
</form>
2. I created iframe
when submit clicked (I tried to avoid unnecessary onload
event firing). Notice, after adding iframe
to body, I added attribute onload
. Because if I add onload attribute while creating iframe, it instantly fired when I append iframe
to body
. Now closePopup
is called once when server responded.
$('#send_message_form').submit(function() {
var customIframe = $('<iframe></iframe>');
customIframe.attr({
'id': "multipart_uploader_iframe",
'name': "multipart_uploader_iframe"
});
$('body').append(customIframe);
customIframe.attr({
'onload': "closePopup();"
});
return true;
});
3. When server responds with responseText (if it returns with text/plain type), responseText will be put in iframe
body. Then iframe
's onload event fires (of course our closePopup function). In my case server responded with OK or other error text:
// Generated by CoffeeScript
window.closePopup = function() {
var error, response, _ref, _ref1;
setTimeout(function() {
return $('#multipart_uploader_iframe').remove();
}, 500);
try {
response = (_ref = (_ref1 = frames['multipart_uploader_iframe']) != null ?
_ref1.document.getElementsByTagName("body")[0].innerHTML : void 0) != null ? _ref : "";
if (response.indexOf("OK") !== -1) {
// close here your popup or do something after successful response
alert('Message has been sent successfully.');
return $(".popup").dialog('close');
}
} catch (_error) {
error = _error;
throw new Error(error);
}
return alert("Error occurred while sending message.");
};
I'm really inspired by this article. I hope this helps someone who has the same problem.
PS: It worked on IE8
One non-ajax option is to have a hidden iframe
on the page with a name, and to set the target
action of your form to the name of that iframe
. Have the server respond with a cookie that's specific to the form (you might even pass in an id
the server should use as the cookie name), then on form submit start polling to see if that cookie exists. When the cookie arrives, it means the server has replied to the form post in the iframe
. You can either put the success/failure information in the cookie itself, or put it in the document that ends up in the iframe
and have your client-side code scrape it from there. Then take appropriate action.
E.g., in pseudo-code:
On The Client On The Server
--------------------------- ---------------------------
1. JS assigns ID to form
2. User submits form
3. JS handles submit event,
starts polling for the
cookie with the relevant
ID
4. Receives and processes the form
5. Responds with success/failure and
cookie
6. JS polling sees cookie,
reads success/fail from
cookie or document in
iframe
7. JS does something appropriate
with success/fail info
I first came up with this technique to answer this other question here, immediately used it on a project, and it works a treat. In the case of that question, we were dealing with something that would return a document to download (Content-Disposition: attachment
) (I used it to show a "Building your document" div
and then replace that with success/failure when the cookie arrived), but it works perfectly well if you're doing something else.