web-dev-qa-db-fra.com

jQuery serializeArray n'inclut pas le bouton d'envoi qui a été cliqué

J'ai un formulaire qui a deux boutons. L'un pour sauvegarder un enregistrement et l'autre pour annuler la procédure de sauvegarde. J'utilise le Rails.js (un plug-in AJAX/jQuery commun pour ceux d'entre vous qui ne le savent pas) Fichier javascript qui fonctionne avec jQuery pour un javascript discret/appels ajax. Lorsque j'envoie les données du formulaire via ajax, je souhaite que le nom et la valeur du bouton sur lequel j'ai cliqué soient soumis avec le reste des données afin de pouvoir décider quoi faire en fonction du bouton sur lequel vous avez cliqué.

La méthode du fichier Rails.js Utilise .serializeArray() pour envoyer les données du 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 (même si je pense qu'ils le devraient):

"La méthode .serializeArray() utilise les règles standard du W3C pour contrôles réussis pour déterminer les éléments à inclure; en particulier, l'élément ne peut pas être désactivé et doit contenir un attribut de nom. Aucun bouton d'envoi La valeur est sérialisée car le formulaire n'a pas été soumis à 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 hypothèse erronée, 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 NE FAIT PAS exclure le bouton activé dans une sérialisation ?

EDIT: Voici un exemple rapide de ce à quoi pourrait ressembler mon formulaire ...

<!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>
55
aarona

Il n'y en a pas, le comportement est basé sur l'événement submit du <form>, Pas d'un bouton , p.ex. appuyer sur Entrée 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 à voir avec un clic sur un bouton - c'est juste un événement séparé, ils ne sont pas connectés. Ces méthodes à un niveau supérieur à celui: vous pouvez sérialiser un formulaire (ou un sous-ensemble de celui-ci) à tout moment pour n'importe quelle raison.

Vous pouvez cependant ajouter la paire nom/valeur de soumission comme le ferait un formulaire normal soumis à partir de ce bouton, 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
});
67
Nick Craver

J'utilise l'extrait de code 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());
 });
7
digitalPBK

moyen assez soigné pour résoudre ce problème:

<form>
    <input type="hidden" name="stuff" value="">
    <button type="submit" onclick="this.form.stuff.value=this.value" value="reset">reset</button>
    <button type="submit" onclick="this.form.stuff.value=this.value" value="delete">delete</button>
</form>
4
commonpike

Cette solution est "universelle" car elle gérera toutes vos soumissions d'entrée, en les transmettant chacune sous forme de variable de formulaire lors de la soumission.

$(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() });
        });
    });
});
4
Robert Waddell
    var form = button.closest('form');
    var serialize = form.serialize();

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