Mam formularz, którego przetworzenie przez serwer zajmuje trochę czasu. Muszę się upewnić, że użytkownik czeka i nie próbuje ponownie przesłać formularza, klikając ponownie przycisk. Próbowałem użyć następującego kodu jQuery:
<script type="text/javascript">
$(document).ready(function() {
$("form#my_form").submit(function() {
$('input').attr('disabled', 'disabled');
$('a').attr('disabled', 'disabled');
return true;
});
});
</script>
Kiedy próbuję tego w Firefoksie, wszystko zostaje wyłączone, ale formularz nie jest przesyłany z żadnymi danymi POST, które powinien zawierać. Nie mogę użyć jQuery do przesłania formularza, ponieważ potrzebuję przycisku do przesłania wraz z formularzem, ponieważ istnieje wiele przycisków przesyłania i określam, który został użyty, przez którą wartość jest uwzględniona w POST. Potrzebuję przesłania formularza tak, jak to zwykle bywa i muszę wszystko wyłączyć zaraz po tym.
Dzięki!
Odpowiedzi:
Aktualizacja w 2018 r . : Właśnie dostałem kilka punktów za tę starą odpowiedź i chciałem tylko dodać, że najlepszym rozwiązaniem byłoby uczynienie operacji idempotentną, aby zduplikowane zgłoszenia były nieszkodliwe.
Np. Jeśli formularz tworzy zamówienie, umieść w formularzu unikalny identyfikator. Gdy serwer po raz pierwszy zobaczy żądanie utworzenia zamówienia o tym identyfikatorze, powinien je utworzyć i odpowiedzieć „sukces”. Kolejne zgłoszenia również powinny odpowiadać „sukces” (w przypadku, gdy klient nie otrzymał pierwszej odpowiedzi), ale nie powinny niczego zmieniać.
Duplikaty powinny być wykrywane przez kontrolę unikalności w bazie danych, aby zapobiec sytuacjom wyścigu.
Myślę, że Twoim problemem jest ta linia:
Wyłączasz WSZYSTKIE dane wejściowe, w tym, jak sądzę, te, których dane ma przesłać formularz.
Aby wyłączyć tylko przyciskiem przedstawienia (S), to mogłaby to zrobić:
Nie sądzę jednak, aby IE przesłał formularz, jeśli nawet te przyciski są wyłączone. Proponuję inne podejście.
Wtyczka jQuery do rozwiązania tego problemu
Właśnie rozwiązaliśmy ten problem za pomocą następującego kodu. Sztuczka polega na tym, że użycie jQuery
data()
do oznaczenia formularza jako już przesłanego lub nie. W ten sposób nie musimy majstrować przy przyciskach przesyłania, co wkurza IE.Użyj tego w ten sposób:
Jeśli istnieją formularze AJAX, które powinny być przesyłane wiele razy podczas ładowania strony, możesz nadać im klasę wskazującą na to, a następnie wykluczyć je ze swojego selektora w następujący sposób:
źródło
$(this)
do avar that = $(this)
?$form
jednak - 'form', ponieważ jest bardziej opisowy i wiodący,$
ponieważ według mojej konwencji oznacza to, że jest to obiekt jQuery.Podejście czasowe jest nieprawidłowe - skąd wiesz, jak długo potrwa działanie w przeglądarce klienta?
Jak to zrobić
Gdy formularz zostanie przesłany, wyłączy wszystkie znajdujące się w nim przyciski przesyłania.
Pamiętaj, że w przeglądarce Firefox po wyłączeniu przycisku ten stan zostanie zapamiętany, gdy wrócisz do historii. Aby temu zapobiec, musisz na przykład włączyć przyciski podczas ładowania strony.
źródło
Myślę, że odpowiedzią Nathana Longa jest droga. W moim przypadku używam walidacji po stronie klienta, więc właśnie dodałem warunek, że formularz jest ważny.
EDYCJA : Jeśli ta opcja nie zostanie dodana, użytkownik nigdy nie będzie mógł przesłać formularza, jeśli walidacja po stronie klienta napotka błąd.
źródło
event.timeStamp
nie działa w przeglądarce Firefox. Zwracanie false jest niestandardowe, powinieneś zadzwonićevent.preventDefault()
. A skoro już o tym mowa , zawsze używaj nawiasów klamrowych z konstrukcją kontrolną .Podsumowując wszystkie poprzednie odpowiedzi, oto wtyczka, która wykonuje zadanie i działa w różnych przeglądarkach.
Aby rozwiązać problem Kern3l, metoda pomiaru czasu działa u mnie po prostu dlatego, że próbujemy zatrzymać dwukrotne kliknięcie przycisku przesyłania. Jeśli masz bardzo długi czas odpowiedzi na zgłoszenie, polecam zastąpienie przycisku wysyłania lub formularza spinnerem.
Całkowite blokowanie kolejnych wysyłek formularza, jak to ma miejsce w większości powyższych przykładów, ma jeden zły efekt uboczny: jeśli wystąpi awaria sieci i chcą spróbować przesłać ponownie, nie byliby w stanie tego zrobić i utraciliby wprowadzone zmiany. zrobiony. To zdecydowanie rozzłościłoby użytkownika.
źródło
Proszę, sprawdź wtyczkę jquery-safeform .
Przykład użycia:
źródło
Poprawny. Wyłączone nazwy / wartości elementów formularza nie będą wysyłane na serwer. Powinieneś ustawić je jako elementy tylko do odczytu .
Ponadto zakotwiczenia nie można w ten sposób wyłączyć. Będziesz musiał albo usunąć ich HREF (niezalecane), albo zapobiec ich domyślnemu zachowaniu (lepszy sposób), np .:
źródło
$('input[type=submit]').attr("disabled", "disabled");
ale moim ulubionym sposobem jest umieszczenieonclick="this.disabled = 'disabled'"
w przycisku onclick przesyłania.Istnieje możliwość ulepszenia podejścia Nathana Longa . Możesz zastąpić logikę wykrywania już przesłanego formularza na następującą:
źródło
Kod Nathana, ale dla wtyczki jQuery Validate
Jeśli zdarzy ci się użyć wtyczki jQuery Validate, mają już zaimplementowaną procedurę obsługi przesyłania, a w takim przypadku nie ma powodu, aby implementować więcej niż jedną. Kod:
Możesz łatwo rozszerzyć go w ramach
} else {
-block, aby wyłączyć wejścia i / lub przycisk przesyłania.Twoje zdrowie
źródło
Skończyło się na tym, że wykorzystałem pomysły z tego postu, aby znaleźć rozwiązanie, które jest dość podobne do wersji AtZako.
Używanie w ten sposób:
Okazało się, że rozwiązania, które nie obejmowały jakiegoś limitu czasu, a jedynie wyłączono przesyłanie lub wyłączone elementy formularza, powodowały problemy, ponieważ po uruchomieniu blokady nie można przesłać ponownie, dopóki nie odświeżysz strony. To sprawia mi pewne problemy podczas robienia rzeczy Ajax.
Można to prawdopodobnie trochę upiększyć, ponieważ nie jest to takie wyszukane.
źródło
Jeśli używasz AJAX do wysyłania formularza, ustawianie
async: false
powinno zapobiegać dodatkowym przesłaniom przed wyczyszczeniem formularza:źródło
Zmodyfikowane nieco rozwiązanie Nathana dla Bootstrap 3. Spowoduje to ustawienie wczytywania tekstu na przycisku wysyłania. Ponadto wygaśnie po 30 sekundach i pozwoli na ponowne przesłanie formularza.
źródło
Użyj dwóch przycisków przesyłania.
Oraz jQuery:
źródło
Użyj prostego licznika podczas przesyłania.
I wywołaj
monitor()
funkcję po przesłaniu formularza.źródło
Miałem podobne problemy, a moje rozwiązania są następujące.
Jeśli nie masz żadnej weryfikacji po stronie klienta, możesz po prostu użyć metody jquery one (), jak opisano tutaj.
http://api.jquery.com/one/
Spowoduje to wyłączenie programu obsługi po jego wywołaniu.
Jeśli przeprowadzasz walidację po stronie klienta, tak jak ja, wtedy jest to nieco trudniejsze. Powyższy przykład nie pozwala na ponowne przesłanie po nieudanej weryfikacji. Zamiast tego wypróbuj to podejście
źródło
Możesz zatrzymać drugie przesyłanie w ten sposób
źródło
Moje rozwiązanie:
źródło
W moim przypadku przesłanie formularza przy przesłaniu zawierało kod weryfikacyjny, więc zwiększam odpowiedź Nathana Longa, w tym punkt kontrolny przy przesłaniu
źródło
Zmień przycisk przesyłania:
Z normalnym przyciskiem:
Następnie użyj funkcji kliknięcia:
I pamiętaj, aby ponownie włączyć przycisk, gdy jest to konieczne:
źródło
Nie mogę uwierzyć w dobrą staromodną sztuczkę CSS dotyczącą zdarzeń wskaźnikowych: żaden nie został jeszcze wspomniany. Miałem ten sam problem, dodając wyłączony atrybut, ale to nie jest wysyłane z powrotem. Wypróbuj poniższe i zamień #SubmitButton na identyfikator swojego przycisku przesyłania.
źródło
Enter
klawisz.Dlaczego nie tylko to - spowoduje to przesłanie formularza, ale również wyłączy przycisk wysyłania,
Ponadto, jeśli używasz jQuery Validate, możesz umieścić te dwie linie poniżej
if ($('#myForm').valid())
.źródło
ten kod wyświetli ładowanie na etykiecie przycisku i ustaw przycisk na
wyłącz stan, a następnie po przetworzeniu włącz ponownie i przywróć oryginalny tekst przycisku **
źródło
Bardzo podobny problem rozwiązałem używając:
źródło