Pregunta Convierta datos de formulario a objetos de JavaScript con jQuery


¿Cómo convierto todos los elementos de mi formulario a un objeto JavaScript?

Me gustaría tener alguna forma de crear automáticamente un objeto JavaScript a partir de mi formulario, sin tener que pasar por encima de cada elemento. No quiero una cadena, como la devuelve $('#formid').serialize();, tampoco quiero que el mapa sea devuelto por $('#formid').serializeArray();


1437


origen


Respuestas:


serializeArray ya hace exactamente eso. Solo necesita masajear los datos en su formato requerido:

function objectifyForm(formArray) {//serialize data function

  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  }
  return returnArray;
}

Tenga cuidado con los campos ocultos que tienen el mismo nombre que las entradas reales, ya que se sobrescribirán.


1541



Convierte formularios a JSON LIKE A BOSS


La fuente actual está en GitHub y Bower.

$ bower install jquery-serialize-object


El siguiente código es ahora obsoleto.

El siguiente código puede tomar el trabajo con todo tipo de nombres de entrada; y manejarlos como es de esperar.

Por ejemplo:

<!-- all of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// output
{
  "honey":{
    "badger":"a"
  },
  "wombat":["b"],
  "hello":{
    "panda":["c"]
  },
  "animals":[
    {
      "name":"d",
      "breed":"e"
    }
  ],
  "crazy":[
    null,
    [
      {"wonky":"f"}
    ]
  ],
  "dream":{
    "as":{
      "vividly":{
        "as":{
          "you":{
            "can":"g"
          }
        }
      }
    }
  }
}

Uso

$('#my-form').serializeObject();

La brujería (JavaScript)

(function($){
    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };


        this.build = function(base, key, value){
            base[key] = value;
            return base;
        };

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            }
            return push_counters[key]++;
        };

        $.each($(this).serializeArray(), function(){

            // skip invalid keys
            if(!patterns.validate.test(this.name)){
                return;
            }

            var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;

            while((k = keys.pop()) !== undefined){

                // adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // push
                if(k.match(patterns.push)){
                    merge = self.build([], self.push_counter(reverse_key), merge);
                }

                // fixed
                else if(k.match(patterns.fixed)){
                    merge = self.build([], k, merge);
                }

                // named
                else if(k.match(patterns.named)){
                    merge = self.build({}, k, merge);
                }
            }

            json = $.extend(true, json, merge);
        });

        return json;
    };
})(jQuery);

406



Qué hay de malo en:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;}); 

252



Una versión fija de la solución de Tobias Cohen. Este maneja correctamente los valores de falsy como 0 y ''.

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

Y una versión de CoffeeScript para su conveniencia de codificación:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData

96



Me gusta usar Array.prototype.reduce porque es de una sola línea, y no depende de Underscore.js o similar:

$('#formid').serializeArray()
    .reduce(function(a, x) { a[x.name] = x.value; return a; }, {});

Esto es similar a la respuesta usando Array.prototype.map, pero no necesita saturar su alcance con una variable de objeto adicional. Uno para de comprar.

NOTA IMPORTANTE: Formularios con entradas que tienen duplicados name los atributos son HTML válidos, y en realidad es un enfoque común. Usar cualquiera de las respuestas en este hilo será inapropiado en ese caso (ya que las claves de objeto deben ser únicas).


49



Todas estas respuestas me parecieron excesivas. Hay algo que decir por simplicidad. Siempre y cuando todas sus entradas de formulario tengan el atributo de nombre establecido, esto debería funcionar solo jim dandy.

$('form.myform').submit(function () {
  var $this = $(this)
    , viewArr = $this.serializeArray()
    , view = {};

  for (var i in viewArr) {
    view[viewArr[i].name] = viewArr[i].value;
  }

  //Do stuff with view object here (e.g. JSON.stringify?)
});

28



Si estás usando Underscore.js puedes usar lo relativamente conciso:

_.object(_.map($('#myform').serializeArray(), _.values))

24



Realmente no hay forma de hacer esto sin examinar cada uno de los elementos. Lo que realmente quieres saber es "¿alguien más ya ha escrito un método que convierta un formulario en un objeto JSON?" Debería funcionar algo como lo siguiente: tenga en cuenta que solo le proporcionará los elementos de formulario que se devolverán a través de un POST (debe tener un nombre). Esto es no probado.

function formToJSON( selector )
{
     var form = {};
     $(selector).find(':input[name]:enabled').each( function() {
         var self = $(this);
         var name = self.attr('name');
         if (form[name]) {
            form[name] = form[name] + ',' + self.val();
         }
         else {
            form[name] = self.val();
         }
     });

     return form;
}

21



Ok, sé que esto ya tiene una respuesta altamente votada, pero otra pregunta similar fue hecha Recientemente, y me dirigieron a esta pregunta también. También me gustaría ofrecer mi solución, porque ofrece una ventaja sobre la solución aceptada: puede incluir elementos de formulario desactivados (que a veces es importante, dependiendo de cómo funcione su UI).

Aquí está mi respuesta del otra pregunta SO:

Inicialmente, estábamos usando jQuery's serializeArray() método, pero eso no incluye elementos de formulario que están deshabilitados. A menudo deshabilitaremos los elementos del formulario que están "sincronizados" con otras fuentes en la página, pero aún necesitamos incluir los datos en nuestro objeto serializado. Asi que serializeArray()Está fuera. Usamos el :input selector para obtener todos los elementos de entrada (tanto habilitados como deshabilitados) en un contenedor dado, y luego $.map() para crear nuestro objeto

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);

Tenga en cuenta que para que esto funcione, cada una de sus entradas necesitará una name atributo, que será el nombre de la propiedad del objeto resultante.

Eso es en realidad un poco modificado de lo que usamos. Necesitábamos crear un objeto que estuviera estructurado como .ID IDictionary, así que usamos esto: (Lo proporciono aquí en caso de que sea útil)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);

Me gustan estas dos soluciones, porque son simples usos del $.map() función, y tiene control completo sobre su selector (entonces, qué elementos termina incluyendo en su objeto resultante). Además, no se requiere un complemento adicional. Llanura de jQuery.


17



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:

jQuery.fn.serializeJSON=function() {
  var json = {};
  jQuery.map(jQuery(this).serializeArray(), function(n, i) {
    var _ = n.name.indexOf('[');
    if (_ > -1) {
      var o = json;
      _name = n.name.replace(/\]/gi, '').split('[');
      for (var i=0, len=_name.length; i<len; i++) {
        if (i == len-1) {
          if (o[_name[i]]) {
            if (typeof o[_name[i]] == 'string') {
              o[_name[i]] = [o[_name[i]]];
            }
            o[_name[i]].push(n.value);
          }
          else o[_name[i]] = n.value || '';
        }
        else o = o[_name[i]] = o[_name[i]] || {};
      }
    }
    else {
      if (json[n.name] !== undefined) {
        if (!json[n.name].push) {
          json[n.name] = [json[n.name]];
        }
        json[n.name].push(n.value || '');
      }
      else json[n.name] = n.value || '';      
    }
  });
  return json;
};

16



Puedes hacerlo:

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeArray());

Ver JSON.


14