2009-03-20 53 views
17

he estado observando un comportamiento extraño con el siguiente código:

$.fn.submit_to_remote = function() { 
    // I use .each instead of the .submit directly so I can save 
    // the 'submitEnabled' variable separately for each form 
    jQuery.each($(this), function() { 
    $(this).submit(function() { 
     form = $(this); 
     if (form.data('submitEnabled') == false) { alert('disabled'); return false; } 
     form.data('submitEnabled', false); 
     $.ajax({type: 'POST', url: 'url', data: data, dataType: 'script', 
     success: function(script) { 
      alert('success') 
     } 
     }) 
     return false; 
    }) 
    }) 
} 
$('.submit_to_remote').submit_to_remote(); 

Así que, básicamente, al llamar submit_to_remote en una formulario (s), deshabilitará su envío normal y luego realizará una solicitud AJAX POST.

Lo extraño es que el formulario se publica varias veces, ya que se mostrará la alerta "deshabilitada". Como puede ver, lo estoy evitando al usar una "variable" guardada en el objeto de formulario, y verificando esa variable para ver si el formulario ya se ha enviado.

Al realizar más pruebas, parece que el culpable es la secuencia de comandos devuelta por la llamada AJAX. Déjame explicar un poco lo que estoy haciendo, así que es más claro.

El formulario se publica en el servidor y se devuelve un script. La secuencia de comandos muestra el formulario nuevamente, pero esta vez con mensajes de error para algunos campos. Tenga en cuenta que el formulario es completamente reemplazado.

El guión, al mostrar la nueva forma, ejecuta esto:

$('.submit_to_remote').submit_to_remote(); 

tengo que hacerlo porque de lo contrario, al hacer clic en el botón de enviar de nuevo, el formulario se envía normalmente, sin AJAX.

Por lo tanto, supongamos que un usuario envía el formulario y lo devuelve con los errores apropiados (no se muestra la alerta "deshabilitada"). Luego lo vuelve a enviar; esta vez la alerta 'deshabilitada' se muestra una vez. Ahora lo envía una vez más, ¡y esta vez la alerta se muestra dos veces! Y así sucesivamente ...

Parece que la reenvío de .submit se está añadiendo una y otra vez a cada solicitud, pero ¿por qué?

¿Podría ser que al usar .html() la forma original se guarda como un fantasma o algo así?

Gracias!

PD: En caso de que sea relevante, aquí está la secuencia de comandos que devuelve la llamada $ .ajax:

replace_content_with = 'the form and other stuff here'; 
$('.page-content').html(replace_content_with); 
$('.submit_to_remote').submit_to_remote(); 

Respuesta

4

No está seguro acerca de este comportamiento extraño, pero parece que desatar el evento presentará hará el truco.

lo tanto, antes de ejecutar el script devuelve la llamada a $ .ajax, ejecute lo siguiente:

$('.submit_to_remote').unbind("submit"); 

Eso debería eliminar fijaciones anteriores y dejar sólo la nueva.

+0

me olvidó mencionar que he intentado también, pero que extrañamente no funciona porque entonces el nuevo formulario no tendrá el comportamiento AJAX, incluso hago que estoy re-unión con el guión ... – Ivan

+0

+1 Pude usar esto como una solución aquí: http://stackoverflow.com/questions/12340484/duplicated-entries-to-mysql-using-jquery-ajax-and-php/12340646#12340646 –

52

Sí, estoy de acuerdo con Seb, es una buena práctica, en mi opinión para desvincular siempre antes de la vinculación a menos que esté seguro de que actualmente no se vincula a su elemento que desea. Puedes vincular tus cosas por accidente con solo usar las funciones '.submit', '.click', '.mouseover', etc ...

entrar en el hábito de hacer esto (nunca falla para mí):

$('.some_element').unbind('submit').bind('submit',function() { 
    // do stuff here... 
}); 

...en lugar de:

$('.some_element').submit(function() { 
    // do stuff here... 
}); 
+2

Funcionó muy bien para mí –

+1

Ooh Gracias Amigo guarde es mi fin de semana :) aplausos – chhameed

+0

Intento esto, pero en mi caso hay un formulario enviado, pero si actualizo el contenido del formulario, y lo presento, el envío envía el contenido original en su lugar . Si no estoy haciendo esto, tengo envío de formulario incremental (1, 2, 3, etc.). – Mike

9

Desvinculación no funcionó para mí. Esto hizo:

$(document).off('submit'); 
$(document).on('submit',"#element_id",function(e){ 
    e.preventDefault(); 
    //do something 
}); 

espero que ayude ...

De hecho unbind() que puede traer algunas dificultades si tiene alguna validación y volver antes de enviarlo. Ejemplo:

$(document).on('submit',"#element_id",function(e){ 
    e.preventDefault(); 
    $(document).unbind('submit'); 
    var name = $(this).children('input[name="name"]').val(); 
    if(name == 'wrong name') 
     return; 

    //do something 
}); 

En este caso, si la entrada es 'nombre equivocado' el formulario no será enviado y después de eso, cuando se pone el "nombre correcto", el $ (document) .en ('submit' .. no se activará, ni el e.preventDefault(), y su forma se presentará en la forma habitual

+0

Gracias - esto es exactamente lo que necesitaba – Laurence

1

Tenga en cuenta que la presente jQuery() evento busca: <input type="submit">, <input type="image">, or <button type="submit"> en la forma (http://api.jquery.com/submit/.). Algunos marcos predeterminan el atributo de tipo para "enviar", por lo que si está intentando anular el valor predeterminado, cambie el atributo de tipo por otro para que no se envíe varias veces.

0

El envío doble de OpenCart ocurre porque hay un enlace de envío en common.js.

Evite esto mediante el uso de un patrón de identificación para el formulario que no no coincida con "form-".

Ejemplo: <form id="myform" >.

0

puede utilizar este código para resolver:

$(this).submit(function() { 
. 
. 
. 
}); 

$(this).unbind("submit"); 
1

Más fácil aún es:

$(".some-class").off().submit(function() { 
    //Do stuff here 
}); 
0

que tenían el mismo problema y se fijan como a continuación mediante clic.

$('.submit_to_remote').on('click', function(){ 
//Some validation or other stuff 
$(this).submit(); 
}); 
Cuestiones relacionadas