0

I am using jQuery Validate to validate my forms. At each validation, I use submitHandler to submit the form via ajax to my controller (I'm using asp.net core 3.1, but I don't think it's that relevant). However, by double-clicking the submit button, my application performs two entries with the same data. The same thing happens with multiple enter.

I've researched different solutions and none of them worked for me so far. Some of them were:

jQuery preventing form from being submited twice and on enter key

Prevent double form submission

Prevent AJAX form from submitting twice?

Prevent submit form twice with change event

Most of my forms are in a modal, maybe that motivated such an action, but I still couldn't find a valid solution. So here's a sample source code from one of the forms - all the others use a similar structure:

THE MODAL WITH FORM

<div class="modal fade" id="modal-user-test" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">New Test</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Fechar">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <form id="form-user-test" autocomplete="off">
                <div class="modal-body">
                    <div class="form-group">
                        <label>Name</label>
                        <input type="text" class="form-control form-control-sm" name="Name" placeholder="Name" maxlength="120" autocomplete="off" />
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-outline-warning" data-dismiss="modal">Back</button>
                    <button class="btn btn-outline-success" type="submit">Salve</button>
                </div>
            </form>
        </div>
    </div>
</div>

THE JS TO VALIDATE:

$(document).ready(function() {
    $("#form-user-test").validate({
        rules: {
            Name: {
                required: true, 
                minlength: 2
            }
        },
        messages: {
            Name: {
                required: "The name is required",
                minlength: "Enter at least two characters"
            }
        },
        submitHandler: sendFormUserTest
    });
});

THE FUNCTION FOR SUBMITTING FORM:

function sendFormUserTest(form) {
    $.ajax({
        url: `/User/Save`,
        type: "POST",
        dataType: "json",
        data: $(form).serialize(),
        success: function (resposta) {
            messageSuccess(resposta.Message);
            $("#modal-user-test").modal("hide");
        },
        error: showErrorMessage
    });
}

I have tried using event.stopPropagation(), event.preventDefault(), in different places, such as before calling the valite method in document ready, within the form submission function, but no solution was helpful to me.

I would like to inform you of a solution without marking this question as duplicate, as as I quoted twice, no solution has worked so far.

Leomar de Souza
  • 677
  • 10
  • 23
  • You're calling the `validate()` function as soon as the document is ready? Why? – Scott Marcus Dec 26 '19 at 20:46
  • @ScottMarcus It was one of my last attempts to see if it worked. Even outside ``document ready``, the problem remains – Leomar de Souza Dec 26 '19 at 20:58
  • `validate()` should only be called when the `submit` event occurs. Please show all your relevant code. – Scott Marcus Dec 26 '19 at 20:59
  • 1
    You mentioned "by double-clicking the submit button" come on!!! as much as do you click it will works, so you need to hide or change or disable submit button after success – Hamid Dec 26 '19 at 21:10
  • You mention using `event.preventDefault()`, but the code does not show that. The function passed to `submitHandler` is given the `form` and the `event`. Were you calling `preventDefault()` on the event passed to the `sendFormUserTest` function? – Heretic Monkey Dec 26 '19 at 21:13
  • @ScottMarcus I followed this example (https://codepen.io/SitePoint/pen/akPoad) and it uses the equivalent of the code I showed. Basically, all of my registration code is the one I posted. – Leomar de Souza Dec 27 '19 at 00:45
  • @HereticMonkey Here are some examples that I followed: https://pastebin.com/wrKzU9Z8, https://pastebin.com/RH6yChbv – Leomar de Souza Dec 27 '19 at 00:57
  • @Hamid I tried this solution https://stackoverflow.com/questions/17106885/disable-submit-button-only-after-submit/36802036, but it didn't work :( – Leomar de Souza Dec 27 '19 at 01:02
  • @LeomardeSouza, you need to set a status variable declaring your validation is processing or not. So set a global var and set it TRUE once your submit button clicked (just before validation) and set it FALSE when validation process finished (include ajax). and avoiding validation rerun when that variable isn't false. `var submitIsBusy=false; onSubmitClick=function(){ if(submitIsBusy) return; submitIsBusy=true; /* start your validation and ajax*/ submitIsBusy=false; /*don't forget set submitIsBusy to false whenever your validation or ajax faild*/ }` – Hamid Dec 27 '19 at 07:23

3 Answers3

0

Not only twice, if you click it thrice it will be submitted thrice, that also goes for n number of clicks.

You need to disable the submit button when the form is being submitted and enable the button when $.ajax calls success or error callback.

let $elem = $('#form-user-test button[type="submit"]');
function handleButton(enable){
    if(enable) $elem.removeAttr('disabled');
    else $elem.attr('disabled','disabled');
}
function sendFormUserTest(form) {
    handleButton(false);
    $.ajax({
        url: `/User/Save`,
        type: "POST",
        dataType: "json",
        data: $(form).serialize(),
        success: function (resposta) {
            handleButton(true);
            messageSuccess(resposta.Message);
            $("#modal-user-test").modal("hide");
        },
        error: function(){
            handleButton(true);
            showErrorMessage();
        }
    });
}
Anah Victor
  • 16
  • 1
  • 5
0

Try to use my approach. hopefully, this can help. :)

let psBuild = { busy: false, }
$(document).on('click', '.options__button--search', function (e){
        e.preventDefault();
        if (!psBuild.busy) { // void double click
            psBuild.busy = true;
            // your ajax here ...
        } else {
            bind_ps_getNotication( 'INFO', 'Please wait ...' );
            psBuild.busy = false;
        }
    });
0
let submitted_form = false;
$("#form-user-test").validate({
    rules: {
        Name: {
            required: true,
            minlength: 2
        }
    },
    messages: {
        Name: {
            required: "The name is required",
            minlength: "Enter at least two characters"
        }
    },
    submitHandler: function(form) {
        if (submitted_form === true) {
            return false;
        } else {
            submitted_form = true;
            sendFormUserTest();
        }
    }
});
makki
  • 1
  • 1