2010-05-14 35 views
5

Utilizo jquery's .submit() para interceptar el evento de envío del usuario, sin embargo, encontré un problema.Uso de jquery para evitar volver a enviar el formulario

Cuando el usuario hace clic solo en el botón de enviar, el formulario se envía normalmente, pero si un usuario deliberadamente rápido lo hace varias veces, lo enviará varias veces, lo que causará la duplicación de datos en la base de datos.

¿Cuál es la solución para este tipo de problema?

Actualización: Bueno, veo algunos de los consejos que dicen deshabilitar el botón Enviar. Esto debería evitar que el formulario se envíe varias veces, pero el problema es que el elemento de formulario en mi página no se actualiza, si lo desactivo, el usuario ya no podrá enviarlo, puede que lo deshabilite durante 15 segundos, pero es esta es la forma correcta de resolver este problema?

+0

está usando ajax para enviar el formulario ... causa de discapacidad es bueno si no ajax ... – Reigel

+0

Sí, estoy usando la carga de jQuery. cuando el usuario envía el formulario, aumenta una fila en la tabla. – Sawyer

+0

revise mi respuesta nuevamente si ayuda ... – Reigel

Respuesta

7

La desactivación del botón de envío es de hecho el camino a seguir.

Sin embargo, en muchos casos, la lógica del servidor que se ejecutará depende de la presencia del par nombre-valor del botón de envío en cuestión en el mapa de parámetros de solicitud. Especialmente en marcos MVC basados ​​en componentes del lado del servidor como MS ASP.NET y Sun JSF, pero también en formularios "simples" que tienen más de un botón de envío. El par nombre-valor del botón de envío presionado es obligatorio para determinar la acción que se ejecutará. Al deshabilitar el botón, su par nombre-valor desaparecería por completo en el mapa de parámetros de solicitud y el lado del servidor no tomará ninguna medida ni ejecutará la acción incorrecta.

Hay básicamente 2 maneras de ir alrededor de este:

  1. Uso setTimeout() deshabilitar el botón después de unos pocos milisegundos de manera que su par nombre-valor son enviadas de todos modos. 50 ms es una cantidad asequible.

    $("form").submit(function() { 
        var form = this; 
        setTimeout(function() { 
         $(':submit', form).attr('disabled', true); 
        }, 50); 
    }); 
    
  2. Copiar el par nombre-valor de la realidad presionado botón de enviar en un campo oculto del formulario. Esto es un poco más complicado ya que esta información no está disponible en el evento submit del <form>. Debe dejar que el $(document) capture el último elemento cliqueado.

    $("form").submit(function() { 
        $(':submit', this).attr('disabled', true); 
        $(this).append($('<input/>').attr({ 
         type: 'hidden', 
         name: $.lastClicked.name, 
         value: $.lastClicked.value 
        })); 
    }); 
    
    $(document).click(function(e) { 
        e = e || event; 
        $.lastClicked = e.target || e.srcElement; 
    }); 
    

actualización: según su actualización

Bueno, ver algunos de los consejos dicho deshabilitar el botón de envío. Esto debería evitar que se envíe varias veces, pero el problema es que el elemento de formulario en mi página no se actualiza, si lo desactivo, el usuario ya no podrá enviarlo más, inhabilitarlo durante 15 segundos puede funcionar, pero esto es la forma correcta de resolver este problema?

Así que en realidad estás disparando una solicitud ájica. Simplemente podría volver a habilitar los botones en el controlador de devolución de llamada de la función ajax de jQuery. Suponiendo que está usando jQuery.post:

$("form").submit(function() { 
    // Disable buttons here whatever way you want. 

    var form = this; 
    $.post('some/url', function(data) { 
     // Re-enable buttons at end of the callback handler. 
     $(':submit', form).attr('disabled', false); 
    }); 
}); 
1

intente deshabilitar el botón de enviar el formulario de presentar ....

$("form").submit(function() { 
    $(':submit',this).attr('disabled','disabled'); 
    $('selector').load(url,function(){ 
     $(':submit',this).removeAttr('disabled'); 
    }) 
});​ 

quick demo

+0

Gracias, hombre, mira mi actualización! – Sawyer

+0

¿Qué es "url"? Además, no olvide que presionar Enter envía el formulario. – nickf

+0

@nickf - ¿me gustaría preguntarme también qué es '$ ('selector')'? ... el OP no dio muchos códigos (solo el '.submit()') ... así que estaba asumiendo. .. sí, presionar enter también se enviaría si un cuadro de texto está enfocado y usted presiona enter ... pero de nuevo, dependerá de los códigos del OP ... – Reigel

0

El verdadero problema radica en la capa de base de datos debe estar diseñado para evitar duplicaciones. aquí hay una solución universal pero un poco fea:

Cuando inicialmente hace una página, puede crear un GUID. Digamos, ID de operación. y ponerlo en un estado visual. Cuando procesa un evento en el lado del servidor simplemente inserte este guid en una tabla, diga OngoingOperations donde es una clave principal. La primera inserción tendrá éxito, la otra fallará. Por supuesto, para ser más amigable, puede omitir las operaciones posteriores y devolver el estado de la primera.

La tabla OngoingOperations puede ser similar al siguiente:

CREATE TABLE OngoingOperations ( OperationID uniqueidentifier clave primaria, OperationDate predeterminado de fecha y hora getdate(), OperationStatus nvarchar (max) );

OperationStatus - es el mensaje de estado o cualquier dato para devolver al cliente de presentaciones posteriores. Aquí puede usar una bandera (ok o no) o un mensaje detallado, como lo desee.

esta tabla requiere la recopilación de registros antiguos, por ejemplo, cada hora que acaba de eliminar operaciones con las que completó 2 o más horas antes.

Anton Burtsev

0

Prueba esto:?

$("form").submit(function() { 
    var form = this; 
    setTimeout(function() { 
     $(':submit', form).attr('disabled', true); 
    }, 50); 

    setTimeout(function() { 
     $(':submit', form).removeAttr('disabled'); 
    }, 1000); 
}); 
Cuestiones relacionadas