web-dev-qa-db-fra.com

jquery serialize et $ .post

J'essaie d'envoyer beaucoup de données d'un formulaire en utilisant la méthode $ .post dans jQuery. J'ai d'abord utilisé la fonction serialize () pour transformer toutes les données de formulaire en une longue chaîne que je vais ensuite exploser avec serveride . serialize () à l'URL comme si je l'envoyais à l'aide de GET. Quelqu'un a une idée de la raison pour laquelle cela se produit? 

Voici le jQuery: 

$("#addShowFormSubmit").click(function(){
  var perfTimes = $("#addShowForm").serialize();
  $.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes }, function(data) {
    $("#addShowSuccess").empty().slideDown("slow").append(data);
  });
});  

voici le php: 

$show = $_POST['name'];
$results = $_POST['results'];
$perfs = explode("&", $results);
foreach($perfs as $perf) {
    $perf_key_values = explode("=", $perf);
    $key = urldecode($perf_key_values[0]);
    $values = urldecode($perf_key_values[1]);
}
echo $key, $values;  
22
musoNic80

Si vous utilisez un élément <button> pour activer les options serialize et ajax, et si cet élément <button> se trouve dans l'élément form, button agira automatiquement comme une soumission de formulaire, quelle que soit l'affectation que vous lui attribuez avec jQuery.

type = 'submit'

<button></button> et <button type='submit'></button> sont la même chose. Ils soumettront un formulaire s'ils sont placés dans l'élément <form>.

type = 'bouton'

<button type='button'></button> est différent. Il ne s'agit que d'un bouton normal et le formulaire ne sera pas soumis (sauf si vous le faites volontairement soumettre le formulaire via JavaScript).

Et dans le cas où un élément form n'a aucun attribut d'action spécifié, cette soumission renvoie simplement les données sur la même page. Vous allez donc finir par voir une actualisation de la page, avec les données sérialisées apparaissant dans l'URL comme si vous utilisiez GET dans votre ajax.

Solutions possibles

1 - Faites le <button> tapez button. Comme expliqué ci-dessus, cela empêchera le bouton de soumettre le formulaire.

Avant:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
    <button id='mySubmitButton'>Submit</button>
</form>

Après:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
<button type='button' id='mySubmitButton'>Submit</button>
</form>

2 - Déplacez l'élément <button> en dehors de l'élément <form>. Cela empêchera le bouton de soumettre le formulaire.

Avant:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
    <button id='mySubmitButton'>Submit</button>
</form>

Après:

<form id='myForm'>
    <!--Some inputs, selects, textareas, etc here-->
</form>
<button id='mySubmitButton'>Submit</button>

3 - Ajoutez le preventDefault() au gestionnaire de clic sur le bouton pour empêcher le formulaire d'être soumis (action par défaut):

$("#addShowFormSubmit").click(function(event){
  event.preventDefault();
  var perfTimes = $("#addShowForm").serialize();
  $.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes },      function(data) {
    $("#addShowSuccess").empty().slideDown("slow").append(data);
  });
});

Évidemment, sans voir tout votre code, je ne sais pas si c'est le cas pour votre problème, mais la seule raison pour laquelle j'ai jamais vu le comportement que vous décrivez est parce que le bouton d'envoi était un <button> sans type spécifié.

18
Jake Wilson

essayez d'utiliser serializeArray () au lieu de serialize (). serialize () produira une chaîne de requête codée en URL, alors que serializeArray () produit une structure de données JSON.

7
Franz

Qu'est-ce qui vous fait croire que les données sont ajoutées à l'URL?

Quoi qu'il en soit, ne serait-il pas plus logique de transmettre les valeurs de formulaire dans les données de formulaire elles-mêmes? Cela vous permettra de sauter l'étape "exploser":

$("#addShowFormSubmit")
  .click(function() { 
      var perfTimes = $("#addShowForm").serialize(); 
      $.post("includes/add_show.php", 
         $.param({name: $("#showTitle").val()}) + "&" + perfTimes, 
         function(data) {...}); 
  });
3

Donc c'est probablement un peu obtus, mais j'ai créé une fonction pour m'aider à faire la même chose puisque j'en ai marre de faire des tas de corrections à chaque fois. serializeArray est assez ennuyeux car il fournit une collection d'objets, alors que tout ce que je voulais, c'est que PhP reconstruct soit un tableau associatif. La fonction ci-dessous passera par le tableau sérialisé et construira un nouvel objet avec les propriétés appropriées uniquement lorsqu'une valeur existe.

Tout d'abord, la fonction (il prend l'identifiant du formulaire en question):

function wrapFormValues(form) { 
    form = "#" + form.attr("id") + " :input";
    form = $(form).serializeArray();
    var dataArray = new Object();

    for( index in form)
    {   
        if(form[index].value)   {
            dataArray[form[index].name] = form[index].value;    
        }
    }       

    return dataArray; 
}

Lors de la construction de mes publications, j'utilise aussi généralement un objet, car je marque habituellement deux ou trois autres valeurs avant les données de formulaire et je pense qu'il semble plus simple que de le définir en ligne. La dernière étape est la suivante:

var payload = new Object(); 
//stringify requires json2.js from http://www.json.org/js.html
payload.data = JSON.stringify(data);

$.post("page.php", payload,  
    function(reply) {
        //deal with reply.
    });

Côté serveur, tout ce que vous avez à faire est $payload = json_decode($_POST['data'], true) et vous avez vous-même un tableau associatif où les clés sont les noms de vos champs de formulaire. 

Clause de non-responsabilité complète cependant, la sélection multiple ne fonctionnera probablement pas ici, vous obtiendrez probablement uniquement la dernière valeur sur la liste. Ceci est également créé très spécifiquement pour convenir à l'un de mes projets, vous pouvez donc le modifier pour qu'il vous convienne. Par exemple, j'utilise JSON pour toutes mes réponses du serveur.

2
Vassi

Une autre raison possible de ce problème: si vous avez un formulaire auquel aucune action de soumission n’a été assignée, chaque fois que vous appuierez sur la touche "Entrée" tout en remplissant le formulaire, le formulaire sera soumis à l’URL actuelle. voir les données sérialisées apparaissent dans l'URL comme si vous utilisiez une transaction GET ajax. Une solution simple à ce problème, empêchez simplement ENTER de soumettre le formulaire lorsque vous appuyez dessus:

//Prevent Form Submission when Pressing Enter
$("form").bind("keypress", function(e) {
if (e.keyCode == 13)
    return false;
});
0
Jake Wilson

Essayez cette syntaxe. J'utilise ceci pour sérialiser un formulaire et POST via un appel ajax au service WCF. En outre, vous pouvez renvoyer à cet objet un seul objet JSON au lieu de le construire tel que vous êtes. Essaye ça:

var serializedForm = serializedForm = $("#addShowForm").serializeArray();

$.post("includes/add_show.php", 
    {
        "myObjectName": ("#showTitle").val(), results: perfTimes 
    }, function(data) 
        {
            $("#addShowSuccess").empty()
            .slideDown("slow")
            .append(JSON.stringify(serializedForm)); 
        });
0
Zacho

Sur le côté php, vous voudrez peut-être regarder dans parse_str . Il analysera cette chaîne d'URL en variables ou en un tableau si vous utilisez le deuxième paramètre facultatif.

0
Chris Rasco