Come fare una richiamata Jquery dopo l'invio del modulo?


119

Ho un modulo semplice con remote = true.

Questo modulo si trova in realtà su una finestra di dialogo HTML, che viene chiusa non appena si fa clic sul pulsante Invia.

Ora devo apportare alcune modifiche alla pagina HTML principale dopo che il modulo è stato inviato correttamente.

L'ho provato usando jQuery. Ma questo non garantisce che le attività vengano eseguite dopo una qualche forma di risposta dell'invio del modulo.

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

// do the task here ..

});

Come allegare una richiamata, in modo che il mio codice venga eseguito solo dopo che il modulo è stato inviato con successo? Esiste un modo per aggiungere un callback .success o .complete al modulo?


Perché non usi Ajax? Con le funzioni jQuery Ajax è possibile definire tali callback.
davidbuzatto

12
davidbuzatto, ci sono alcuni casi in cui non puoi usare ajax. Ad esempio, quando vuoi caricare un file.
Pere

3
@ Pere Not true qui in futuro.
SparK

Risposte:


119

Ho appena fatto questo -

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

         // tasks to do 


   });

E le cose hanno funzionato perfettamente.

Vedi questa documentazione api per dettagli più specifici.


3
Wow ... ho appena imparato qualcosa di nuovo. Sì, a quanto pare, questa è la soluzione più semplice. Forse è anche il migliore. Sono un avido lettore di Coding Horror e in quel blog, Jeff Attwood sottolinea che dovremmo scrivere meno codice e questo metodo lo raggiunge. Buona scoperta. :)
Sal

7
E se la <form>viene presentata di solito? (Intendo non con Ajax) Cosa posso inserire nel primo argomento di .bind()? EDIT: beh, immagino click. Nvm, scusa. : p
4wk_

9
attenzione: questo attiverà la tua funzione dopo il completamento di qualsiasi evento ajax, non solo l'invio del modulo (a meno che non mi sbagli, nel qual caso mi piacerebbe che tu
fornissi

18
"A partire da jQuery 1.8, il metodo .ajaxComplete () dovrebbe essere allegato solo al documento"
Meredith

6
Non ha funzionato da me, utilizzando il modulo normale, con un pulsante, ma il pulsante chiama javascript $ ('# formFile'). Submit ();
Daniel

35

Non sono riuscito a far funzionare in modo affidabile la soluzione votata al massimo numero uno, ma ho trovato che funziona. Non sono sicuro se sia richiesto o meno, ma non ho un attributo action o method sul tag, che garantisce che il POST sia gestito dalla funzione $ .ajax e ti dia l'opzione di callback.

<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>

1
+1. La chiave di questa risposta è la $(this).serialize()linea. Ti consente jQuery.ajax()di inviare il modulo esistente in background, quindi catturare la risposta dal server e fare qualcosa con esso.
Warren Young,

15
javascript senza punto e virgola ... alcune persone vogliono solo vedere il mondo bruciare. La tua soluzione funziona, quindi grazie :)
viggity

2
Tieni presente che .serializenon include gli input di file nella richiesta POST. Utilizzare invece il FormData HTML5 (vedere questa domanda ) a meno che non si supportino vecchi browser come IE <9
brichins

Puntelli per l'utilizzo $(this).serialize(), ha risolto i miei problemi!
gnclmorais

cos'è 'form_selector' nel tuo html a cui fai riferimento nel js?
Kevin Meredith

23

Dovrai fare le cose manualmente con una chiamata AJAX al server. Ciò richiederà di sovrascrivere anche il modulo.

Ma non preoccuparti, è un gioco da ragazzi. Ecco una panoramica su come lavorerai con il tuo modulo:

  • sovrascrive l'azione di invio predefinita (grazie all'oggetto evento passato, che ha un'estensione preventDefault metodo)
  • prendi tutti i valori necessari dal modulo
  • lancia una richiesta HTTP
  • gestire la risposta alla richiesta

Per prima cosa, dovrai annullare l'azione di invio del modulo in questo modo:

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

E poi, prendi il valore dei dati. Supponiamo che tu abbia una casella di testo.

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

E poi lancia una richiesta. Supponiamo solo che sia una richiesta 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.
    });
});

E questo dovrebbe farlo.

Nota 2: per analizzare i dati del modulo, è preferibile utilizzare un plug-in . Ti renderà la vita davvero facile, oltre a fornire una bella semantica che imita un'effettiva azione di invio del modulo.

Nota 2: non è necessario utilizzare i rinvii. È solo una preferenza personale. Puoi ugualmente fare quanto segue e dovrebbe funzionare anche.

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});

2
Ottimo campione. Come fare la stessa cosa con il caricamento del file (multiparte / dati del modulo) ???
Adam W

11

Per MVC questo è stato un approccio ancora più semplice. È necessario utilizzare il modulo Ajax e impostare AjaxOptions

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

ecco il codice di invio, questo è nella sezione documento pronto e lega l'evento onclick del pulsante a per inviare il modulo

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

ecco il callback a cui si fa riferimento nelle AjaxOptions

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

nel metodo controller per MVC è simile a questo

[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");
    }
}

2
Quei codici sono codici .Net e nella domanda non lo hanno mai specificato.
MrMins

13
Questa non è davvero una buona ragione per votare a favore. La risposta funziona e potrebbe aiutare uno sviluppatore .NET che sta affrontando lo stesso problema.
edepperson

Mi piace questa idea, ma per qualche motivo la richiamata non viene attivata. Il metodo del controller deve restituire un JsonResult? Il metodo del controller attualmente restituisce un ActionResult.
Mattpm

7

Non credo che ci sia una funzione di callback come quella che descrivi.

Ciò che è normale qui è eseguire le modifiche utilizzando un linguaggio lato server, come PHP.

In PHP potresti, ad esempio, recuperare un campo nascosto dal tuo modulo e apportare alcune modifiche se è presente.

PHP:

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

Un modo per farlo in Jquery è usare Ajax. Puoi ascoltare per submit, restituire false per annullare il suo comportamento predefinito e utilizzare invece jQuery.post (). jQuery.post ha un callback di successo.

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

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


0

I gestori "on submit" del modulo vengono chiamati prima che il modulo venga inviato. Non so se c'è un gestore da chiamare dopo l'invio del modulo. Nel tradizionale senso non Javascript, l'invio del modulo ricaricherà la pagina.


A meno che l'invio del modulo non reindirizzi a un download di file, nel qual caso la pagina viene lasciata intatta. Non posso usare l'invio JavaScript perché una richiesta Ajax non può avviare il download di un file (senza giochi di anchor tag), ma non posso nemmeno dire all'utente di aspettare o pulire una volta che ha il file ...
kitsu .eb

-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });

3
È ajaxForm()un componente di terze parti che hai installato? Non è una parte standard di jQuery.
Warren Young,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.