Prevent duplicate submit with JavaScript

This post shows you how to prevent duplicate submit with JavaScript. It is always a risk that a user clicks on a button several times, it can be because the submit takes time or that the user double-clicks on the submit-button.

Duplicate submits can create big problems in some situations, a user can be registered with 2 or more accounts and one order can result in 2 or more orders.

Styling (CSS)

We are going to prevent duplicate submits by disabling buttons and we need to style disabled buttons to make it clear that disabled buttons not is clickable.

input:disabled, button:disabled, input:disabled:hover, button:disabled:hover {
    resize: none;
    color: #000000;
    background-color: #ddd;
    cursor: default;
}

Submit form

Our form has three buttons and we add a btn-disablable class to buttons that can be disabled. It is important that we also enable buttons when our website is ready to accept submits again. We need to enable buttons if the validation fails or when the submit operation has finished.

<input type="button" class="annytab-form-button btn-disablable" value="@save_tt" onclick="sendForm(document.getElementById('inputForm'))" />
@*<input type="submit" class="annytab-form-button" value="@save_tt" />*@
<input type="button" class="annytab-form-button btn-disablable" value="@cancel_tt" onclick="location.href='/admin_administrators'" />
<input type="button" class="annytab-form-button btn-disablable" value="minify" onclick="panel.minify();" />

<script>
    // Submit a form
    async function sendForm(form)
    {
        // Disable buttons
        disableButtons();

        // Make sure that the form is valid
        if (await annytab.validation.valid(form) === false) { enableButtons(); return false; }

        // Get form data
        var fd = new FormData(form);

        // Post form data
        var xhr = new XMLHttpRequest();
        xhr.open('POST', form.getAttribute('action'), true);
        xhr.onload = function () {
            if (xhr.status === 200)
            {
                // Get the response
                var data = JSON.parse(xhr.response);

                // Check the success status
                if (data.success === true)
                {
                    // Output a success message
                    toastr['success'](data.message);
                }
                else
                {
                    // Output error information
                    toastr['error'](data.message);
                }
            }
            else
            {
                // Output error information
                toastr['error'](xhr.status + " - " + xhr.statusText);
            }

            // Enable buttons
            enableButtons();

        };
        xhr.onerror = function ()
        {
            // Output error information
            toastr['error'](xhr.status + " - " + xhr.statusText);

            // Enable buttons
            enableButtons();
        };
        xhr.send(fd);

    } // End of the sendForm method

    // Disable buttons
    function disableButtons()
    {
        var buttons = document.getElementsByClassName('btn-disablable');
        for (var i = 0; i < buttons.length; i++) {
            buttons[i].setAttribute('disabled', true);
        }

    } // End of the disableButtons method

    // Enable buttons
    function enableButtons()
    {
        var buttons = document.getElementsByClassName('btn-disablable');
        for (var i = 0; i < buttons.length; i++) {
            setTimeout(function (button) { button.removeAttribute('disabled'); }, 1000, buttons[i]);
        }

    } // End of the enableButtons method

</script>

Leave a Reply

Your email address will not be published. Required fields are marked *