Comment convertir tous les éléments de mon formulaire en objet JavaScript?
J'aimerais avoir un moyen de construire automatiquement un objet JavaScript à partir de mon formulaire, sans avoir à parcourir chaque élément. Je ne veux pas de chaîne, telle que renvoyée par $('#formid').serialize();
, ni la carte retournée par$('#formid').serializeArray();
javascript
jquery
json
serialization
Yisroel
la source
la source
Réponses:
serializeArray
fait déjà exactement cela. Vous avez juste besoin de masser les données dans votre format requis:Attention aux champs cachés qui ont le même nom que les entrées réelles car ils seront écrasés.
la source
$.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } );
si vous devez inclure des éléments désactivés.foo[bar]
entrées de type comme prévu, sans parler de la plupart des autres variétés de noms d'entrée. Après avoir été très frustré par des solutions superficielles à ce problème, j'ai fini par écrire mon propre plugin jQuery - détails dans la réponse que j'ai fournie à cette question.Convertir des formulaires en JSON comme un boss
La source actuelle est sur GitHub et Bower .
Le code suivant est désormais obsolète .
Le code suivant peut fonctionner avec toutes sortes de noms d'entrée; et gérez-les comme vous vous en doutez.
Par exemple:
Usage
La sorcellerie (JavaScript)
la source
<select name="foo" multiple="multiple">
ne fonctionnera dans aucun scénario. Cependant, si vous utilisez[]
, comme dans<select name="bar[]" multiple="multiple">
, cela fonctionnera très bien :)Quel est le problème avec:
la source
.each
place de.map
??var form = {}; $.each($(this).serializeArray(), function (i, field) { form[field.name] = field.value || ""; });
$(this).serializeArray().reduce(function(m,o){ m[o.name] = o.value; return m;}, {})
Une version fixe de la solution de Tobias Cohen. Celui-ci gère correctement les valeurs de falsification comme
0
et''
.Et une version CoffeeScript pour votre commodité de codage:
la source
value = @value ? ''
keyMap
et la ligne suivante:key = if keyMap? then keyMap(@name) else @name
. Maintenant, vous pouvez passer la fonction de cartographie comme(name) -> name.match(/\[([^\]]+)]/)[1]
. Et puis il faudrait tout changer@name
aprèskey
, bien sûrpost
, vous pourriez simplement le faire$('form').serializeObject().post
. Pas besoin de cartographie sophistiquée.if (!objectData[this.name].push)
??objectData[this.name]
a la méthode push (en gros, est-ce un tableau). S'il s'agit d'un tableau, il pousse la valeur, s'il ne s'agit pas d'un tableau, il le convertit en tableau afin que plusieurs valeurs avec la même clé soient combinées en un tableau.J'aime utiliser
Array.prototype.reduce
parce que c'est une doublure, et elle ne repose pas sur Underscore.js ou similaire:Ceci est similaire à la réponse utilisée
Array.prototype.map
, mais vous n'avez pas besoin d'encombrer votre portée avec une variable d'objet supplémentaire. Un guichet unique.REMARQUE IMPORTANTE : les formulaires avec des entrées qui ont des
name
attributs en double sont du HTML valide et sont en fait une approche courante. L'utilisation de l'une des réponses de ce fil sera inappropriée dans ce cas (car les clés d'objet doivent être uniques).la source
array.prototype.reduce()
n'est pas disponible dans IE8 car il fait partie de la spécification ECMAScript 5. Donc, si vous avez besoin du support IE8, vous voudrez utiliser un polyfill ou une autre solution.Toutes ces réponses me semblaient tellement exagérées. Il y a quelque chose à dire pour plus de simplicité. Tant que toutes vos entrées de formulaire ont l'attribut name défini, cela devrait fonctionner uniquement avec Jim Dandy.
la source
Il n'y a vraiment aucun moyen de le faire sans examiner chacun des éléments. Ce que vous voulez vraiment savoir, c'est "quelqu'un d'autre a-t-il déjà écrit une méthode qui convertit un formulaire en objet JSON?" Quelque chose comme ce qui suit devrait fonctionner - notez qu'il ne vous donnera que les éléments de formulaire qui seraient retournés via un POST (doit avoir un nom). Ceci n'est pas testé .
la source
Si vous utilisez Underscore.js, vous pouvez utiliser le relativement concis:
la source
J'ai vérifié qu'il y a un problème avec toutes les autres réponses, que si le nom d'entrée est comme un tableau, comme
name[key]
, alors il doit être généré comme ceci:name:{ key : value }
Par exemple: Si vous avez un formulaire HTML similaire à celui ci-dessous:
Mais il doit être généré comme le JSON ci-dessous et ne devient pas un objet comme le suivant avec toutes les autres réponses. Donc, si quelqu'un veut apporter quelque chose comme le JSON suivant, essayez le code JS ci-dessous.
la source
eval
ne doit pas être utilisé de cette façon careval
, lorsqu'il est utilisé de cette manière, favorise des pratiques terriblement peu fiables, buggy, peu performantes et potentiellement non sécurisées.this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
est court et non explicatif. Un développeur avec moins d'expérience copiera simplement ceci sans comprendre pourquoi et comment cela fonctionne.eval()
de mon code.Ok, je sais que cela a déjà une réponse très appréciée, mais une autre question similaire a été posée récemment, et j'ai également été dirigée vers cette question. Je voudrais également proposer ma solution, car elle offre un avantage sur la solution acceptée: vous pouvez inclure des éléments de formulaire désactivés (ce qui est parfois important, selon le fonctionnement de votre interface utilisateur)
Voici ma réponse de l' autre question SO :
Initialement, nous utilisions la
serializeArray()
méthode de jQuery , mais cela n'inclut pas les éléments de formulaire qui sont désactivés. Nous désactiverons souvent les éléments de formulaire qui sont "synchronisés" avec d'autres sources sur la page, mais nous devons toujours inclure les données dans notre objet sérialisé. Il enserializeArray()
va de même. Nous avons utilisé le:input
sélecteur pour obtenir tous les éléments d'entrée (activés et désactivés) dans un conteneur donné, puis$.map()
pour créer notre objet.Notez que pour que cela fonctionne, chacune de vos entrées aura besoin d'un
name
attribut, qui sera le nom de la propriété de l'objet résultant.C'est en fait légèrement modifié de ce que nous avons utilisé. Nous avions besoin de créer un objet qui était structuré en tant que .NET IDictionary, nous l'avons donc utilisé: (je le fournis ici au cas où cela serait utile)
J'aime ces deux solutions, car ce sont des utilisations simples de la
$.map()
fonction, et vous avez un contrôle complet sur votre sélecteur (donc, quels éléments vous finissez par inclure dans votre objet résultant). De plus, aucun plugin supplémentaire n'est requis. Plaine ancienne jQuery.la source
map
comme cela crée un tableau d'objets avec une seule propriété, il ne réduit pas toutes les propriétés en un seul objet.Cette fonction doit gérer des tableaux multidimensionnels ainsi que plusieurs éléments portant le même nom.
Je l'utilise depuis quelques années:
la source
Tu peux le faire:
Voir JSON .
la source
One-liner (pas de dépendances autres que jQuery), utilise une liaison d'objet fixe pour la fonction passée à la
map
méthode.Ce qu'il fait?
adapté aux applications Web progressives (on peut facilement prendre en charge à la fois l'action de soumission de formulaire régulière ainsi que les demandes ajax)
la source
Utilisation:
Production:
la source
La simplicité est meilleure ici. J'ai utilisé un simple remplacement de chaîne par une expression régulière, et ils ont fonctionné comme un charme jusqu'à présent. Je ne suis pas un expert en expression régulière, mais je parie que vous pouvez même remplir des objets très complexes.
la source
D'après une réponse plus ancienne :
la source
serializeArray
, vous avez donc la liberté de choisir les entrées que vous voulez (par exemple, vous pouvez inclure des entrées désactivées), non? C'est à dire que ce n'est pas couplé à une forme ou à l'événement de soumission, c'est juste indépendant par lui-même?reduce
renvoie l'objet. Ce n'est pas indépendant cartoArray
vient de jQuery.J'ai trouvé un problème avec le code de Tobias Cohen (je n'ai pas assez de points pour le commenter directement), qui sinon fonctionne pour moi. Si vous avez deux options de sélection avec le même nom, toutes deux avec value = "", le code d'origine produira "name": "" au lieu de "name": ["", ""]
Je pense que cela peut être corrigé en ajoutant "|| o [this.name] == ''" à la première condition if:
la source
En utilisant la solution de maček , je l'ai modifiée pour fonctionner avec la façon dont ASP.NET MVC gère leurs objets imbriqués / complexes sur le même formulaire. Il vous suffit de modifier la pièce de validation en ceci:
Cela correspondra, puis mappera correctement les éléments avec des noms comme:
Et
la source
le moyen le plus simple et le plus précis que j'ai trouvé pour ce problème était d'utiliser le plugin bbq ou celui- ci (qui fait environ 0,5 K octets).
il fonctionne également avec des tableaux multidimensionnels.
la source
Il existe un plugin pour faire exactement cela pour jQuery, jquery.serializeJSON . Je l'ai utilisé avec succès sur quelques projets maintenant. Il fonctionne comme un charme.
la source
la source
Je préfère cette approche car: vous n'avez pas à parcourir plus de 2 collections, vous pouvez obtenir autre chose que "nom" et "valeur" si vous en avez besoin, et vous pouvez nettoyer vos valeurs avant de les stocker dans l'objet ( si vous avez des valeurs par défaut que vous ne souhaitez pas stocker, par exemple).
Utilisez comme ça:
Uniquement testé dans Firefox.
la source
Transformez n'importe quoi en objet (non testé à l'unité)
La sortie de test:
sur
donnera:
la source
J'ai trouvé un problème avec la solution sélectionnée.
Lorsque vous utilisez des formulaires qui ont des noms basés sur des tableaux, la fonction jQuery serializeArray () meurt réellement.
J'ai un framework PHP qui utilise des noms de champs basés sur des tableaux pour permettre au même formulaire d'être mis sur la même page plusieurs fois dans plusieurs vues. Cela peut être pratique pour mettre à la fois ajouter, modifier et supprimer sur la même page sans modèles de formulaire en conflit.
Comme je voulais séraliser les formulaires sans avoir à retirer cette fonctionnalité de base absolue, j'ai décidé d'écrire mon propre seralizeArray ():
Veuillez noter: cela fonctionne également en dehors du formulaire submit (), donc si une erreur se produit dans le reste de votre code, le formulaire ne sera pas soumis si vous placez sur un bouton de lien disant "enregistrer les modifications".
Notez également que cette fonction ne doit jamais être utilisée pour valider le formulaire uniquement pour collecter les données à envoyer côté serveur pour validation. L'utilisation de ce code faible et assigné en masse provoquera XSS , etc.
la source
J'ai eu le même problème récemment et je suis sorti avec ce plugin .toJSON jQuery qui convertit un formulaire en un objet JSON avec la même structure. Cela est également particulièrement utile pour les formulaires générés dynamiquement où vous souhaitez laisser votre utilisateur ajouter plus de champs à des endroits spécifiques.
Le fait est que vous voudrez peut-être réellement créer un formulaire afin qu'il ait une structure elle-même, alors disons que vous voulez créer un formulaire où l'utilisateur insère ses endroits préférés en ville: vous pouvez imaginer ce formulaire pour représenter un
<places>...</places>
élément XML contenant un liste de lieux l'utilisateur aime ainsi une liste d'<place>...</place>
éléments contenant chacun par exemple un<name>...</name>
élément, un<type>...</type>
élément puis une liste d'<activity>...</activity>
éléments pour représenter les activités que vous pouvez effectuer dans un tel endroit. Donc, votre structure XML serait comme ceci:À quel point ce serait cool d'avoir un objet JSON à partir de cela qui représenterait cette structure exacte afin que vous puissiez soit:
OK, nous devons donc maintenant réfléchir à la manière dont un formulaire peut représenter un fichier XML.
Bien sûr, la
<form>
balise est leroot
, mais nous avons cet<place>
élément qui est un conteneur et non un élément de données lui-même, nous ne pouvons donc pas utiliser de balise d'entrée pour cela.Voici où la
<fieldset>
balise est utile! Nous utiliserons des<fieldset>
balises pour représenter tous les éléments de conteneur dans notre représentation de formulaire / XML et ainsi obtenir un résultat comme celui-ci:Comme vous pouvez le voir dans ce formulaire, nous enfreignons la règle des noms uniques, mais c'est OK car ils seront convertis en un tableau d'éléments donc ils ne seront référencés que par leur index à l'intérieur du tableau.
À ce stade, vous pouvez voir comment il n'y a pas de
name="array[]"
nom similaire dans le formulaire et tout est joli, simple et sémantique.Maintenant, nous voulons que ce formulaire soit converti en un objet JSON qui ressemblera à ceci:
Pour ce faire, j'ai développé ce plugin jQuery ici que quelqu'un a aidé à optimiser dans ce fil de révision de code et ressemble à ceci:
J'ai aussi fait ce blog pour expliquer cela davantage.
Cela convertit tout dans un formulaire en JSON (même radio et cases à cocher) et tout ce qu'il vous reste à faire est d'appeler
Je sais qu'il existe de nombreuses façons de convertir des formulaires en objets JSON et bien sûr
.serialize()
et.serializeArray()
très bien dans la plupart des cas et sont principalement destinés à être utilisés, mais je pense que toute cette idée d' écrire un formulaire comme une structure XML avec des noms significatifs et de le convertir en un Un objet JSON bien formé vaut la peine d'être essayé, le fait que vous puissiez ajouter des balises d'entrée du même nom sans vous inquiéter est très utile si vous devez récupérer des données de formulaires générées dynamiquement.J'espère que ça aidera quelqu'un!
la source
J'ai codé moi-même un formulaire en un objet JavaScript multidimensionnel pour l'utiliser en production. Le résultat est https://github.com/serbanghita/formToObject.js .
la source
Une autre réponse
FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData
la source
[MISE À JOUR 2020]
Avec un simple oneliner en vanille js:
la source
J'aime la version samuels, mais je crois qu'elle a une petite erreur. Normalement, JSON est envoyé en tant que
Pas aussi
donc la fonction IMO devrait se lire:
et de l'envelopper dans un tableau de données (comme cela est généralement prévu aussi), et enfin de l'envoyer sous astring App.stringify ({data: App.toJson ('#cropform: input')})
Pour le regard stratifié à la question 3593046 pour la version allégée, à json2.js pour la version couverte par toutes les éventualités. Cela devrait tout couvrir :)
la source
Pour une solution rapide et moderne, utilisez JSONify plugin jQuery. L'exemple ci-dessous est extrait textuellement du fichier LISEZMOI GitHub. Tout le crédit à Kushal Pandya, auteur du plugin.
Donné:
Fonctionnement:
Produit:
Si vous voulez faire un jQuery POST avec cet objet JSON:
la source