Disable Submit button to make no multiple calls to the server

Asked

Viewed 17,714 times

5

I am trying to disable the button after clicking , so that it does not keep sending the form data several times if the user keeps clicking.

my button

<input type="submit" class="formButton" name="send" id="send" value="Enviar">

my js

       $("#send").click(function(event){
            $(event.target).attr('disabled', 'disabled');
        });

When I click the button it only disables the do not send button

Altering

    $(document).ready(function(){           
        $("#contato_1").submit(function(event){
            $("#send").attr('disabled', 'disabled');
        });
    });

With this change is not sending the value of my form , in my php I make a test if (!isset($_POST['send'])) {, I don’t know why you stopped telling me, so it’s not working

  • If you take this JS code Submit occurs? I ask this because I do not know what you put in your form action.

  • yes, my form was already working , I am trying to solve the problem of the user being able to click several times

  • 1

    deactivate the $("#send") at the event submit of their respective form.

  • and so onsubmit="send.disabled=true;" ?

  • added an answer with more information about the problem and the possible solution.

  • http://answall.com/questions/86806/como-trata-que-a-submissive%C3%A3o-de-um-formul%C3%A1rio-se-execute-once-only/86807#86807

  • It did not work here the solution of this duplicate , not disabled

  • I always do it the way you did, using true false with a variable. Just so you know, we’re not a forum. If you have an answer then post as answer, do not put the answer within the body of the question, this is very confusing. We are a Q&A ;)

Show 3 more comments

3 answers

3


The HTML page will not send the form if the the input[type="submit"] is disabled.

Like the event click of input[type="submit"] occurs before the submit of form, then you are to indirectly abort the sending of the form

then try to change the $("#send").click() for $("#formID").submit();

var formID = document.getElementById("formID");
var send = $("#send");

$(formID).submit(function(event){
  if (formID.checkValidity()) {
    send.attr('disabled', 'disabled');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="formID">
  <input type="text" required />
  <input type="submit" class="formButton" name="send" id="send" value="Enviar">
</form>

as altenative to the method mentioned, we can try alternative solutions:

1 - lock send button with a div:

var formID = document.getElementById("formID");
var send = document.getElementById("send");

var onSendClick = function (event) {
  if (formID.checkValidity()) {
    event.target.parentNode.classList.add("disabled");
    event.target.removeEventListener("click", onSendClick);
  }
}

send.addEventListener("click", onSendClick);
#containerEnviar {
  position: relative;
}

#containerEnviar #blockEnviar {
  display: none;
  position: absolute;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
}


#containerEnviar.disabled #blockEnviar {
  display: block;
}

#containerEnviar.disabled #send {
  opacity: 0.5;
}
<form id="formID">
  <input type="text" required />
  <div id="containerEnviar">    
    <input type="submit" class="formButton" name="send" id="send" value="Enviar">
    <div id="blockEnviar"></div>
  </div>
</form>

In the example above, the div#blockEnviar will prevent the input#send the click event associated with the input#send is also being removed.

2 - Sending by AJAX

var formID = document.getElementById("formID");
var send = document.getElementById("send");

formID.addEventListener("submit", function (event) {
  if (formID.checkValidity()) {
    var formData = new FormData(formID);
    var httpRequest = new XMLHttpRequest();
    
    httpRequest.open(formID.method, formID.action, false);
    httpRequest.addEventListener("readystatechange", function(event) {
      if (httpRequest.readyState == 4) {
        if (httpRequest.status == 200) {
          alert("Envio do Formulario realizado com sucesso");
        } else {
          alert("Ocorreu um erro ao enviar o Formulario");
          send.disabled = false; //posibilitar uma nova tentativa;
        }
      }
    });
    
    send.disabled = true;
    httpRequest.send(formData);    
  }
  
  //impedir o envio sincrono do form
  return false;
});
<form id="formID" action="minha_url" method="post">
  <input id="input1" name="input1" type="text" required />
  <input type="submit" class="formButton" name="send" id="send" value="Enviar">
</form>

Here your request is made in an asyncronous way, so you should treat the return of the request to make a decision, either to inform the success of it and perform a redirect or to report an error.

  • my form has some test , there is time that does not send for lack of some field filled and with that then the button is disabled if not send , how can I enable back

  • not sending it like this :/ , I will update the question as it was

  • @Ilgnerdeoliveira do not change the question with ideas of the answers. So the answers no longer make sense...

  • @Ilgnerdeoliveira, If you are using an HTML5 validation, you can check if the form is valid before disabling the button using the method checkValidity in the form... you can check the answer to see the implementation.

  • @Tobymosque before putting this js my form was sending the input value, I need it to do a test in php. when I put js it stops sending this value, you know why this happens?

  • @Ilgnerdeoliveira, I believe your initial problem is already solved, now you are having problems to receive a specific data in PHP (as a C# programmer that feeds a certain disdain for PHP, I can’t help you at this point), but as an option, you can try to prevent the resubmission of the form otherwise, for example with a screen lock, use of a flag or an AJAX request.

  • @Ilgnerdeoliveira, I added an outline solution to the problem I, although I do not believe it is the ideal solution, it should solve your problem.

  • What you changed was how to disable ne? with your solution was disabling , but it is not sending information I need in php

  • @Ilgnerdeoliveira in solution #1, I am no longer disabling the input#send, I am just making it impossible for it to be clicked (there is an invisible div covering it)... in solution #2, I am sending the form asincrona, so there is no problem in the input#send is disabled.

  • @Tobymosque put the solution that worked there in the question

Show 5 more comments

2

If you intend to send the form data, process and receive some feedback, then you must disable the button in beforeSend and after receiving the return in Success you must enable the button again, or you can redirect to another page. I believe the code below can help you.

jQuery(document).ready(function(){

    jQuery("#send").click(function(event){
            event.preventDefault();

            codigo   = jQuery('input[id="nome"]').val();//campo no form

            jQuery.ajax({
                url: 'teste_botao.php', 
                dataType: 'html',
                data: {par01: codigo},
                type: 'POST',
                beforeSend: function(){
                    //jQuery('#insere-aqui').html(iconCarregando);
                    jQuery('#send').attr('disabled', 'disabled');//desabilito
                },
                complete: function(){
                    jQuery(iconCarregando).remove();
                },
                success: function(data, textStatus) {
                    jQuery('#insere-aqui').html('');
                    jQuery('#insere-aqui').html(data);
                    jQuery('#send').removeAttr('disabled');//habilito
                },
                error: function(xhr,er) {
                    jQuery('#insere-aqui').html('Error ' + xhr.status + ' - ' + xhr.statusText + '<br />Tipo de erro: ' + er +'')
                }       
            });
    });

});

EXAMPLE With serialize()

<script type="text/javascript"> 
$(document).ready(function(){
        var iconCarregando = $('<img src="../icon/mini.gif" class="icon" /> <span class="destaque">Carregando. Por favor aguarde...</span>');
    $('#form_um').submit(function(e) {
    e.preventDefault();
    var serializeDados = $('#form_um').serialize();

    $.ajax({
            url: 'exemplo-serialize.php', 
            dataType: 'html',
            type: 'POST',
            data: serializeDados,
            beforeSend: function(){
            $('#insere_aqui').html(iconCarregando);
            $('#send').attr('disabled', 'disabled');//desabilito
            },
            complete: function() {
            $(iconCarregando).remove();
            },
            success: function(data, textStatus) {
            $('#insere_aqui').html('<p>' + data + '</p>');
            $('#send').removeAttr('disabled');//habilito
            },
            error: function(xhr,er) {
                $('#mensagem_erro').html('<p class="destaque">Error ' + xhr.status + ' - ' + xhr.statusText + '<br />Tipo de erro: ' + er +'</p>')
            }       
        });
    }); 
})
</script>
  • So it is only sending the name , and the rest of the form data

  • the code is an example, the rest of the fields you add, the idea was to disable the button, but to send the whole form you can use the serialize method().

  • @Ilgnerdeoliveira, I left an example with the serialize().

2

I suggest you change your logic. I think during the execution of the event callback click it is still possible to prevent the submit, that must come after the click.

Either you run that code at the end of Submit, or you can switch to this logic that uses a flag to prevent submitting twice:

var ativo = false;
$("#aTuaForm").on('submit', function(event) {
    if (ativo) preventDefault();
    ativo = true;
    var xhr;

    var timeout = setTimeout(function() { // caso o ajax não corra bem
        xhr.abort();
        ativo = false; // preparado para um novo envio
    }, 5000); // cancela depois de 5000

    xhr = $.ajax({
        url: "/o/teu/endereco",
        success: function(result) {
            ativo = false; // preparado para um novo envio
            clearTimeout(timeout);
            // o resto do teu código
        }
    });
});

If you want, like @Tobymosque referred also you can use the callback error jQuery. Then you don’t need the timeout:

error: function(){
    ativo = false;
}
  • Sergio, wouldn’t it be better to set the flag ativo for false in the error in the ajax?

  • 1

    @Tobymosque this is also a good way. I will join, thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.