11

I found this question but it wasn't answered: Is there a jQuery event that I can monitor if form submission is cancelled?

So if the user submits a form, while it's loading the user pressed "esc", or clicked "stop" button of the browser, I want to invoke a function, is it possible?

Note: I know we can bind "esc" button, but what about if the user stopped the submission by the browser's "stop/cancel" button?

Is there a JavaScript or jquery possible solution?

EDIT:

I know we can handle this issue with XHR (json/ajax) post, but I'm looking for a normal form submission.

Simply what I'm trying to achieve is this: when the user presses the "submit" button, I want to disable the submit button. If the user cancelled/stopped the submission while it's loading, the submit button will still be disabled (should be re-enabled if submission was cancelled/stopped).


Edit/Rephrase - 16th Dec 2013:

My problem is similar to this: Is there a jQuery event that I can monitor if form submission is cancelled?

For example, I have this form:

<form method="post" enctype="multipart/form-data">
    <input type="file" name="imginput" value=""/>
    <input type="text" name="textinput" value=""/>
    <input type="button" id="submitbtn" value="Submit"/>
</form>

Here's the problem scenario:

A newbie user fills up the form, then double-clicks the submit button. The same form values are inserted into the server twice!

Trying to Achieve:

I want to disable the submit button on click with $('#submitbtn').bind('click', function() { $(this).attr('disabled','disabled'); $(this).prop('disabled', true); });, which solves the problem but creates another problem: if the user clicked "esc" or stopped the browser while the form is still submitting, the submit button would still be disabled and the user cannot re-submit the form any more, I want to re-enable the submit button as soon as the "submission process" is cancelled. Is there a way to achieve this? Something like: $(window).onStop(function() { ... }); ? or a way to indicate that the submission process has been interrupted (or still running)?

Notes:

  • Looking for client-side (javascript or jquery) solution. I know it can be solved easily with server-side checking for identical entries, but I'm not interested in server-side solution.
  • Problem can be solved with XHR (ajax/json) bindings (like onSuccess, onFailure, etc).. but in this case, I'm using a normal post, not XHR, so please exclude XHR from your answer.
  • Solution has to solve the problem at least for the 5 major browsers (IE, FF, Chrome, Safari, Opera).
  • Someone may suggest that we bind "keypress" for the "esc" button, so when the user press "esc" we re-enable the submit button. That's good, but that's half-solution. What if the user stopped the "submission process" by the stop button of the browser, is there a way to indicate that this stop button has been clicked?
Community
  • 1
  • 1
evilReiko
  • 19,501
  • 24
  • 86
  • 102
  • The only possible way is to set timeout on submit and fire the function if after X milliseconds the page is still not unloaded. – VisioN Dec 13 '13 at 18:57
  • what kind of interaction are we looking at? do we want to cancel the submit data from reaching the server? do we want a message to fire? maybe dispatch a 2nd XHR to the server calling abort on last commit? or are you just looking to capture an event while the transfer hasn't finished? – hanzo2001 Dec 13 '13 at 19:41
  • @hanzo2001 I've edited the question and add some extra details – evilReiko Dec 13 '13 at 20:02
  • OK, the disabling and enabling part is pretty straightforward. The cancelled stop submission is the part that I don't understand completely. The user `submits` but he may yet call an `abort()`? I think this can be done as well... and the events can be chained together so that it's coherent behaviour. Am I getting this right? – hanzo2001 Dec 13 '13 at 20:10
  • @hanzo2001 Correct, that's what I'm trying to achieve – evilReiko Dec 13 '13 at 20:36
  • I have a crude implementation of what you seem to want – hanzo2001 Dec 14 '13 at 10:28
  • I would like to add a caveat to this procedure. Some forms are not meant to be undone/cancelled. Please be very weary of this. Insert procedures may set autoincrement values that are difficult to undo so anyone reading this should be very wary about cancelling post procedures (or at least procedures which are hardly irreversible). This also means that the server has to keep track of processes that are undoable – hanzo2001 Dec 14 '13 at 11:18
  • "_If the user cancelled/stopped the submission while it's loading, the submit button will still be disabled (should be re-enabled if submission was cancelled/stopped)_". Now I don't know what's going on. Is submit disabled or not? what is a "_normal form submission_"? why is Ajax not good in this case? – hanzo2001 Dec 16 '13 at 08:08
  • @hanzo2001 my bad, maybe I explained it too complicated. I know we can solve the problem with XHR very easily, but I don't want to use XHR. Here's the problem simplified: "What happens if a user clicks a submit button twice? Same form gets submitted twice!". I want to disable the submit button when user clicks it for the first time, but then while the form is submitting, the user may cancel the process, so I want to re-enable the submit button again – evilReiko Dec 16 '13 at 08:36
  • If submitting twice is **a problem** (for whatever reason), then the fact that the user can cancel just makes it worse!On top of that, the user gets a reanabled form and may submit a **THIRD** time. Do you understand the process behind form submission? What you are asking defeats the purpose of what you want. If what you want is your form to be _multi-submit-protected_ then once the form has been submitted it is disabled **for-good**. The user will have to renavigate to the form if he wants to do something else. If what you want is a process that can be cancelled then that's a different animal – hanzo2001 Dec 16 '13 at 08:41

3 Answers3

7

Finally, this question actually breaks down the complex problem and can thus be addressed in parts, as it should be. First, let's get the elephant out of the room:

  • there is no cross browser solution that detects when the user hits a stop/(ref) button

I actually looked this up for a while and couldn't find how to do it but maybe someone can provide an answer to that and enlighten us both. Now, let's get the 2nd elephant out of the room.

  • No Ajax requests allowed (for some reason). Once the user has hit the submit button and the actual submit event triggers away, we are STUCK

It's a fact that we being able to do things while some request is being processed is what is called Asynchronous (like the first "A" in "Ajax"). Let's see the 3rd elephant

  • I have dumb/inexperienced/clickety-clackety/abusers users that can create inconsistencies on the server (ie: unwanted duplicates) by accident. We should provide a mechanism to impede such event.

Disabling buttons is, of course, the easiest solution in this dilemma. We capture the submit, put in a line to disable any further submit events from that form. Done. May the next elephant come in?

  • The process has begun, the user sees the progress indicator spinning and realizes he just fucked up. He wants to stop it, HELL! he needs to stop it.

Problem, the user doesn't know (and he sure as hell shouldn't need to know) if the server already has complete headers and is processing the request. The server can listen to see if the client aborted but...

  • The user hit the stop button! did the server process the request? did the server dump it? did my data hit the database? oh, now I have a disabled form that I can't use anymore, and I don't know if what I did had consequences. How about a refresh?

Now your issue has a bunch of big holes in it that are worsened by the fact that YOU do NOT want your requests to be ASYNCHRONOUS, AND there is NO WAY to listen for browser.onStopreliably.

My Answer

Think things differently.

  • You are afraid of inconsistencies. Solution: disable submit events after the first

  • Your users are dumb/inexperienced. Solution: big red label Warning: do not press the stop button during the process, or navigate away from the page until the request has completed.

  • Your users are worried. Solution: add a caveat You may edit your post/info in another page once the request has completed. (some instructions to find the edit page)

  • Your server (or slow connection) is taking too long to finish and the user may be impatient. Solution: set a timeout event before triggering the submission that will... but wait! the request is Synchronous which means nothing else can be done until it's finished. Dear User: this process may take a while. If after X mins you have not been redirected to this/page.html please... (do something/more instructions)

  • Take all this advice and start using Ajax if you want higher levels of interactivity, educate your users on the hazards of trying to abort requests and give them options to edit afterwards.

  • Follow examples of other services. Many companies warn very strongly during payment procedures to be patient until the process has finished and add some instructions just in case something goes wrong and the user is worried.

  • Consider adding limitations to the interactivity, some processes are just not meant to be interactive (payments, unique entries...)

  • If you are worried that a user will leave himself stranded on a disabled form then add some info to him. If you tried to stop the procedure please follow this link to see if it was processed, if it wasn't you will be redirected to this form again (you may want to save the users form data so he doesn't have to start over)

hanzo2001
  • 1,338
  • 1
  • 10
  • 24
  • 1
    None of the processes above described will actually interrupt the process if the request reached the server. I don't think that is even remotely possible with current technologies. If the request is sent before the abort was triggered, the client is ok but the server will have processed the request anyway. – hanzo2001 Dec 14 '13 at 11:23
  • this is very strange, it doesn't work in my browser anymore. I'll have to edit some stuff to find out why – hanzo2001 Dec 14 '13 at 12:03
  • The whole idea is prevent the user from clicking the "submit" button more than once, so the user don't submit the same form twice or more. Thank you for this long solution, but I really don't want to include any XHR. – evilReiko Dec 14 '13 at 13:36
  • oh. then the solution becomes quite trivial... or not? – hanzo2001 Dec 16 '13 at 07:55
  • I'll not down-vote it, since maybe someone looking for an XHR solution for the same problem – evilReiko Dec 16 '13 at 08:26
  • sorry. I just don't seem to understand what you want. It's clear that you want to disable buttons onSubmit. What I don't understand is, what happens in the server? the server will still process the request unless it's told not to. Having a _cancel-submission-feature_ alongside this _disable_ feature makes no sense in my view. It also does not make sense that you are using jQuery but you don't want any xhr? is the code in the server not prepared to handle such a request (depending on your framework it may be)? And can it be reanabled or not? – hanzo2001 Dec 16 '13 at 08:35
  • I'm using XHR already, but in some cases I use normal submit (like when uploading a file to the server requires a normal/real post). As for the server, I have no problem with it, the server can handle all submissions. I want to prevent the user from submitting the same form more than once, because I noticed some users do "double-click" on the submit button – evilReiko Dec 16 '13 at 08:42
  • does this double-click actually produce **double entries/files** in your server? I'm not entirely sure if the server actually processes a double-clicked request, the first request gets cancelled when the user hits the button a 2nd time. Both requests are identical and the 2 will only be sent if they are small enough so that in the interval of the 2 clicks the first one actually gets out – hanzo2001 Dec 16 '13 at 08:47
  • tested and approved: if you click a submit button more than once, let's say 3 times, the form with same input values get submitted 3 times = 3 identical entries to the server. hanzo, I have no problem of having the same form with same values submitted more than once if the user did that **manually and on purpose**, I mean, if the user **fill up** the form again with same values more than once. but because some users are really noob, they do "double-click" on the submit button = which causes double identical entries to the server – evilReiko Dec 16 '13 at 09:01
  • what about the cancelling business? is this feature to be implemented on submissions that take a long time? (like a file upload). Because just disabling buttons is very easy, cancel and reanable has consequences – hanzo2001 Dec 16 '13 at 09:04
  • rephrased the question – evilReiko Dec 16 '13 at 10:10
  • Interesting ideas to do a workaround. So, my main question was **is there a way to indicate that the submission process has been interrupted?**, and based on your answer, the anwser is "No". Correct? – evilReiko Dec 16 '13 at 12:12
  • 1
    That is very, very good question! I suppose the answer to that is 2 fold: in a traditional sense, **NO**, and if it can be done it's not crossbrowser reliable. If we introduce _Asynchronicity_ into the mix we can begin to check if the submission process happened but that means that there will have to be some system of process verification implemented and that kind of code and logic behind isn't very pretty. AND the client side behaviour is still not reliable; the **stop** button in the browser introduces a level of chaos that cannot be verified, sadly – hanzo2001 Dec 17 '13 at 08:03
  • Thank you for all the explanation! – evilReiko Dec 17 '13 at 10:02
1

Internet Explorer has a document.onstop event that is fired, but other browsers don't seem to support that. Note that it's fired when the user clicks Stop or hits Esc, OR if the user navigates to another page during page load, which has the same effect.

I don't believe there is a reliable way to trigger an event on clicking Stop in other browsers. Perhaps it would be possible to do something like: keeping the connection to the server open (as in the Comet approach), streaming some sort of keep-alive down the connection, and detecting if the stream ends (as I assume it would if the Stop button were clicked).

From: Any javascript event occuring when user clicks Stop load button?

Community
  • 1
  • 1
JAKEtheJAB
  • 289
  • 1
  • 11
  • Live streaming through a socket while checking for an interruption (and undisabling the submit button) theoretically seems like it would work, however that would be overkill. I have not tried it myself. – JAKEtheJAB Dec 13 '13 at 20:17
  • That's a close one, but yet doesn't solve the issue since it's only supported in IE – evilReiko Dec 14 '13 at 10:26
1

I based my answer on the comment hanzo2001 added in his question:

"The whole idea is prevent the user from clicking the "submit" button more than once, so the user don't submit the same form twice or more."

Then you could possibly have a wasNeverSubmitted flag, and set it to true after the first form submit.

Finally you'd check this flag for every form submit, if true, then you cancel the form submission, see how to do this on this question Disable submit functionality for all forms on a HTML page


The code would look something like below:

HTML:

<form class="js-form-submit-once">

  /* .. form elements here*/

</form>

Javascript (requires jQuery):

var wasNeverSubmitted = true; 

$('js-form-submit-once').on('click', function(){

  if( wasNeverSubmitted ){
    wasNeverSubmitted = false;
    /* ... do nothing, let it submit */
  }
  else {
    return false;  /* cancels form submission */
  }

});
Community
  • 1
  • 1
Adriano
  • 19,463
  • 19
  • 103
  • 140