Debounce clicks when submitting a web form
Asked Answered
B

6

6

A poorly-written back-end system we interface with is having trouble with handling the load we're producing. While they fix their load problems, we're trying to reduce any additional load we're generating, one of which is that the back-end system continues to try and service a form submission even if another submission has come from the same user.

One thing we've noticed is users double-clicking the form submission button. I need to de-bounce these clicks, and prevent a second form submission.
My approach (using Prototype) places an onSubmit on the form that calls the following function which hides the form submission button and displays a "loading..." div.

function disableSubmit(id1, id2) {
    $(id1).style.display = 'none';
    $(id2).style.display = 'inline';
}

The problem I've found with this approach is that if I use an animated gif in the "loading..." div, it loads fine but doesn't animate while the form is submitting.

Is there a better way to do this de-bouncing and continue to show animation on the page while waiting for the form result to (finally) load? ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Batts answered 18/9, 2008 at 23:23 Comment(2)
no answer picked after all this time? laaaaamePeake
Erm, you mean apart from the one I picked? (your response, no less) I haven't voted it up because while it answers the question, it's not Prototype.Batts
P
2

If you've got jQuery handy, attach a click() event that disables the button after the initial submission -

$('input[type="submit"]').click(function(event){
 event.preventDefault();
 this.click(null);
});

that sort of thing.

Pantomime answered 18/9, 2008 at 23:23 Comment(4)
Even better I've discovered with jQuery is onesubmit() manalang.com/jquery/docs/index.html#onesubmit-fnBatts
Dead link in commentRaspy
This is not satisfactory. The code can perform validation and other tasks after the button press but before the actual submit. Because of that you won't be able to save yourself from properly debouncing the click.Tanka
yeah wow blast from the past - I guess jquery really has been around for over a decade now! rather than removing the click event (in case you need to use it later) it might make more sense to disable the submit button (as answered by @Beedon below) or disable the entire form (as outlined here)Peake
B
5

Using Prototype, you can use this code to watch if any form has been submitted and disable all submit buttons when it does:

document.observe( 'dom:loaded', function() { // when document is loaded
    $$( 'form' ).each( function( form ) { // find all FORM elements in the document
        form.observe( 'submit', function() {  // when any form is submitted
            $$( 'input[type="submit"]' ).invoke( 'disable' );  // disable all submit buttons
        } );
    } );
} );

This should help with users that double-click on submit buttons. However, it will still be possible to submit the form any other way (e.g. pressing Enter on text field). To prevent this, you have to start watching for any form submission after the first one and stop it:

document.observe( 'dom:loaded', function() {
    $$( 'form' ).each( function( form ) {
        form.observe( 'submit', function() {
            $$( 'input[type="submit"]' ).invoke( 'disable' );
            $$( 'form' ).observe( 'submit', function( evt ) { // once any form is submitted
                evt.stop(); // prevent any other form submission
            } );
        } );
    } );
} );
Beedon answered 27/9, 2008 at 4:28 Comment(0)
M
5

All good suggestions above. If you really want to "debounce" as you say, then I've got a great function for that. More details at unscriptable.com

var debounce = function (func, threshold, execAsap) {

    var timeout;

    return function debounced () {
        var obj = this, args = arguments;
        function delayed () {
            if (!execAsap)
                func.apply(obj, args);
            timeout = null; 
        };

        if (timeout)
            clearTimeout(timeout);
        else if (execAsap)
            func.apply(obj, args);

        timeout = setTimeout(delayed, threshold || 100); 
    };

}
Macymad answered 20/3, 2009 at 17:17 Comment(0)
P
2

If you've got jQuery handy, attach a click() event that disables the button after the initial submission -

$('input[type="submit"]').click(function(event){
 event.preventDefault();
 this.click(null);
});

that sort of thing.

Pantomime answered 18/9, 2008 at 23:23 Comment(4)
Even better I've discovered with jQuery is onesubmit() manalang.com/jquery/docs/index.html#onesubmit-fnBatts
Dead link in commentRaspy
This is not satisfactory. The code can perform validation and other tasks after the button press but before the actual submit. Because of that you won't be able to save yourself from properly debouncing the click.Tanka
yeah wow blast from the past - I guess jquery really has been around for over a decade now! rather than removing the click event (in case you need to use it later) it might make more sense to disable the submit button (as answered by @Beedon below) or disable the entire form (as outlined here)Peake
M
1

You could try setting the "disabled" flag on the input (type=submit) element, rather than just changing the style. That should entirely shut down the from on the browser side.

See: http://www.prototypejs.org/api/form/element#method-disable

Molini answered 18/9, 2008 at 23:28 Comment(0)
N
0

Here I have a simple and handy way to prevent duplicate or multiple form submittion.

Give a class "prevent-mult-submit-form" to the desired form and another class to the submit button "disable-mult-click". You can aslo add a font awesome spinner like

<i class="spinner hidden fa fa-spinner fa-spin" style="margin-right: 2px"></i>

Now pest the code below inside script tag. you are good to go.

 $('.prevent-mult-submit-form').on('submit', function(){
      $('.disable-mult-click').attr('disabled', true)
      $('.spinner').removeClass('hidden')
     })
Nynorsk answered 22/7, 2022 at 8:3 Comment(0)
C
-1

Submit the form with AJAX, and the GIF will animate.

Ceruse answered 3/12, 2010 at 1:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.