Tengo un formulario que el servidor tarda un poco en procesar. Necesito asegurarme de que el usuario espere y no intente volver a enviar el formulario haciendo clic nuevamente en el botón. Intenté usar 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 intento esto en Firefox, todo se deshabilita, pero el formulario no se envía con ninguno de los datos POST que se supone que debe incluir. No puedo usar jQuery para enviar el formulario porque necesito que el botón se envíe con el formulario, ya que hay varios botones de envío y determino cuál fue utilizado por cuál valor se incluye en la POST. Necesito que el formulario se envíe tal como es y necesito deshabilitar todo inmediatamente después de que eso suceda.
¡Gracias!
Respuestas:
Actualización en 2018 : acabo de recibir algunos puntos para esta vieja respuesta, y solo quería agregar que la mejor solución sería hacer que la operación sea idempotente para que los envíos duplicados sean inofensivos.
Por ejemplo, si el formulario crea un pedido, coloque una ID única en el formulario. La primera vez que el servidor ve una solicitud de creación de pedido con esa identificación, debe crearla y responder "éxito". Los envíos posteriores también deberían responder "éxito" (en caso de que el cliente no obtuviera la primera respuesta) pero no deberían cambiar nada.
Los duplicados deben detectarse mediante una comprobación de unicidad en la base de datos para evitar condiciones de carrera.
Creo que tu problema es esta línea:
Está deshabilitando TODAS las entradas, incluidas, supongo, aquellas cuyos datos se supone que debe enviar el formulario.
Para deshabilitar solo los botones de envío, puede hacer esto:
Sin embargo, no creo que IE envíe el formulario si incluso esos botones están deshabilitados. Sugeriría un enfoque diferente.
Un complemento jQuery para resolverlo
Acabamos de resolver este problema con el siguiente código. El truco aquí es usar jQuery's
data()
para marcar el formulario como ya enviado o no. De esa manera, no tenemos que meternos con los botones de envío, lo que asusta a IE.Úselo así:
Si hay formas de AJAX que debe ser permitido enviar múltiples veces por carga de la página, puede darles una clase que indica que, a continuación, les excluyen de su selector de la siguiente manera:
fuente
$(this)
que unavar that = $(this)
?$form
embargo, solía : 'formulario' porque es más descriptivo y el principal$
porque, según mi convención, eso significa que es un objeto jQuery.El enfoque de sincronización es incorrecto: ¿cómo sabe cuánto tiempo durará la acción en el navegador del cliente?
Cómo hacerlo
Cuando se envía el formulario, deshabilitará todos los botones de envío dentro.
Recuerde, en Firefox cuando deshabilita un botón, este estado se recordará cuando regrese al historial. Para evitar que tenga que habilitar botones en la carga de la página, por ejemplo.
fuente
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 acabo de agregar una condición para que el formulario sea válido.
EDITAR : si esto no se agrega, el usuario nunca podrá enviar el formulario si la validación del lado del cliente encuentra un error.
fuente
event.timeStamp
No funciona en Firefox. Devolver falso no es estándar, debe llamarevent.preventDefault()
. Y mientras lo hacemos, use siempre llaves con una construcción de control .Para resumir todas las respuestas anteriores, aquí hay un complemento que hace el trabajo y funciona en varios navegadores.
Para abordar Kern3l, el método de sincronización funciona para mí simplemente porque estamos tratando de detener un doble clic en el botón Enviar. Si tiene un tiempo de respuesta muy largo para un envío, le recomiendo reemplazar el botón o formulario de envío con una flecha giratoria.
El bloqueo completo de los envíos posteriores del formulario, como lo hacen la mayoría de los ejemplos anteriores, tiene un efecto secundario negativo: si hay una falla en la red y quieren intentar volver a enviarla, no podrían hacerlo y perderían los cambios que hecho. Esto definitivamente haría que un usuario enojado.
fuente
Por favor, consulte el complemento jquery-safeform .
Ejemplo de uso:
fuente
Correcto. Los nombres / valores de elementos de formulario deshabilitados no se enviarán al servidor. Debe establecerlos como elementos de solo lectura .
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:
fuente
$('input[type=submit]').attr("disabled", "disabled");
pero mi forma favorita es incluironclick="this.disabled = 'disabled'"
el onclick del envío.Existe la posibilidad de mejorar el enfoque de Nathan Long . Puede reemplazar la lógica para la detección del formulario ya enviado por este:
fuente
El código de Nathan pero para el complemento jQuery Validate
Si utiliza el complemento jQuery Validate, ya tienen implementado el controlador de envío, y en ese caso no hay razón para implementar más de uno. El código:
Puede expandirlo fácilmente dentro de
} else {
bloque para deshabilitar las entradas y / o enviar el botón.Salud
fuente
Terminé usando ideas de esta publicación para llegar a una solución que es bastante similar a la versión de AtZako.
Usando así:
Descubrí que las soluciones que no incluían algún tipo de tiempo de espera sino que simplemente desactivaban el envío o los elementos de formulario inhabilitados causaban problemas porque una vez que se activa el bloqueo, no puede enviar nuevamente hasta que actualice la página. Eso me causa algunos problemas cuando hago cosas de ajax.
Esto probablemente se puede mejorar un poco, ya que no es tan elegante.
fuente
Si usa AJAX para publicar un formulario, el conjunto
async: false
debería evitar envíos adicionales antes de que se borre el formulario:fuente
La solución de Nathan modificada un poco para Bootstrap 3. Esto establecerá un texto de carga en el botón de envío. Además, expirará después de 30 segundos y permitirá que el formulario se vuelva a enviar.
fuente
Use dos botones de envío.
Y jQuery:
fuente
Use un contador simple al enviar.
Y llame a la
monitor()
función al enviar el formulario.fuente
He tenido problemas similares y mis soluciones son las siguientes.
Si no tiene ninguna validación del lado del cliente, simplemente puede usar el método jquery one () como se documenta aquí.
http://api.jquery.com/one/
Esto deshabilita el controlador después de haber sido invocado.
Si está haciendo la validación del lado del cliente como lo estaba haciendo, entonces es un poco más complicado. El ejemplo anterior no le permitiría enviar nuevamente después de una validación fallida. Prueba este enfoque en su lugar
fuente
Puede detener el segundo envío por este
fuente
Mi solución:
fuente
En mi caso, el formulario de envío del formulario tenía un código de validación, por lo que incrementé la respuesta de Nathan Long, incluido un punto de control de envío
fuente
Cambiar el botón de enviar:
Con botón normal:
Luego use la función de clic:
Y recuerde volver a habilitar el botón cuando sea necesario:
fuente
No puedo creer el buen truco css anticuado de los eventos de puntero: ninguno no ha sido mencionado todavía. Tuve el mismo problema al agregar un atributo deshabilitado, pero esto no se publica nuevamente. Pruebe lo siguiente y reemplace #SubmitButton con la ID de su botón de envío.
fuente
Enter
presiona la tecla.¿Por qué no solo esto? Esto enviará el formulario pero también deshabilitará el botón de envío,
Además, si está utilizando jQuery Validate, puede colocar estas dos líneas debajo
if ($('#myForm').valid())
.fuente
este código mostrará la carga en la etiqueta del botón y establecerá el botón en
deshabilite el estado, luego, después del procesamiento, vuelva a habilitar y regrese el texto del botón original **
fuente
Resolví un problema muy similar usando:
fuente