¿Cómo convierto todos los elementos de mi formulario en un objeto JavaScript?
Me gustaría tener alguna forma de crear automáticamente un objeto JavaScript a partir de mi formulario, sin tener que recorrer cada elemento. No quiero una cadena, como la devuelta $('#formid').serialize();
, ni quiero que el mapa sea devuelto por$('#formid').serializeArray();
javascript
jquery
json
serialization
Yisroel
fuente
fuente
Respuestas:
serializeArray
Ya hace exactamente eso. Solo necesita masajear los datos en el formato requerido:Tenga cuidado con los campos ocultos que tienen el mismo nombre que las entradas reales ya que se sobrescribirán.
fuente
$.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } );
si necesita incluir elementos deshabilitados.foo[bar]
entradas de tipo como se esperaba, sin mencionar la mayoría de las otras variedades de nombres de entrada. Después de estar muy frustrado con soluciones superficiales a este problema, terminé escribiendo mi propio complemento jQuery, detalles en la respuesta que proporcioné a esta pregunta.Convierte formularios a JSON como un jefe
La fuente actual está en GitHub y Bower .
El siguiente código ahora está en desuso .
El siguiente código puede funcionar con todo tipo de nombres de entrada; y manejarlos como es de esperar.
Por ejemplo:
Uso
La brujería (JavaScript)
fuente
<select name="foo" multiple="multiple">
No funcionará en ningún escenario. Sin embargo, si se utiliza[]
, como en<select name="bar[]" multiple="multiple">
, que funciona muy bien :)Qué hay de malo en:
fuente
.each
lugar 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;}, {})
Una versión fija de la solución de Tobias Cohen. Éste maneja correctamente los valores falsos como
0
y''
.Y una versión de CoffeeScript para su conveniencia de codificación:
fuente
value = @value ? ''
keyMap
y la siguiente línea:key = if keyMap? then keyMap(@name) else @name
. Ahora puede pasar la función de mapeo como(name) -> name.match(/\[([^\]]+)]/)[1]
. Y luego uno tendría que cambiar todo después@name
dekey
, por supuestopost
, simplemente podría hacerlo$('form').serializeObject().post
. No hay necesidad de mapeo elegante.if (!objectData[this.name].push)
??objectData[this.name]
tiene el método push (más o menos, es una matriz). Si es una matriz, empuja el valor, si no es una matriz, la convierte en una matriz para que múltiples valores con la misma clave se combinen en una matriz.Me gusta usar
Array.prototype.reduce
porque es de una sola línea, y no se basa en Underscore.js o similares:Esto es similar al uso de la respuesta
Array.prototype.map
, pero no necesita saturar su alcance con una variable de objeto adicional. Uno para de comprar.NOTA IMPORTANTE : Los formularios con entradas que tienen
name
atributos duplicados son HTML válidos, y en realidad es un enfoque común. El uso de cualquiera de las respuestas en este hilo será inapropiado en ese caso (ya que las claves de objeto deben ser únicas).fuente
array.prototype.reduce()
no está disponible en IE8 ya que es parte de la especificación ECMAScript 5. Entonces, si necesita soporte para IE8, querrá usar un polyfill u otra solución por completo.Todas estas respuestas me parecieron demasiado exageradas. Hay algo que decir por simplicidad. Siempre que todas sus entradas de formulario tengan el atributo de nombre establecido, esto debería funcionar solo con jim dandy.
fuente
Realmente no hay forma de hacerlo sin examinar cada uno de los elementos. Lo que realmente quiere saber es "¿alguien más ya ha escrito un método que convierta un formulario en un objeto JSON?" Algo como lo siguiente debería funcionar: tenga en cuenta que solo le dará los elementos del formulario que se devolverían a través de un POST (debe tener un nombre). Esto no está probado .
fuente
Si está utilizando Underscore.js puede usar el relativamente conciso:
fuente
Verifiqué que hay un problema con todas las otras respuestas, que si el nombre de entrada es como una matriz, como
name[key]
, entonces debería generarse así:name:{ key : value }
Por ejemplo: si tiene un formulario HTML similar al siguiente:
Pero debe generarse como el JSON a continuación, y no se convierte en un objeto como el siguiente con todas las demás respuestas. Entonces, si alguien quiere traer algo como el siguiente JSON, pruebe el código JS a continuación.
fuente
eval
no debería usarse de esta manera porqueeval
, cuando se usa de esta manera, promueve prácticas terriblemente poco confiables, con errores, de bajo rendimiento y potencialmente inseguras.this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
es breve y no explicativo. Un desarrollador con menos experiencia simplemente copiará esto sin entender por qué y cómo funciona.eval()
.Ok, sé que esto ya tiene una respuesta altamente votada, pero recientemente se hizo otra pregunta similar , y también me dirigieron a esta pregunta. También me gustaría ofrecer mi solución, ya que ofrece una ventaja sobre la solución aceptada: puede incluir elementos de formulario deshabilitados (que a veces es importante, dependiendo de cómo funcione su interfaz de usuario)
Aquí está mi respuesta de la otra pregunta SO :
Inicialmente, estábamos usando el
serializeArray()
método de jQuery , pero eso no incluye elementos de formulario que están deshabilitados. A menudo deshabilitaremos elementos de formulario que están "sincronizados" con otras fuentes en la página, pero aún necesitamos incluir los datos en nuestro objeto serializado. AsíserializeArray()
está fuera. Utilizamos el:input
selector para obtener todos los elementos de entrada (tanto habilitados como deshabilitados) en un contenedor determinado, y luego$.map()
para crear nuestro objeto.Tenga en cuenta que para que esto funcione, cada una de sus entradas necesitará un
name
atributo, que será el nombre de la propiedad del objeto resultante.Eso en realidad está ligeramente modificado de lo que usamos. Necesitábamos crear un objeto estructurado como .NET IDictionary, así que utilizamos esto: (lo proporciono aquí en caso de que sea útil)
Me gustan ambas soluciones, porque son usos simples de la
$.map()
función y usted tiene control completo sobre su selector (por lo tanto, qué elementos termina incluyendo en su objeto resultante). Además, no se requiere ningún complemento adicional. Llano viejo jQuery.fuente
map
así crea una matriz de objetos con una sola propiedad, no contrae todas las propiedades en un solo objeto.Esta función debe manejar matrices multidimensionales junto con múltiples elementos con el mismo nombre.
Lo he estado usando durante un par de años hasta ahora:
fuente
Puedes hacerlo:
Ver JSON .
fuente
One-liner (sin dependencias distintas de jQuery), utiliza el enlace de objeto fijo para la función pasada al
map
método.¿Que hace?
Adecuado para aplicaciones web progresivas (uno puede admitir fácilmente tanto la acción de envío de formularios regulares como las solicitudes de ajax)
fuente
Utilizar:
Salida:
fuente
La simplicidad es mejor aquí. He usado un simple reemplazo de cadena con una expresión regular, y hasta ahora funcionaron como un encanto. No soy un experto en expresiones regulares, pero apuesto a que incluso puedes llenar objetos muy complejos.
fuente
De alguna respuesta anterior :
fuente
serializeArray
lo que tiene la libertad de elegir las entradas que desee (por ejemplo, puede incluir entradas deshabilitadas), ¿verdad? Es decir, esto no está asociado a ningún formulario o al evento de envío, ¿es solo independiente por sí mismo?reduce
devuelve el objeto. Esto no es independiente ya quetoArray
es de jQuery.Encontré un problema con el código de Tobias Cohen (no tengo suficientes puntos para comentarlo directamente), que de lo contrario me funciona. Si tiene dos opciones de selección con el mismo nombre, ambas con valor = "", el código original generará "nombre": "" en lugar de "nombre": ["", ""]
Creo que esto se puede solucionar agregando "|| o [this.name] == ''" a la primera condición if:
fuente
Usando la solución de maček , la modifiqué para que funcione con la forma en que ASP.NET MVC maneja sus objetos anidados / complejos en el mismo formulario. Todo lo que tiene que hacer es modificar la pieza de validación para esto:
Esto coincidirá y luego correlacionará correctamente los elementos con nombres como:
Y
fuente
la forma más sencilla y precisa he encontrado para este problema era utilizar plug-in barbacoa o esta uno (que es aproximadamente 0,5 K bytes de tamaño).
También funciona con matrices multidimensionales.
fuente
Hay un complemento para hacer eso para jQuery, jquery.serializeJSON . Lo he usado con éxito en algunos proyectos ahora. Funciona a las mil maravillas.
fuente
fuente
Prefiero este enfoque porque: no tiene que iterar sobre 2 colecciones, puede obtener otras cosas que no sean "nombre" y "valor" si es necesario, y puede desinfectar sus valores antes de almacenarlos en el objeto ( si tiene valores predeterminados que no desea almacenar, por ejemplo).
Use así:
Solo probado en Firefox.
fuente
Convierta cualquier cosa en un objeto (no unidad probada)
La salida de prueba:
en
rendirá:
fuente
Encontré un problema con la solución seleccionada.
Cuando se usan formularios que tienen nombres basados en matrices, la función jQuery serializeArray () en realidad muere.
Tengo un marco PHP que usa nombres de campo basados en matrices para permitir que el mismo formulario se coloque en la misma página varias veces en múltiples vistas. Esto puede ser útil para agregar, editar y eliminar en la misma página sin modelos de formulario en conflicto.
Como quería seralizar los formularios sin tener que sacar esta funcionalidad de base absoluta, decidí escribir mi propio seralizeArray ():
Tenga en cuenta: esto también funciona fuera del formulario submit (), por lo que si se produce un error en el resto de su código, el formulario no se enviará si coloca un botón de enlace que dice "guardar cambios".
También tenga en cuenta que esta función nunca debe usarse para validar el formulario solo para recopilar los datos para enviarlos al lado del servidor para su validación. El uso de dicho código débil y asignado en masa causará XSS , etc.
fuente
Tuve el mismo problema últimamente y salí con este complemento .toJSON jQuery que convierte un formulario en un objeto JSON con la misma estructura. Esto también es especialmente útil para formularios generados dinámicamente donde desea permitir que su usuario agregue más campos en lugares específicos.
El punto es que es posible que desee crear un formulario para que tenga una estructura en sí misma, así que supongamos que desea crear un formulario donde el usuario inserte sus lugares favoritos en la ciudad: puede imaginar este formulario para representar un
<places>...</places>
elemento XML que contiene un lista de lugares que le gusta al usuario, por lo tanto, una lista de<place>...</place>
elementos que contienen cada uno, por ejemplo, un<name>...</name>
elemento, un<type>...</type>
elemento y luego una lista de<activity>...</activity>
elementos para representar las actividades que puede realizar en dicho lugar. Entonces su estructura XML sería así:Qué bueno sería tener un objeto JSON fuera de este que representaría esta estructura exacta para que pueda:
Bien, ahora debemos pensar cómo un formulario puede representar un archivo XML.
Por supuesto, la
<form>
etiqueta es laroot
, pero luego tenemos que<place>
elemento que es un contenedor y no un elemento de datos en sí mismo, por lo que no podemos usar una etiqueta de entrada para ello.¡Aquí es donde la
<fieldset>
etiqueta es útil! Usaremos<fieldset>
etiquetas para representar todos los elementos del contenedor en nuestra representación de formulario / XML y así llegar a un resultado como este:Como puede ver en este formulario, estamos rompiendo la regla de los nombres únicos, pero esto está bien porque se convertirán en una matriz de elementos, por lo que solo se referenciará por su índice dentro de la matriz.
En este punto, puede ver cómo no hay
name="array[]"
un nombre similar dentro del formulario y todo es bonito, simple y semántico.Ahora queremos que este formulario se convierta en un objeto JSON que se verá así:
Para hacer esto, he desarrollado este complemento jQuery aquí que alguien ayudó a optimizar en este hilo de Revisión de Código y se ve así:
También hice esta publicación de blog para explicar esto más.
Esto convierte todo en un formulario a JSON (incluso radio y casillas de verificación) y todo lo que le queda por hacer es llamar
Sé que hay muchas maneras de convertir formularios en objetos JSON y de seguro
.serialize()
y.serializeArray()
funcionan muy bien en la mayoría de los casos, y en su mayoría están destinados a ser utilizados, pero creo que esta idea es escribir un formulario como una estructura XML con nombres significativos y convertirlo en un objeto JSON bien formado Vale la pena intentarlo con un , también el hecho de que puede agregar etiquetas de entrada del mismo nombre sin preocuparse es muy útil si necesita recuperar datos de formularios generados dinámicamente.¡Espero que esto ayude a alguien!
fuente
Codifiqué un formulario en un objeto JavaScript multidimensional para usarlo en producción. El resultado es https://github.com/serbanghita/formToObject.js .
fuente
Otra respuesta
FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData
fuente
[ACTUALIZACIÓN 2020]
Con un simple oneliner en vainilla js:
fuente
Me gusta la versión de Samuel, pero creo que tiene un pequeño error. Normalmente JSON se envía como
NO como
entonces la función IMO debería leer:
y envolverlo en una matriz de datos (como comúnmente se espera), y finalmente enviarlo como astring App.stringify ({data: App.toJson ('#cropform: input')})
Para ver el stringify, vea la pregunta 3593046 para la versión ajustada , y json2.js para la versión cubierta por todas las eventualidades. Eso debería cubrirlo todo :)
fuente
Para una solución rápida y moderna, use JSONify complemento jQuery. El siguiente ejemplo se toma textualmente del archivo README de GitHub. Todo el crédito a Kushal Pandya, autor del complemento.
Dado:
Corriendo:
Produce:
Si desea hacer una POST jQuery con este objeto JSON:
fuente