Pregunta

Tengo un formulario en el que se toma un poco de tiempo para que el servidor de proceso.Necesito para asegurarse de que el usuario espera y no intenta volver a enviar el formulario haciendo clic en el botón de nuevo.He intentado utilizar el siguiente código jQuery:

<script type="text/javascript">
$(document).ready(function() {
    $("form#my_form").submit(function() {
        $('input').attr('disabled', 'disabled');
        $('a').attr('disabled', 'disabled');
        return true;
    });
});
</script>

Cuando yo intente esto en Firefox todo se deshabilitado, pero la forma no es presentado con cualquiera de los datos de entrada se supone que debe incluir.Yo no puedo usar jQuery para enviar el formulario porque necesito el botón para presentarse con el formulario, ya que hay varios botones de envío y determinar que fue utilizado por el que el valor está incluido en el POST.Necesito el formulario para ser presentado como generalmente lo es y tengo que desactivar todo después de que ocurre.

Gracias!

¿Fue útil?

Solución

Actualizar en 2018 : Acabo de recibir algunos puntos de esta vieja respuesta, y sólo quería añadir que el mejor solución sería hacer el idempotente operación para que duplicado presentaciones son inofensivos.

Por ejemplo, si la forma crea una orden, puso un identificador único en el formulario. La primera vez que el servidor ve una solicitud de apertura con el fin de que la identificación, debe crearlo y responder "éxito". comunicaciones posteriores deben también responder "éxito" (en caso de que el cliente no recibió la primera respuesta), pero no debe cambiar nada.

Los duplicados deben ser detectados a través de un control de la unicidad en la base de datos para evitar las condiciones de carrera.


Creo que su problema es esta línea:

$('input').attr('disabled','disabled');

Esta desactivación de todas las entradas, incluyendo, supongo, aquellos cuyos datos de la forma que se supone que se someten.

Para desactivar sólo el botón de envío (s), que podría hacer esto:

$('button[type=submit], input[type=submit]').prop('disabled',true);

Sin embargo, no creo que IE le envíe el formulario si incluso los botones están desactivados. Me gustaría sugerir un enfoque diferente.

Un plugin de jQuery para resolverlo

Nos acabamos de resolver este problema con el código siguiente. El truco aquí es utilizar data() de jQuery para marcar la forma como ya se ha presentado o no. De esa manera, no tiene que meterse con los botones Enviar, que los monstruos es decir, fuera.

// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
  $(this).on('submit',function(e){
    var $form = $(this);

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
    }
  });

  // Keep chainability
  return this;
};

El uso de esta manera:

$('form').preventDoubleSubmission();

Si hay formas de AJAX que debe se le permita enviar varias veces por carga de la página, se les puede dar una clase que indica que, a continuación, les excluyen de su selector de la siguiente manera:

$('form:not(.js-allow-double-submission)').preventDoubleSubmission();

Otros consejos

El tiempo es el enfoque equivocado - ¿cómo se sabe cuánto tiempo tomará la acción en el navegador del cliente

¿Cómo hacerlo?

$('form').submit(function(){
  $(this).find(':submit').attr('disabled','disabled');
});

Cuando se presenta la forma que va a desactivar todos los botones de envío en el interior.

Recuerde, en Firefox cuando se desactiva un botón será recordado en este estado cuando se retrocede en la historia. Para evitar que se tiene que habilitar los botones de carga de la página, por ejemplo.

Creo que la respuesta de Nathan Long es el camino a seguir. Para mí, estoy usando la validación del lado del cliente, por lo que me acaba de agregar una condición que el formulario sea válido.

Editar . Si esto no se añade, el usuario nunca será capaz de enviar el formulario si la validación del lado del cliente se encuentra con un error

        // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                var $form = $(this);

                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                    alert('Form already submitted. Please wait.');
                    e.preventDefault();
                } else {
                    // Mark it so that the next submit can be ignored
                    // ADDED requirement that form be valid
                    if($form.valid()) {
                        $form.data('submitted', true);
                    }
                }
            });

            // Keep chainability
            return this;
        };

event.timeStamp no funciona en Firefox. Volviendo falsa no es estándar, debe llamar event.preventDefault(). Y ya que estamos en ello, siempre utilizar llaves con un control constructo .

Para resumir todas las respuestas anteriores, aquí es un plugin que hace el trabajo y funciona a través del navegador.

jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    jQuery(this).bind('submit', function(event) {

        if(last_clicked) {
            time_since_clicked = jQuery.now() - last_clicked;
        }

        last_clicked = jQuery.now();

        if(time_since_clicked < 2000) {
            // Blocking form submit because it was too soon after the last submit.
            event.preventDefault();
        }

        return true;
    });
};

Para la dirección Kern3l, funciona el método de tiempo para mí, simplemente porque estamos tratando de detener un doble clic del botón de envío. Si usted tiene un tiempo de respuesta muy larga a una presentación, recomiendo reemplazar el botón o envío de formulario con un control de giro.

completamente el bloqueo de comunicaciones posteriores de la forma, ya que la mayoría de los ejemplos anteriores hacen, tiene un mal efecto secundario: si hay un fallo en la red y que quieren tratar de volver a ejecutar, que sería incapaz de hacerlo y perderían los cambios que se hicieron. Esto sin duda haría un usuario enojado.

Por favor, echa un vistazo a jquery-safeform plugin.

Ejemplo de uso:

$('.safeform').safeform({
    timeout: 5000,  // disable next submission for 5 sec
    submit: function() {
        // You can put validation and ajax stuff here...

        // When done no need to wait for timeout, re-enable the form ASAP
        $(this).safeform('complete');
        return false;
    }
});

... Pero el formulario no se envía con ninguno de los datos de publicación que se supone que debe incluir.

Correcto.Los nombres/valores de los elementos de formulario deshabilitados no se enviarán al servidor.Deberías configurarlos como solo lectura elementos.

Además, los anclajes no se pueden desactivar de esa manera.Deberá eliminar sus HREF (no recomendado) o evitar su comportamiento predeterminado (mejor manera), por ejemplo:

<script type="text/javascript">
$(document).ready(function(){
    $("form#my_form").submit(function(){
      $('input').attr('readonly', true);
      $('input[type=submit]').attr("disabled", "disabled");
      $('a').unbind("click").click(function(e) {
          e.preventDefault();
          // or return false;
      });
    });
</script>

código de Nathan, pero para jQuery plugin de Validar

Si usted usa jQuery Validar plugin, que ya han implementado presentar manipulador, y en ese caso no hay ninguna razón para poner en práctica más de uno. El código:

jQuery.validator.setDefaults({
  submitHandler: function(form){
    // Prevent double submit
    if($(form).data('submitted')===true){
      // Previously submitted - don't submit again
      return false;
    } else {
      // Mark form as 'submitted' so that the next submit can be ignored
      $(form).data('submitted', true);
      return true;
    }
  }
});

Se puede ampliar fácilmente dentro del bloque } else { a las entradas desactivar y / o botón de envío.

Saludos

Terminé usando las ideas de este post para llegar a una solución que es bastante similar a la versión de AtZako.

 jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    $(this).bind('submit', function(event){

    if(last_clicked) 
      time_since_clicked = event.timeStamp - last_clicked;

    last_clicked = event.timeStamp;

    if(time_since_clicked < 2000)
      return false;

    return true;
  });   
};

El uso de la siguiente manera:

$('#my-form').preventDoubleSubmission();

He encontrado que las soluciones que no incluían una especie de tiempo de espera, pero los problemas de presentación o elementos de formulario con discapacidad causada simplemente con discapacidad porque una vez que se activa el bloqueo se puede presentar de nuevo hasta que no se actualiza la página. Eso hace que algunos problemas para mí al hacer ajax cosas.

Esto puede ser probablemente prettied un poco, ya que no es tan elegante.

Si se usa AJAX para enviar un formulario, establezca async: false debe evitar que somete adicionales antes de que los claros de formulario:

$("#form").submit(function(){
    var one = $("#one").val();
    var two = $("#two").val();
    $.ajax({
      type: "POST",
      async: false,  // <------ Will complete submit before allowing further action
      url: "process.php",
      data: "one="+one+"&two="+two+"&add=true",
      success: function(result){
        console.log(result);
        // do something with result
      },
      error: function(){alert('Error!')}
    });
    return false;
   }
});

Modificado solución de Nathan un poco de Bootstrap 3. Esto establecerá un texto de carga hasta el botón de enviar. Además será el tiempo de espera después de 30 segundos y permitir que la forma que se volvió a presentar.

jQuery.fn.preventDoubleSubmission = function() {
  $('input[type="submit"]').data('loading-text', 'Loading...');

  $(this).on('submit',function(e){
    var $form = $(this);

    $('input[type="submit"]', $form).button('loading');

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
      $form.setFormTimeout();
    }
  });

  // Keep chainability
  return this;
};

jQuery.fn.setFormTimeout = function() {
  var $form = $(this);
  setTimeout(function() {
    $('input[type="submit"]', $form).button('reset');
    alert('Form failed to submit within 30 seconds');
  }, 30000);
};

El uso de dos botones de envío.

<input id="sub" name="sub" type="submit" value="OK, Save">
<input id="sub2" name="sub2" type="submit" value="Hidden Submit" style="display:none">

Y jQuery:

$("#sub").click(function(){
  $(this).val("Please wait..");
  $(this).attr("disabled","disabled");
  $("#sub2").click();
});

He tenido problemas similares y mi solución (s) son los siguientes.

Si usted no tiene ninguna validación del lado del cliente, entonces puede simplemente usar el método de una jQuery () tal como se documenta aquí.

http://api.jquery.com/one/

Esto desactiva el controlador después de su sido invocada.

$("#mysavebuttonid").on("click", function () {
  $('form').submit();
});

Si estás haciendo validación del lado del cliente como que estaba haciendo entonces su un poco más complicado. El ejemplo anterior no permitiría que usted envíe de nuevo después de la validación fallida. Pruebe este enfoque en lugar

$("#mysavebuttonid").on("click", function (event) {
  $('form').submit();
  if (boolFormPassedClientSideValidation) {
        //form has passed client side validation and is going to be saved
        //now disable this button from future presses
        $(this).off(event);
   }
});

aquí es cómo lo hago:

$(document).ready(function () {
  $('.class_name').click(function () {
    $(this).parent().append('<img src="data:image/gif;base64,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" />');
    $(this).hide();
  });
});

créditos: https://github.com/phpawy/jquery-submit-once

El uso simple contador en enviar.

    var submitCounter = 0;
    function monitor() {
        submitCounter++;
        if (submitCounter < 2) {
            console.log('Submitted. Attempt: ' + submitCounter);
            return true;
        }
        console.log('Not Submitted. Attempt: ' + submitCounter);
        return false;
    }

Y monitor() función de llamada en enviar el formulario.

    <form action="/someAction.go" onsubmit="return monitor();" method="POST">
        ....
        <input type="submit" value="Save Data">
    </form>

este código se mostrará carga en la etiqueta del botón, y botón de ajuste para

desactivar el Estado, a continuación, después del procesamiento, vuelva a habilitar y vuelta de nuevo el texto original del botón **

$(function () {

    $(".btn-Loading").each(function (idx, elm) {
        $(elm).click(function () {
            //do processing
            if ($(".input-validation-error").length > 0)
                return;
            $(this).attr("label", $(this).text()).text("loading ....");
            $(this).delay(1000).animate({ disabled: true }, 1000, function () {
                //original event call
                $.when($(elm).delay(1000).one("click")).done(function () {
                    $(this).animate({ disabled: false }, 1000, function () {
                        $(this).text($(this).attr("label"));
                    })
                });
                //processing finalized
            });
        });
    });
    // and fire it after definition
}

);

Mi solución:

// jQuery plugin to prevent double submission of forms
$.fn.preventDoubleSubmission = function () {
    var $form = $(this);

    $form.find('[type="submit"]').click(function () {
        $(this).prop('disabled', true);
        $form.submit();
    });

    // Keep chainability
    return this;
};

En mi caso onsubmit de la forma tenía algún código de validación, por lo que la subasta Nathan Long respuesta que incluye un puesto de control onsubmit

$.fn.preventDoubleSubmission = function() {
      $(this).on('submit',function(e){
        var $form = $(this);
        //if the form has something in onsubmit
        var submitCode = $form.attr('onsubmit');
        if(submitCode != undefined && submitCode != ''){
            var submitFunction = new Function (submitCode);
            if(!submitFunction()){
                event.preventDefault();
                return false;
            }                   
        }

        if ($form.data('submitted') === true) {
            /*Previously submitted - don't submit again */
            e.preventDefault();
        } else {
          /*Mark it so that the next submit can be ignored*/
          $form.data('submitted', true);
        }
      });

      /*Keep chainability*/
      return this;
    };

Cambiar botón de enviar:

<input id="submitButtonId" type="submit" value="Delete" />

Con el botón normales:

<input id="submitButtonId" type="button" value="Delete" />

A continuación, utilice la función clic:

$("#submitButtonId").click(function () {
        $('#submitButtonId').prop('disabled', true);
        $('#myForm').submit();
    });

Y recuerde botón vuelva a habilitar cuando es NECESARIO:

$('#submitButtonId').prop('disabled', false);

No puedo creer que el buen viejo truco CSS moda del puntero-eventos: Ninguno no se ha mencionado todavía. Yo tenía el mismo problema agregando un atributo desactivado pero esto no segundo palo. Pruebe el siguiente y reemplazar #SubmitButton con el ID de su botón de envío.

$(document).on('click', '#SubmitButton', function () {
    $(this).css('pointer-events', 'none');
})

¿Por qué no sólo esto - esto va a enviar el formulario, sino también desactivar el botón realiza la entrega,

   $('#myForm').on('submit', function(e) {
       var clickedSubmit = $(this).find('input[type=submit]:focus');
       $(clickedSubmit).prop('disabled', true);
   });

Además, si usted está usando jQuery Validar, usted puede poner estas dos líneas bajo if ($('#myForm').valid()).

Se puede dejar de presentar el segundo por esta

$("form").submit(function() {
        // submit more than once return false
        $(this).submit(function() {
            return false;
        });
        // submit once return true
        return true; // or do what you want to do
    });
});

I resolvió un problema muy similar usando:

$("#my_form").submit(function(){
    $('input[type=submit]').click(function(event){
        event.preventDefault();
    });
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top