Comment faire un rappel Jquery après l'envoi du formulaire?

119

J'ai un formulaire simple avec remote = true.

Ce formulaire est en fait sur une boîte de dialogue HTML, qui se ferme dès que le bouton Soumettre est cliqué.

Maintenant, je dois apporter des modifications sur la page HTML principale une fois le formulaire soumis avec succès.

J'ai essayé cela en utilisant jQuery. Mais cela ne garantit pas que les tâches sont effectuées après une forme de réponse de la soumission du formulaire.

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

// do the task here ..

});

Comment attacher un rappel, de sorte que mon code ne soit exécuté qu'une fois le formulaire soumis avec succès? Existe-t-il un moyen d'ajouter un rappel .success ou .complete au formulaire?

geeky_monster
la source
Pourquoi n'utilisez-vous pas Ajax? Avec les fonctions jQuery Ajax, vous pouvez définir de tels rappels.
davidbuzatto
12
davidbuzatto, dans certains cas, vous ne pouvez pas utiliser ajax. Par exemple, lorsque vous souhaitez télécharger un fichier.
Pere
3
@Pere Ce n'est pas vrai ici dans le futur.
SparK

Réponses:

119

Je viens de faire ça -

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

         // tasks to do 


   });

Et les choses ont parfaitement fonctionné.

Consultez cette documentation API pour plus de détails.

geeky_monster
la source
3
Wow ... je viens d'apprendre quelque chose de nouveau. Oui, à première vue, c'est la solution la plus simple. C'est peut-être même le meilleur. Je suis un lecteur avide de Coding Horror, et dans ce blog, Jeff Attwood insiste sur le fait que nous devrions écrire moins de code, et cette méthode y parvient. Bonne trouvaille. :)
Sal
7
Et si le <form>est soumis habituellement? (Je veux dire pas avec Ajax) Que puis-je mettre dans le premier argument de .bind()? EDIT: eh bien, je suppose click. Nvm, désolé. : p
4wk_
9
méfiez-vous: cela va déclencher votre fonction après la fin de tout événement ajax, pas seulement votre soumission de formulaire (sauf si je me trompe, auquel cas j'aimerais que vous fournissiez un lien pour savoir où vous l'avez trouvé)
DMac the Destroyer
18
"Depuis jQuery 1.8, la méthode .ajaxComplete () ne doit être attachée qu'au document"
Meredith
6
Cela n'a pas fonctionné avec moi, en utilisant le formulaire normal, avec un bouton, mais le bouton appelle javascript $ ('# formFile'). Submit ();
Daniel
35

Je n'ai pas pu faire fonctionner de manière fiable la solution numéro un votée positivement, mais j'ai trouvé que cela fonctionne. Je ne sais pas si c'est nécessaire ou non, mais je n'ai pas d'attribut d'action ou de méthode sur la balise, ce qui garantit que le POST est géré par la fonction $ .ajax et vous donne l'option de rappel.

<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
la source
1
+1. La clé de cette réponse est la $(this).serialize()ligne. Il vous permet jQuery.ajax()de soumettre le formulaire existant en arrière-plan, puis d'attraper la réponse du serveur et d'en faire quelque chose.
Warren Young
15
javascript sans point-virgule ... certaines personnes veulent juste regarder le monde brûler. Votre solution fonctionne bien, alors merci :)
viggity
2
Notez que cela .serializen'inclut pas les entrées de fichier dans votre requête POSTée. Utilisez plutôt le HTML5 FormData (voir cette question ) à moins que vous ne preniez en charge d'anciens navigateurs comme IE <9
brichins
Props pour l'utilisation $(this).serialize(), ça a résolu mes problèmes!
gnclmorais
qu'est-ce que 'form_selector' dans votre html que vous référencez dans le js?
Kevin Meredith
23

Vous devrez faire les choses manuellement avec un appel AJAX au serveur. Cela vous obligera également à remplacer le formulaire.

Mais ne vous inquiétez pas, c'est du gâteau. Voici un aperçu de la manière dont vous allez travailler avec votre formulaire:

  • remplacer l'action de soumission par défaut (grâce à l'objet événement passé, qui a une preventDefaultméthode)
  • saisir toutes les valeurs nécessaires du formulaire
  • déclencher une requête HTTP
  • gérer la réponse à la demande

Tout d'abord, vous devrez annuler l'action d'envoi de formulaire comme suit:

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

Et puis, saisissez la valeur des données. Supposons simplement que vous ayez une zone de texte.

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

Et puis lancez une demande. Supposons simplement que ce soit une requête 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.
    });
});

Et cela devrait le faire.

Remarque 2: Pour analyser les données du formulaire, il est préférable d'utiliser un plugin . Cela vous facilitera la vie et vous fournira une belle sémantique qui imite une action de soumission de formulaire réelle.

Remarque 2: Vous n'êtes pas obligé d'utiliser des reports. C'est juste une préférence personnelle. Vous pouvez également faire ce qui suit, et cela devrait également fonctionner.

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});
Sal
la source
2
Excellent échantillon. Comment faire la même chose avec le téléchargement de fichiers (multi-part / form-data) ???
Adam W
11

Pour MVC, c'était une approche encore plus simple. Vous devez utiliser le formulaire Ajax et définir les AjaxOptions

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

voici le code de soumission, il se trouve dans la section document prêt et lie l'événement onclick du bouton à pour soumettre le formulaire

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

voici le callback référencé dans AjaxOptions

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

dans la méthode du contrôleur pour MVC, cela ressemble à ceci

[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
la source
2
Ces codes sont des codes .Net, et dans la question ne l'ont jamais spécifié.
MrMins
13
Ce n'est vraiment pas une bonne raison pour voter contre cela. La réponse fonctionne et pourrait aider un développeur .NET confronté au même problème.
edepperson
J'aime cette idée, mais pour une raison quelconque, le rappel ne se déclenche pas. La méthode du contrôleur doit-elle renvoyer un JsonResult? Ma méthode de contrôleur renvoie actuellement un ActionResult.
mattpm
7

Je ne crois pas qu'il existe une fonction de rappel comme celle que vous décrivez.

Ce qui est normal ici, c'est de faire les modifications en utilisant un langage côté serveur, comme PHP.

En PHP, vous pouvez par exemple récupérer un champ caché de votre formulaire et faire quelques changements s'il est présent.

PHP:

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

Une façon de procéder dans Jquery est d'utiliser Ajax. Vous pouvez écouter pour soumettre, retourner false pour annuler son comportement par défaut et utiliser jQuery.post () à la place. jQuery.post a un rappel de succès.

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

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

Sindre
la source
0

Les gestionnaires «à la soumission» du formulaire sont appelés avant que le formulaire ne soit soumis. Je ne sais pas s'il y a un gestionnaire à appeler après l'envoi du formulaire. Dans le sens traditionnel non Javascript, la soumission du formulaire rechargera la page.

anguille ghEEz
la source
À moins que la soumission du formulaire ne redirige vers un téléchargement de fichier, auquel cas la page reste intacte. Je ne peux pas utiliser la soumission JavaScript car une requête Ajax ne peut pas lancer un téléchargement de fichier (sans jeux de balises d'ancrage), mais je ne peux pas non plus dire à l'utilisateur d'attendre ou de nettoyer une fois qu'il a le fichier ...
kitsu .eb
-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });
Aikanáro
la source
3
Avez ajaxForm()-vous installé un composant tiers? Ce n'est pas une partie standard de jQuery.
Warren Young