1

I am using web api in my MVC project and I have ran into a problem where if the user is on the create page.. fills out the form... and hits submit.. during the processing time, the user is able to continuously click the submit button for multiple creations.

My goal

Only allow the user to submit the form once. Basically, after the user clicks, or hits enter on the keyboard or however the user submits the form.. it should only allow 1 time.

I have researched this.

How do I implement that though? Here is what I have so far:

<input id="Edit-Btn-Submit" type="submit" value="Save" class="btn btn-primary" />

$("form").data("validator").settings.submitHandler =
    function(form) {

        $.ajax({
            method: "PUT",
            url: infoGetUrl + itemId,
            data: $("form").serialize(),
            beforeSend: function() {
                disableSendButton();
            },
            complete: function() {
                enableSendButton();
            },
            success: function() {
                toastr.options = {
                    onHidden: function() {
                        window.location.href = newUrl;
                    },
                    timeOut: 3000
                }
                toastr.success("Equipment successfully edited.");
            },
            error: function(jqXHR, textStatus, errorThrown) {
                var status = capitalizeFirstLetter(textStatus);
                var error = $.parseJSON(jqXHR.responseText);
                //console.log(error);
                var modelState = error.modelState;
                //console.log(error.modelState);
                $.each(modelState,
                    function(key, value) {
                        var id = "";
                        if (key === "$id") {
                            id = "#" +
                                key.replace('$', '').substr(0, 1).toUpperCase() +
                                key.substr(2);
                        } else {
                            id = "#" +
                                key.replace('$', '').substr(0, 1).toUpperCase() +
                                key.substr(1);
                            var status = capitalizeFirstLetter(textStatus);
                            toastr.error(status + " - " + modelState[key]);
                        }
                        var input = $(id);
                        console.log(id); // result is #id
                        if (input) { // if element exists
                            input.addClass('input-validation-error');
                        }
                    });
            }
        });
    }

function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function disableSendButton() {
    $('#Edit-Btn-Submit').prop('disabled', true);
}

function enableSendButton() {
    $('#Edit-Btn-Submit').prop('disabled', false);
}
});

Any help is appreciated.

Grizzly
  • 5,873
  • 8
  • 56
  • 109

2 Answers2

3

The way i fix your problem is by disabling the button until the request is complete. This prevents the user from spam-sending. You can also chose to do something else than sidabling the button like hiding it or whatever.

The below code should disable the button when the ajax request start and re-enable it once it is over (success or failure, doesn't matter).

You can refer to this page for more info about the events and handleres fired/accessible with the JQuery Ajax object.

$("form").data("validator").settings.submitHandler =
    function(form) {
        $.ajax({
            method: "PUT",
            url: infoGetUrl + itemId,
            data: $("form").serialize(),
            beforeSend: function() {
                disableSendButton();
            },   
            complete: function() {
                enableSendButton();
            },
            success: function() { /* code */ },
            error: function(jqXHR, textStatus, errorThrown) { /* code */}
        });
    };
function disableSendButton()
{
    $('input').prop('disabled', true);
}
function enableSendButton()
{
    $('input').prop('disabled', false);
}
GGO
  • 2,678
  • 4
  • 20
  • 42
Mathieu VIALES
  • 4,526
  • 3
  • 31
  • 48
  • For some reason when I click the button.. it is not disabling it, see my updated code – Grizzly Oct 13 '17 at 15:07
  • Add a breakpoint in the `beforeSend` method. You can do it by using the `debugger;` expression. you can find more info about the debugger keyword [here](https://www.w3schools.com/js/js_debugging.asp) – Mathieu VIALES Oct 13 '17 at 15:14
  • Do you get a js error in the browser console ? Does it disable the button if you manually call `$('#Edit-Btn-Submit').prop('disabled', true);` ? – Mathieu VIALES Oct 13 '17 at 15:17
  • The only one that works is in the `complete` function, but that doesn't help if the user receives an error.. they would have to refresh the page in order to re-enable the button – Grizzly Oct 13 '17 at 17:10
  • I got it. Thank you for your help – Grizzly Oct 13 '17 at 17:14
  • I don t have access to a computer right now. I'll look into it in a few hours I think I did that exact thing in a projects of mines, I'll see exactly what I did. – Mathieu VIALES Oct 13 '17 at 17:16
1

You can disable the button before call using the "beforeSend" event and then enable it on "success" event.

$.ajax({
   method: "PUT",
   url: infoGetUrl + itemId,
   data: $("form").serialize(),
   beforeSend: function() {
      $('#buttonId').prop('disabled', true);
   },
   success: function() {
      $('#buttonId').prop('disabled', false);
      //some code here
   },
   error: function(jqXHR, textStatus, errorThrown) {
      alert("Error during communication with the service, try later");
      $('#buttonId').prop('disabled', false);
      //some other code
   }
});
Daniele
  • 56
  • 1
  • 9
  • if there is an error during the request, the user can't click the "send" button again. This means that to try again (and the user will) they have to reload the page, potentially losing all the data in the form fields. – Mathieu VIALES Oct 13 '17 at 15:15
  • Second point : duplicating code is a bad practice. The `complete` callback was create precisely for this purpose. It is good to use it :-) – Mathieu VIALES Oct 13 '17 at 18:09
  • upvoted you anyways, since you actually answered the question :-) – Mathieu VIALES Oct 13 '17 at 18:09
  • Thanks, write code quickly is the worst practice ;) – Daniele Oct 13 '17 at 18:18