2010-10-24 11 views
47

J'ai un formulaire avec deux boutons. Un pour enregistrer un enregistrement et l'autre pour annuler la procédure de sauvegarde. J'utilise le rails.js(un plugin AJAX/jQuery commun pour ceux d'entre vous qui ne sont pas au courant) fichier javascript qui fonctionne avec jQuery pour les appels javascript/ajax discrets. Lorsque j'envoie les données de formulaire sur ajax, je veux que le nom et la valeur du bouton sur lequel j'ai cliqué soient soumis avec le reste des données afin que je puisse prendre une décision sur ce que je dois faire en fonction du bouton sur lequel j'ai cliqué.jQuery serializeArray n'inclut pas le bouton d'envoi sur lequel vous avez cliqué

La méthode du fichier rails.js utilise .serializeArray() pour envoyer des données de formulaire au serveur. Le problème est que cela n'inclut pas la paire nom/valeur du bouton sur lequel j'ai cliqué. le site Web de jQuery déclare qu'ils le font exprès (eventhough son mon avis, ils devraient):

« La méthode .serializeArray() utilise les règles standard W3C pour successful controls de déterminer quels éléments il devrait inclure, en particulier l'élément ne peut pas être désactivé et doit contenir un attribut de nom Aucune valeur de bouton de soumission n'est sérialisée car le formulaire n'a pas été envoyé à l'aide d'un bouton. "

Comment peuvent-ils supposer qu'un formulaire n'a PAS été soumis à l'aide d'un bouton? Cela n'a aucun sens et une mauvaise supposition je crois.

Selon les règles du W3C, le bouton qui a été activé pour la soumission d'un formulaire est considéré comme un contrôle réussi.

Étant donné que les développeurs de jQuery ont décidé de le faire exprès, puis-je supposer qu'il existe une autre méthode qui exclut du bouton activé dans une sérialisation?

EDIT: Voici exemple rapide de ce que ma forme pourrait ressembler ...

<!DOCTYPE html5> 
<html> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js" type="text/javascript"></script> 
<script type="text/javascript"> 
    $(document).ready(function() { 
    $('#form').submit(function(e) { 
     // put your breakpoint here to look at e 
     var x = 0; 
    }); 
    }); 
</script> 
</head> 
<body> 
    <form id="form"> 
    <input name="name" type="text"><br/> 
    <input name="commit" type="submit" value="Save"/> 
    <input name="commit" type="submit" value="Cancel"/> 
    </form> 
</body> 
+2

Pour toute personne qui trouve autre cela, le même problème existe avec la balise ''

Répondre

59

Il n'y a pas, le comportement est basé sur l'événement submitdu<form>, non de un bouton, par exemple frapper entrer ou appeler .submit() en JavaScript. Vous mélangez 2 concepts ici, un .serialize() ou .serializeArray() peut ou peut ne pas avoir quoi que ce soit faire avec un clic de bouton - c'est juste un événement distinct, ils ne sont pas connectés. Ces méthodes à un niveau plus élevé que cela: vous pouvez sérialiser un formulaire (ou un sous-ensemble de celui-ci) à tout moment pour une raison quelconque.

Vous pouvez toutefois ajouter la paire nom/valeur de soumission comme une forme normale de soumettre ce bouton serait, si vous soumettez à partir d'un bouton par exemple:

$("#mySubmit").click(function() { 
    var formData = $(this).closest('form').serializeArray(); 
    formData.push({ name: this.name, value: this.value }); 
    //now use formData, it includes the submit button 
}); 
+0

@Nick, merci pour la réponse rapide.Je vais avoir éditer le 'rails.js' (et éventuellement soumettre un patch) pour que cela fonctionne. Je vais donner un coup de feu. – DJTripleThreat

+0

@DJTripleThreat - Je ne suis pas familier avec leur code, est-il possible de remplacer le gestionnaire d'événements à l'extérieur peut-être? Si vous pouviez le poster je vais jeter un coup d'oeil –

+0

@Nick - consultez le fichier sur gh: http://github.com/rails/jquery-ujs/blob/master/src/rails.js. Regardez le gestionnaire sur les lignes 34 et 76. Existe-t-il un moyen de savoir quel bouton a été cliqué dans l'objet 'event' passé par' .submit (function (e) {}) '? – DJTripleThreat

4

J'utilise l'extrait suivant, ajoute essentiellement un élément caché avec le même nom

var form = $("form"); 
$(":submit",form).click(function(){ 
      if($(this).attr('name')) { 
       $(form).append(
        $("<input type='hidden'>").attr({ 
         name: $(this).attr('name'), 
         value: $(this).attr('value') }) 
       ); 
      } 
     }); 

$(form).submit(function(){ 
    console.log($(this).serializeArray()); 
}); 
3

Cette solution est « universel » comme il traitera tous vos commentaires soumet, en passant chacun comme une variable de formulaire sur demande.

$(document).ready(function(){ 
    $('input:submit').each(function(){ 
     $(this).click(function(){ 
      var formData = $(this).closest('form').serializeArray(); 
      formData.push({ name: $(this).attr('name'), value: $(this).val() }); 
     }); 
    }); 
}); 
+2

Vous n'avez pas besoin de l'appel 'each' - juste appelez' click' directement sur l'objet jquery représentant tous les éléments d'entrée – SpoonMeiser

0
var form = button.closest('form'); 
    var serialize = form.serialize(); 

    if (button.attr('name') !== undefined) { 
     serialize += '&'+button.attr('name')+'='; 
    }