2009-03-20 5 views
17

byłem obserwując niektóre dziwne zachowanie z następującego kodu:

$.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(); 

Więc w zasadzie, na wywołanie submit_to_remote na zasadzie formularz (y), wyłączy to normalne przesłanie, a następnie złoży zapytanie o POST AJAX.

Dziwne jest to, że formularz jest wysyłany wiele razy, ponieważ pojawi się komunikat "wyłączony". Jak widzisz, zapobiegam temu, używając "zmiennej" zapisanej w obiekcie formularza i sprawdzając tę ​​zmienną, aby zobaczyć, czy formularz został już przesłany.

Po dalszych testach wydaje się, że winowajcą jest skrypt zwrócony przez wywołanie AJAX. Pozwól mi wyjaśnić nieco, co robię, więc jest bardziej zrozumiały.

Formularz zostanie opublikowany na serwerze i zwrócony zostanie skrypt. Skrypt ponownie pokazuje formularz, ale tym razem z komunikatami o błędach dla niektórych pól. Zwróć uwagę, że formularz został całkowicie zastąpiony.

Skrypt, po przedstawiający nową formę, wykonuje to:

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

muszę zrobić, bo inaczej, po kliknięciu na przycisk złożyć ponownie, formularz jest składany normalnie, bez AJAX.

Załóżmy, że użytkownik przesyła formularz i jest on zwracany z odpowiednimi błędami (alert "wyłączony" nie jest wyświetlany). Następnie składa to ponownie; tym razem alert "wyłączony" jest wyświetlany jeden raz. Teraz przesyła go jeszcze raz i tym razem alert jest wyświetlany dwukrotnie! I tak dalej ...

Wygląda na to, że wywołanie zwrotne .submit jest dołączane wielokrotnie przy każdym żądaniu, ale dlaczego?

Czy to możliwe, że przy użyciu .html() oryginalna forma jest trzymana jako duch czy coś?

Dzięki!

PS: W przypadku jest to istotne, oto skrypt zwrócony przez wywołanie $ .ajax:

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

Odpowiedz

4

Nie wiesz o tym dziwnego zachowania, ale wydaje się, że Rozpinanie zdarzenie przedstawienia rade.

Tak więc, przed uruchomieniem skryptu zwrócony przez wywołanie $ .ajax, uruchom to:

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

To powinno usunąć poprzednie powiązania i pozostawić tylko nowe.

+0

Zapomniałem wspomnieć, że próbowałem tego również, ale to dziwnie nie działa, ponieważ wtedy nowa forma nie będzie miała zachowania AJAX, nawet czy wiążę je ze skryptem ... – Ivan

+0

+1 Mogłem użyć tego jako rozwiązania tutaj: http://stackoverflow.com/questions/12340484/duplicated-entries-to-mysql-using-jquery-ajax-and-php/12340646#12340646 –

52

Tak, zgadzam się z Sebem, to jest dobra praktyka, moim zdaniem, aby zawsze się wiązać przed wiązaniem, chyba że masz pewność, że aktualnie nie wiążą się z twoim żywiołem. Możesz podwoić swoje rzeczy na wypadek, używając po prostu funkcji ".submit", ".click", ".mouseover", etc ....

Nabierz zwyczaju robić to (nigdy nie dla mnie):

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

...zamiast:

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

Pracowałem świetnie dla mnie –

+1

Ooh Dzięki, Dude to zapisz się na mój Weekend :) Pozdrawiam – chhameed

+0

Próbuję tego, ale w moim przypadku istnieje zgłoszenie formularza, ale jeśli zaktualizuję treść formularza, a następnie ponownie go prześlę, przesyłaj zamiast tego oryginalną treść . Jeśli tego nie zrobię, mam przyrostową formę przesłania (1, 2, 3 itd.). – Mike

9

Unbind nie działał dla mnie. Ten zrobił:

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

Mam nadzieję, że to pomaga ...

W rzeczywistości Unbind() może przynieść pewne problemy, jeśli masz jakieś walidacji i wrócić przed wysłaniem. Przykład:

$(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 
}); 

W tym przypadku, jeśli wejście jest „niewłaściwa nazwa” formularz nie zostanie złożony, a po tym, kiedy można umieścić nazwę „prawo”, to $ (document) .Na („submit” .. nie zostanie wyzwolony, ani e.preventDefault(); i twoja postać zostanie przedstawiony w regularny sposób

+0

Dzięki - to jest dokładnie to, czego potrzebowałem – Laurence

1

należy pamiętać, że jQuery submit() zdarzenie wygląda na: <input type="submit">, <input type="image">, or <button type="submit"> w postaci (http://api.jquery.com/submit/. Niektóre frameworki domyślnie używają atrybutu type "submit", więc jeśli próbujesz przesłonić wartość domyślną, zmień atrybut type na inny, aby nie był przesyłany wiele razy.

0

Podwójne przesłanie OpenCart dzieje się, ponieważ istnieje powiązanie przesyłania w common.js.

Unikaj tego, używając wzoru id dla formularza, który ma , a nie mecz "form-".

Przykład: <form id="myform" >.

0

można użyć tego kodu, aby rozwiązać:

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

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

jest jeszcze prostsze:

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

miałem ten sam problem i stała jak poniżej za pomocą kliknięcia.

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