305 votes

Sérialiser les données du formulaire en JSON

Je souhaite effectuer une pré-validation serveur d'un formulaire dans un fichier Backbone.js modèle. Pour ce faire, je dois transformer les données saisies par l'utilisateur dans un formulaire en données utilisables. J'ai trouvé trois méthodes pour y parvenir :

  1. var input = $("#inputId").val();
  2. var input = $("form.login").serialize();
  3. var input = $("form.login").serializeArray();

Malheureusement, aucun d'entre eux ne fournit un bon objet JSON réutilisable et développable dont j'ai besoin. J'ai déjà regardé plusieurs questions sur Stack Overflow, mais je n'ai trouvé que quelques bibliothèques supplémentaires.

N'est pas Underscore.js La version actuelle de jQuery ou Backbone.js fournit-elle une méthode d'aide ?

Je ne peux pas imaginer qu'il n'y ait pas de demande pour une telle fonction.

HTML

<form class="login">
    <label for="_user_name">username:</label>
    <input type="text" id="_user_name" name="user[name]" value="dev.pus" />
    <label for="_user_pass">password:</label>
    <input type="password" id="_user_pass" name="user[pass]" value="1234" />
    <button type="submit">login</button>
</form>

JavaScript

var formData = $("form.login").serializeObject();
console.log(formData);

Sorties

{
    "name": "dev.pus",
    "pass": "1234"
}

Modèle Backbone.js

var user = new User(formData);
user.save();

1 votes

JQuery dispose d'un plugin pour jSON : code.google.com/p/jquery-json il n'inclut pas de méthode d'aide.

5 votes

Qu'est-ce qui ne va pas avec .serializeArray() ?

2 votes

J'en ai besoin pour les formulaires, je m'interroge sur le fait que trois frameworks ne proposent pas de mappeur de formulaire...

312voto

Maciej Pyszyński Points 2113

Voici une fonction pour ce cas d'utilisation :

function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        indexed_array[n['name']] = n['value'];
    });

    return indexed_array;
}

Utilisation :

var $form = $("#form_data");
var data = getFormData($form);

0 votes

Il se rapproche. J'ai mis à jour le fil de discussion de départ sur la façon dont je pensais qu'il devrait ressembler...

9 votes

Les codes écrasent les clés portant le même nom. Vous devriez vérifier si indexed_array[n['name']] existe déjà et si c'est le cas le convertir en tableau et y ajouter la n['value']. Bien entendu, vous devez également vérifier si indexed_array[n['name']] est déjà un tableau.

19 votes

Le nom doit être TOUJOURS unique (les boutons radio ne peuvent avoir qu'une seule valeur !), et s'il ne l'est pas, seule la dernière occurrence du champ dont le nom est répété est envoyée avec la demande. Si vous souhaitez créer une structure de tableau à plusieurs niveaux, vous devez détecter les crochets et, à partir de cette information, construire des tableaux multidimensionnels. Astuce : entourez la première partie du nom du champ de crochets, par exemple somefield[2] => [somefield][2] et utiliser eval pour assigner une valeur eval('you_array_varialbe'+bracketed_field_name+'=\''+n['valu‌​e']+'\'')

174voto

Mohammad Adil Points 25444

Vous pouvez le faire :

function onSubmit( form ){
  var data = JSON.stringify( $(form).serializeArray() ); //  <-----------

  console.log( data );
  return false; //don't submit
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form onsubmit='return onSubmit(this)'>
  <input name='user' placeholder='user'><br>
  <input name='password' type='password' placeholder='password'><br>
  <button type='submit'>Try</button>
</form>

voir ceci : http://www.json.org/js.html

73 votes

Bonjour, pas tout à fait. J'obtiens quelque chose comme {"name" : "user[name]" value : "dev.pus" } mais je veux { "name" : "dev.pus", "password" : "1234" } etc.

2 votes

@dev.pus : Il se peut que vous deviez le gérer au format [{"name" : "username", "value" : "foo"}]. Sinon, vous ne pouvez pas gérer plusieurs éléments portant le même nom.

15 votes

Si vous n'aviez pas plusieurs éléments avec les mêmes noms, vous pourriez facilement traduire les données du formulaire en une chaîne JSON comme ceci : var myjson = {} ; $.each(allFormTags, function() { myjson[this.name] = this.value ; }) ;

87voto

STEEL Points 649

Le code ci-dessous devrait vous aider :)

 //The function is based on http://css-tricks.com/snippets/jquery/serialize-form-to-json/
 <script src="//code.jquery.com/jquery-2.1.0.min.js"></script>

<script>
    $.fn.serializeObject = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };

    $(function() {
        $('form.login').on('submit', function(e) {
          e.preventDefault();

          var formData = $(this).serializeObject();
          console.log(formData);
          $('.datahere').html(formData);
        });
    });
</script>

0 votes

C'est génial, merci ! Quelqu'un sait-il si cela fonctionnera pour le téléchargement de fichiers ?

0 votes

@AaronMatthews Le téléchargement de fichiers utilise un objet Blob, ce qui ne fonctionne pas.

5 votes

Cette fonction n'est pas seulement "basée sur", elle est la fonction à partir de ce lien. C'est une bonne chose que Les astuces CSS vous donnent la permission .

46voto

Bny Points 3197

Utiliser :

var config = {};
jQuery(form).serializeArray().map(function(item) {
    if ( config[item.name] ) {
        if ( typeof(config[item.name]) === "string" ) {
            config[item.name] = [config[item.name]];
        }
        config[item.name].push(item.value);
    } else {
        config[item.name] = item.value;
    }
});

2 votes

Il ne s'agit pas d'une solution générale ; un formulaire peut avoir plusieurs valeurs pour la même clé. Cette fonction ne retiendra que la dernière valeur.

1 votes

En effet, réponse adaptée - merci

0 votes

La dernière valeur est la méthode standard, très utile pour écraser les valeurs précédentes.

37voto

ryanday Points 1367

Je sais que cela ne répond pas aux exigences de la fonction d'aide, mais j'ai utilisé la méthode $.each() de jQuery.

var loginForm = $('.login').serializeArray();
var loginFormObject = {};
$.each(loginForm,
    function(i, v) {
        loginFormObject[v.name] = v.value;
    });

Ensuite, je peux passer loginFormObject à mon backend, ou vous pouvez créer un userobject et le sauvegarder() dans le backbone également.

0 votes

Cette solution est simple et agréable, et semble répondre parfaitement à mes besoins actuels. C'est du bon travail !

0 votes

J'ai essayé de l'utiliser pour moi-même comme solution de contournement pour d'autres problèmes, mais j'ai trouvé un problème ici. Sur un site web réalisé via ASP.NET MVC (vue de style Razor), le code génère une case à cocher visible et une entrée cachée. En utilisant votre code, loginForm contenait les deux entrées (si la case était cochée), false seulement otherweise) et loginFormObject a ensuite obtenu la deuxième entrée, qui était toujours false . Solution ici : dans la sous-fonction de la each ajouter la ligne suivante après la ligne { : if(formObject[v.name] != "true") . Cela permet de préserver la true .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X