Vraag Converteer formuliergegevens naar JavaScript-object met jQuery


Hoe converteer ik alle elementen van mijn formulier naar een JavaScript-object?

Ik zou graag een manier hebben om automatisch een JavaScript-object te bouwen vanuit mijn formulier, zonder elk element te hoeven omcirkelen. Ik wil geen touw, zoals geretourneerd door $('#formid').serialize();en ik wil ook niet dat de kaart wordt geretourneerd door $('#formid').serializeArray();


1437


oorsprong


antwoorden:


serializeArray doet al precies dat. U hoeft alleen de gegevens in uw gewenste formaat te masseren:

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;
}

Pas op voor verborgen velden die dezelfde naam hebben als echte invoer omdat ze worden overschreven.


1541



Converteer formulieren naar JSON LIKE A BOSS


De huidige bron is ingeschakeld GitHub en prieel.

$ bower installeert jquery-serialize-object


De volgende code is nu verouderd.

De volgende code kan werken met allerlei soorten invoernamen; en behandel ze zoals je zou verwachten.

Bijvoorbeeld:

<!-- 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"
          }
        }
      }
    }
  }
}

Gebruik

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

The Sorcery (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



Wat is mis met:

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

252



Een vaste versie van de oplossing van Tobias Cohen. Deze behandelt correct valse waarden zoals 0 en ''.

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;
};

En een CoffeeScript-versie voor uw codeergemak:

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



Ik gebruik graag Array.prototype.reduce omdat het een one-liner is en er niet op vertrouwt Underscore.js en dergelijke:

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

Dit is vergelijkbaar met het antwoord met Array.prototype.map, maar u hoeft uw bereik niet te vervuilen met een extra objectvariabele. One-stop-shopping.

BELANGRIJKE NOTITIE: Formulieren met ingangen die duplicaat hebben name attributen zijn geldige HTML en is eigenlijk een gemeenschappelijke aanpak. Het gebruik van een van de antwoorden in deze thread is in dat geval niet geschikt (objecttekens moeten uniek zijn).


49



Al deze antwoorden leken me zo overdreven. Er is iets te zeggen voor de eenvoud. Zolang al je formulierinvoeren de naamkenmerkenset hebben, zou dit alleen jim dandy moeten werken.

$('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



Als je gebruikt Underscore.js je kunt het relatief beknopte gebruiken:

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

24



Er is echt geen manier om dit te doen zonder elk element te onderzoeken. Wat je echt wilt weten, is "heeft iemand anders al een methode geschreven die een formulier omzet in een JSON-object?" Iets als het volgende zou moeten werken - merk op dat je alleen de formulierelementen krijgt die via een POST worden geretourneerd (moet een naam hebben). Dit is niet getest.

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é, ik weet dat dit al een zeer upvoted antwoord heeft, maar een andere vergelijkbare vraag werd gesteld onlangs, en ik werd ook naar deze vraag verwezen. Ik wil ook graag mijn oplossing aanbieden, omdat het een voordeel biedt ten opzichte van de geaccepteerde oplossing: u kunt vormelementen met een beperking toevoegen (wat soms belangrijk is, afhankelijk van hoe uw UI functioneert)

Hier is mijn antwoord van de andere ZO vraag:

Aanvankelijk maakten we gebruik van jQuery's serializeArray() methode, maar dit omvat geen formulierelementen die zijn uitgeschakeld. We zullen vaak formulierelementen uitschakelen die zijn 'gesynchroniseerd' met andere bronnen op de pagina, maar we moeten de gegevens nog steeds opnemen in ons geserialiseerde object. Zo serializeArray()is uit. We gebruikten de :input selector om alle invoerelementen (zowel ingeschakeld als uitgeschakeld) in een bepaalde container te krijgen en vervolgens $.map() om ons object te maken.

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

Merk op dat om dit te laten werken, elk van uw ingangen een a nodig heeft name attribuut, wat de naam is van de eigenschap van het resulterende object.

Dat is eigenlijk enigszins aangepast aan wat we gebruikten. We moesten een object maken dat was gestructureerd als een .NET IDictionary, dus we gebruikten dit: (ik geef het hier voor het geval het nuttig is)

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

Ik ben dol op beide oplossingen, omdat ze eenvoudig zijn in gebruik van de $.map() functie, en je hebt volledige controle over je selector (dus, welke elementen je uiteindelijk opneemt in je resulterende object). Ook is geen extra plug-in vereist. Gewoon oud jQuery.


17



Deze functie moet multidimensionale arrays behandelen, samen met meerdere elementen met dezelfde naam.

Ik gebruik het al een paar jaar tot nu toe:

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