Disable submit button to not make multiple calls to server [duplicate]

5

I'm trying to disable the button after clicking, so I will not be sending the form data multiple times if the user clicks.

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 button does not send

Change

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

    
asked by anonymous 24.12.2015 / 11:54

3 answers

3

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

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

Then try changing $("#send").click() to $("#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><formid="formID">
  <input type="text" required />
  <input type="submit" class="formButton" name="send" id="send" value="Enviar">
</form>

As an alternative to the above method, we can try alternative solutions:

1 - block the submit 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 input#send from being clicked, in a preventive way the click event associated with input#send is also being removed.

2 - AJAX Submission

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 done asynchronously, so you should handle the return of the request to make a decision, either to inform the success of the request and perform a redirect or to report an error.     

24.12.2015 / 12:19
2

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

Or run this 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, such as @ TobyMosque you can also use the callback error of jQuery. In this case you do not need the timeout:

error: function(){
    ativo = false;
}
    
24.12.2015 / 12:23
2

If you intend to send the form data, process and receive some feedback, then you should disable the button on the beforeSend and after receiving the return on success you must enable the button again, or you can redirect to another page. I believe the following code 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>
    
24.12.2015 / 12:48