Jak oddzwonić do Jquery po przesłaniu formularza?

119

Mam prosty formularz z remote = true.

Ten formularz znajduje się w oknie dialogowym HTML, które zostaje zamknięte po kliknięciu przycisku Prześlij.

Teraz muszę wprowadzić pewne zmiany na głównej stronie HTML po pomyślnym przesłaniu formularza.

Próbowałem tego za pomocą jQuery. Ale to nie gwarantuje, że zadania zostaną wykonane po jakiejś formie odpowiedzi z przesłania formularza.

$("#myform").submit(function(event) {

// do the task here ..

});

Jak mam dołączyć callback, żeby mój kod był wykonywany dopiero po pomyślnym przesłaniu formularza? Czy istnieje sposób, aby dodać do formularza jakieś wywołanie zwrotne .success lub .complete?

geeky_monster
źródło
Dlaczego nie używasz Ajax? Dzięki funkcjom jQuery Ajax możesz zdefiniować takie wywołania zwrotne.
davidbuzatto
12
davidbuzatto, w niektórych przypadkach nie można użyć Ajax. Na przykład, gdy chcesz przesłać plik.
Pere,
3
@Pere Nie jest to prawda tutaj w przyszłości.
SparK

Odpowiedzi:

119

Właśnie to zrobiłem -

 $("#myform").bind('ajax:complete', function() {

         // tasks to do 


   });

I wszystko działało idealnie.

Więcej szczegółowych informacji można znaleźć w tej dokumentacji interfejsu API .

geeky_monster
źródło
3
Wow ... Właśnie nauczyłem się czegoś nowego. Tak, wygląda na to, że jest to najprostsze rozwiązanie. Być może jest nawet najlepszy. Jestem zapalonym czytelnikiem Coding Horror i na tym blogu Jeff Attwood podkreśla, że ​​powinniśmy pisać mniej kodu, a ta metoda to umożliwia. Dobre znalezisko. :)
Sal
7
A jeśli <form>przesyłane jest zwykle? (To znaczy nie z Ajaxem) Co mogę umieścić w pierwszym argumencie .bind()? EDYCJA: cóż, tak myślę click. Nvm, przepraszam. : p
4wk_
9
uwaga: to uruchomi twoją funkcję po zakończeniu dowolnego zdarzenia Ajax, a nie tylko przesłaniem formularza (chyba że się mylę, w takim przypadku chciałbym, abyś podał link do miejsca, w którym to znalazłeś)
DMac Destroyer
18
„Od jQuery 1.8 metoda .ajaxComplete () powinna być dołączana tylko do dokumentu”
Meredith,
6
U mnie nie działało, używając zwykłego formularza, z przyciskiem, ale przycisk wywołuje javascript $ ('# formFile'). Submit ();
Daniel
35

Nie udało mi się sprawić, aby rozwiązanie numer jeden, które uzyskało poparcie, działało niezawodnie, ale okazało się, że działa. Nie jestem pewien, czy jest to wymagane, czy nie, ale nie mam atrybutu akcji ani metody w tagu, co zapewnia, że ​​POST jest obsługiwany przez funkcję $ .ajax i daje opcję wywołania zwrotnego.

<form id="form">
...
<button type="submit"></button>
</form>

<script>
$(document).ready(function() {
  $("#form_selector").submit(function() {

    $.ajax({
     type: "POST",
      url: "form_handler.php",
      data: $(this).serialize(),
      success: function() {
        // callback code here
       }
    })

  })
})
</script>
Bradley Bossard
źródło
1
+1. Kluczem do tej odpowiedzi jest $(this).serialize()linia. Pozwala jQuery.ajax()przesłać istniejący formularz w tle, a następnie przechwycić odpowiedź z serwera i coś z tym zrobić.
Warren Young,
15
javascript bez średników ... niektórzy chcą po prostu patrzeć, jak świat płonie. Twoje rozwiązanie działa, więc dzięki :)
viggity
2
Zwróć uwagę, że .serializenie obejmuje danych wejściowych pliku w żądaniu POST. Zamiast tego użyj HTML5 FormData (zobacz to pytanie ), chyba że obsługujesz stare przeglądarki, takie jak IE <9
brichins
Podziękowania za używanie $(this).serialize(), to rozwiązało moje problemy!
gnclmorais
co to jest „form_selector” w Twoim html, do którego odwołujesz się w js?
Kevin Meredith
23

Będziesz musiał robić rzeczy ręcznie z wywołaniem AJAX do serwera. Będzie to również wymagało zastąpienia formularza.

Ale nie martw się, to bułka z masłem. Oto przegląd tego, jak będziesz pracować z formularzem:

  • nadpisanie domyślnej akcji przesyłania (dzięki przekazanemu obiektowi zdarzenia, który ma preventDefaultmetodę)
  • pobierz wszystkie niezbędne wartości z formularza
  • odpalić żądanie HTTP
  • obsłużyć odpowiedź na żądanie

Najpierw musisz anulować akcję przesyłania formularza w następujący sposób:

$("#myform").submit(function(event) {
    // Cancels the form's submit action.
    event.preventDefault();
});

A następnie pobierz wartość danych. Załóżmy, że masz jedno pole tekstowe.

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();
});

A potem wystrzel prośbę. Załóżmy tylko, że jest to żądanie POST.

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();

    // I like to use defers :)
    deferred = $.post("http://somewhere.com", { val: val });

    deferred.success(function () {
        // Do your stuff.
    });

    deferred.error(function () {
        // Handle any errors here.
    });
});

I to powinno wystarczyć.

Uwaga 2: do analizowania danych z formularza najlepiej jest użyć wtyczki . Ułatwi ci to życie, a także zapewni przyjemną semantyczną, która naśladuje rzeczywistą akcję składania formularza.

Uwaga 2: nie musisz używać odroczenia. To tylko osobiste preferencje. Możesz również wykonać następujące czynności i to też powinno działać.

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});
Sal
źródło
2
Świetna próbka. Jak zrobić to samo z przesyłaniem plików (wieloczęściowe / dane formularzy) ???
Adam W
11

Dla MVC było to jeszcze łatwiejsze podejście. Musisz użyć formularza Ajax i ustawić AjaxOptions

@using (Ajax.BeginForm("UploadTrainingMedia", "CreateTest", new AjaxOptions() { HttpMethod = "POST", OnComplete = "displayUploadMediaMsg" }, new { enctype = "multipart/form-data", id = "frmUploadTrainingMedia" }))
{ 
  ... html for form
}

tutaj jest kod przesyłania, znajduje się on w sekcji gotowej do dokumentu i wiąże zdarzenie onclick przycisku, aby przesłać formularz

$("#btnSubmitFileUpload").click(function(e){
        e.preventDefault();
        $("#frmUploadTrainingMedia").submit();
});

tutaj jest wywołanie zwrotne, do którego odwołuje się AjaxOptions

function displayUploadMediaMsg(d){
    var rslt = $.parseJSON(d.responseText);
    if (rslt.statusCode == 200){
        $().toastmessage("showSuccessToast", rslt.status);
    }
    else{
        $().toastmessage("showErrorToast", rslt.status);
    }
}

w metodzie kontrolera dla MVC wygląda to tak

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult UploadTrainingMedia(IEnumerable<HttpPostedFileBase> files)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            // there is only one file  ... do something with it
        }
        return Json(new
        {
            statusCode = 200,
            status = "File uploaded",
            file = "",
        }, "text/html");
    }
    else
    {
        return Json(new
        {
            statusCode = 400,
            status = "Unable to upload file",
            file = "",
        }, "text/html");
    }
}
edepperson
źródło
2
Te kody to kody .Net i nigdy go nie podano w pytaniu.
MrMins
13
To naprawdę nie jest dobry powód, by głosować w dół. Odpowiedź działa i może pomóc programiście .NET, który boryka się z tym samym problemem.
edepperson
Podoba mi się ten pomysł, ale z jakiegoś powodu wywołanie zwrotne nie działa. Czy metoda kontrolera musi zwracać JsonResult? Moja metoda kontrolera obecnie zwraca ActionResult.
Mattpm
7

Nie wierzę, że istnieje funkcja zwrotna, taka jak ta, którą opisujesz.

To, co jest tutaj normalne, to dokonywanie zmian za pomocą języka po stronie serwera, takiego jak PHP.

W PHP możesz na przykład pobrać z formularza ukryte pole i dokonać pewnych zmian, jeśli jest obecne.

PHP:

  $someHiddenVar = $_POST["hidden_field"];
    if (!empty($someHiddenVar)) {
        // do something 
    }

Jednym ze sposobów rozwiązania tego problemu w Jquery jest użycie Ajax. Możesz słuchać przesyłania, zwracać false, aby anulować domyślne zachowanie i zamiast tego użyć jQuery.post (). jQuery.post ma udane wywołanie zwrotne.

$.post("test.php", $("#testform").serialize(), function(data) {
  $('.result').html(data);
});

http://api.jquery.com/jQuery.post/

Sindre
źródło
0

Procedury obsługi formularza „przy przesyłaniu” są wywoływane przed przesłaniem formularza. Nie wiem, czy istnieje procedura obsługi, która ma zostać wywołana po przesłaniu formularza. W tradycyjnym sensie innym niż JavaScript przesłanie formularza spowoduje ponowne załadowanie strony.

eel ghEEz
źródło
Chyba że przesłanie formularza przekierowuje do pobierania pliku, w którym to przypadku strona pozostaje nienaruszona. Nie mogę użyć przesyłania JavaScript, ponieważ żądanie Ajax nie może zainicjować pobierania pliku (bez gier z tagiem kotwicy), ale nie mogę też powiedzieć użytkownikowi, aby czekał lub czyścił po otrzymaniu pliku ...
kitsu .eb
-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });
Aikanáro
źródło
3
Czy ajaxForm()zainstalowałeś komponent innej firmy? Nie jest to standardowa część jQuery.
Warren Young,