Javascript: Evitar doble Submit

En algunas ocasiones cuando se hace el envío de datos mediante un formulario el servidor demora en responder y el usuario presiona el botón enviar nuevamente con lo cual se pueden generar registros duplicados o correos enviados varias veces. Para prevenir este problema veremos dos formas de desactivar el envío múltiple del formulario mediante Javascript.

Creando el Formulario
Supongamos que tenemos un formulario en el cual deseamos registrar el nombre y el email de un visitante, para ello creamos un formulario

  1. <form method="post" onsubmit="return checkSubmit();">
  2.     Nombres:<br />
  3.     <input name="nombres" type="text" id="nombres" /><br />
  4.     Email:<br />
  5.     <input name="email" type="text" id="email" /><br />
  6.     <input type="submit" id="btsubmit" value="Registrar" />
  7. </form>

Nótese que hemos agregado en el evento onsubmit (el cual se ejecuta al enviar el formulario) el llamado a la función checkSubmit (el cual crearemos mas adelante), además de ello al botón de envío lo hemos llamado btsubmit.

Metodo I: Verificar el doble envío
Lo que haremos es guardar una variable que indique que ya se envío el formulario, en el siguiente llamado mostraremos un mensaje indicando que el formulario ya se esta enviando. Luego la función checkSubmit tendría la forma:

  1. var statSend = false;
  2. function checkSubmit() {
  3.     if (!statSend) {
  4.         statSend = true;
  5.         return true;
  6.     } else {
  7.         alert("El formulario ya se esta enviando...");
  8.         return false;
  9.     }
  10. }

Pueden ver el ejemplo funcionando en prevent2submitI.html.

Metodo II: Deshabilitar el botón Enviar
En este caso, una vez presionado el botón enviar lo deshabilitamos y ademas le cambiamos el texto indicando que el envío del formulario. Para ello utilizamos el nombre del botón el cual hemos llamado btsubmit.

  1. function checkSubmit() {
  2.     document.getElementById("btsubmit").value = "Enviando...";
  3.     document.getElementById("btsubmit").disabled = true;
  4.     return true;
  5. }

Pueden ver el ejemplo funcionando en prevent2submitII.html.

Comentarios Total 20 comentarios


Yeru
Publicado: 22/05/2008 2:15 pm

Muy buen aporte, lo necesitaba… Copiando y pasteando… ;) Saludos…

caos30
Publicado: 23/05/2008 5:49 am

Muy bien pensado. Sobretodo me ha gustado el primer método. Es más, yo lo recomendaría. Le veo una ventaja importante: permite que la función checkSubmit() sea llamada desde varios sitios. Quiero decir, que se podría llamarla cuando el visitante haga clic en cualquier botón de la página que lleve a un formulario, si es que en una misma página hubieran varios formularios. Sería como una forma de decir: “ahora que ya has hecho clic aquí, tendrás que esperar la respuesta del servidor”, puesto que tal como nosotros sabemos una vez enviada la petición es muy posible que aunque no se haya renderizado en la pantalla la respuesta del servidor, éste ya haya realizado cambios en la base de datos, y un “tirar atrás” a mitad del proceso en determinados casos es peliagudo, jejejeje… y que nadie piense mal, eh!! ;)

SERGI

caos30
Publicado: 23/05/2008 5:52 am

Perdón, ahora que releeo mi primer comentario quiero añadir -para que se me entienda mejor- que estoy pensando en el caso de estar programando una “aplicación web”, no tanto una navegación web sencilla.

Como ya sabréis los que programais aplicaciones web, las repeticiones de clic pueden ser muy “peligrosas”, y en este sentido el artículo me ha parecido muy interesante ;)

SERGI

SERGI

albert
Publicado: 23/05/2008 1:40 pm

hay otro mejor que en vez de que aparezca la ventanita diciendo que el mensaje se esta enviando, simplemente desactiva el boton, no pudiendo hacer mas click.

Danny
Publicado: 20/01/2009 11:15 am

Muy buen aporte me ayudo mucho, en cuanto a los dos métodos se aplican de acuerdo a las necesidades de programación. en mi caso fue muy util la segunda debido a que al realizar un click se habilita un gif animado de “procesando” y es cuando deshabilito el boton.

ceva
Publicado: 29/01/2009 10:31 pm

mmm… siendo una interfaz web, mas peligroso que doble submit, es que te hagan F5 (recargar) en la pagina a donde se envio el formulario tal vez ahi es donde mas interesa, para que no se duplique informacion, para eso seria bueno encontra algun buen metodo

Mario Restrepo
Publicado: 14/03/2009 1:19 pm

CEVA, para eso puedes bloquear algunas teclas en tu aplicación web. Eso implica que implementes una capa de “identificación” de browser y ahí sí el bloqueo de teclas específicas.

Si alguien está interesado envíeme un email y con gusto se lo comparto.

david garcia
Publicado: 11/06/2009 10:43 am

hombre muchas gracias, era lo ke necesitaba, buen post…

Erika
Publicado: 02/06/2010 10:39 pm

lo tomare en cuenta n_n’

Josué
Publicado: 05/07/2010 11:48 am

Muy buen aporte estoy ya utilizando la opcion 1 me inclino mas por la 2 pero no se porque pero yo utilizo una opcion get onsubmit y cuando envio informacion con esta segunda no me funciona solo se deshabilita pero los datos no me los envia, que hago?

Mario Gonzales
Publicado: 15/07/2010 8:51 pm

Yo uso el número 2 asi deshabilito, y le impido al cliente hacer otro click.
Muy bueno, gracias unijimpe.

RGF
Publicado: 25/11/2010 9:22 pm

gracias por el ejemplo me ha servido en mi form aunque la segunda no he podido hacer que me funcione no me llega a procesar el post o sea no me llevan los datos pero con la primera sin problemas. El segundo no me funciona por la funcion disabled = true; la verdad no entiendo nada todabia sobre JS no se que sera lo que le impide procesar el form

Eduardo
Publicado: 10/10/2011 6:24 pm

Consulta, pero que pasa si ya termino de cargar y quiero volver a registrar otro usuario con el mismo nombre y solo quiero cambiar el correo, ya no me deja hacerlo. Y para hacerlo tengo que regrescar todo el formulario. Hay una forma de detectar que el submit termino????

anayeli
Publicado: 16/02/2012 5:37 pm

como enviar varios formularios con un solo boton?

rudy
Publicado: 12/06/2012 7:30 pm

no me procesa el submit la 2da opcion cuando mi action de mi formulario es asia si mismo.. $_SERVER[‘PHP_SELF’]

Diego Carrion
Publicado: 18/10/2012 8:52 am

No funciona. Estoy haciendo un insert a una tabla y así aparezcan los mensajes, si doy clic una vez, lo carga dos veces o si sigo haciendo clic así muestre en mensaje lo carga cuantas veces se dé clic.

Edgar Paredes
Publicado: 19/09/2013 11:02 am

Excelente!!!

svegam
Publicado: 21/11/2013 12:40 pm

Muchas gracias, está excelente!
Lo implementaré…

Solamente es importante recordar que la validación del lado del Cliente es importante por rendimiento y usabilidad de la aplicación web… pero por seguridad es inevitable la validación desde el Servidor.

Es decir, si bien es cierto, esta validación nos ahorrará problemas a nosotros y al usuario, siempre debemos pensar más allá, pues como todos sabemos, el JS se puede desactivar facilmente y si no hemos creado una validación desde el servidor, podrán reenviar el formulario mil veces si quieren.

Una buena opción complementaria es que al hacer el “INSERT” en la base de datos, consulte primero la info del ultimo registro ingresado (si almacena horas de transacción mejor), así podemos verificar que no sea exactamente lo mismo lo que se intenta ingresar.

Un saludo!

Joshua
Publicado: 14/03/2014 7:07 pm

Después de varios años sigue siendo buena alternativa en caso de no querer usar Ajax

Diego
Publicado: 19/06/2014 10:11 am

Excelente trabajo, justo lo que necesitaba.. muchas gracias

 

Comentar

En este blog los comentarios están moderados, serán mostrados cuando el administrador los apruebe. Por favor, evita comentarios ofensivos u obscenos por que no serán aprobados.
Si deseas publicar código fuente debes hacerlo entre las etiquedas <code> y </code>, además debes reemplazar los carácteres < por &lt; y > por &gt;.

(Requerido)

(Requerido, no será publicado)

(Requerido)

(Tags aceptados: <a> <em> <strong> <code> <ul> <li>)