json array - Konvertieren von Formulardaten in JavaScript-Objekte mit jQuery





to object (25)


Verwandle alles in ein Objekt (nicht getestet)

<script type="text/javascript">
string = {};

string.repeat = function(string, count)
{
    return new Array(count+1).join(string);
}

string.count = function(string)
{
    var count = 0;

    for (var i=1; i<arguments.length; i++)
    {
        var results = string.match(new RegExp(arguments[i], 'g'));
        count += results ? results.length : 0;
    }

    return count;
}

array = {};

array.merge = function(arr1, arr2)
{
    for (var i in arr2)
    {
        if (arr1[i] && typeof arr1[i] == 'object' && typeof arr2[i] == 'object')
            arr1[i] = array.merge(arr1[i], arr2[i]);
        else
            arr1[i] = arr2[i]
    }

    return arr1;
}

array.print = function(obj)
{
    var arr = [];
    $.each(obj, function(key, val) {
        var next = key + ": ";
        next += $.isPlainObject(val) ? array.print(val) : val;
        arr.push( next );
      });

    return "{ " +  arr.join(", ") + " }";
}

node = {};

node.objectify = function(node, params)
{
    if (!params)
        params = {};

    if (!params.selector)
        params.selector = "*";

    if (!params.key)
        params.key = "name";

    if (!params.value)
        params.value = "value";

    var o = {};
    var indexes = {};

    $(node).find(params.selector+"["+params.key+"]").each(function()
    {
        var name = $(this).attr(params.key),
            value = $(this).attr(params.value);

        var obj = $.parseJSON("{"+name.replace(/([^\[]*)/, function()
        {
            return '"'+arguments[1]+'"';
        }).replace(/\[(.*?)\]/gi, function()
        {
            if (arguments[1].length == 0)
            {
                var index = arguments[3].substring(0, arguments[2]);
                indexes[index] = indexes[index] !== undefined ? indexes[index]+1 : 0;

                return ':{"'+indexes[index]+'"';
            }
            else
                return ':{"'+escape(arguments[1])+'"';
        })+':"'+value.replace(/[\\"]/gi, function()
        {
            return "\\"+arguments[0]; 
        })+'"'+string.repeat('}', string.count(name, ']'))+"}");

        o = array.merge(o, obj);
    });

    return o;
}
</script>

Die Ausgabe des Tests:

$(document).ready(function()
{
    console.log(array.print(node.objectify($("form"), {})));
    console.log(array.print(node.objectify($("form"), {selector: "select"})));
});

auf

<form>
    <input name='input[a]' type='text' value='text'/>
    <select name='input[b]'>
        <option>select</option>
    </select>

    <input name='otherinput[c][a]' value='a'/>
    <input name='otherinput[c][]' value='b'/>
    <input name='otherinput[d][b]' value='c'/>
    <input name='otherinput[c][]' value='d'/>

    <input type='hidden' name='anotherinput' value='hidden'/>
    <input type='hidden' name='anotherinput' value='1'/>

    <input type='submit' value='submit'/>
</form>

wird ergeben:

{ input: { a: text, b: select }, otherinput: { c: { a: a, 0: b, 1: d }, d: { b: c } }, anotherinput: 1 }
{ input: { b: select } }

Wie konvertiere ich alle Elemente meines Formulars in ein JavaScript-Objekt?

Ich möchte eine Möglichkeit haben, automatisch ein JavaScript-Objekt aus meinem Formular zu erstellen, ohne jedes Element durchlaufen zu müssen. Ich will keine Zeichenkette, wie von $('#formid').serialize(); Ich möchte auch nicht, dass die Map von $('#formid').serializeArray();




Ich habe ein Problem mit der ausgewählten Lösung gefunden.

Bei Verwendung von Formularen mit arraybasierten Namen wird die Funktion jQuery serializeArray () tatsächlich beendet.

Ich habe ein PHP-Framework, das Array-basierte Feldnamen verwendet, um zu ermöglichen, dass das gleiche Formular in mehreren Ansichten mehrmals auf dieselbe Seite gesetzt wird. Dies kann nützlich sein, wenn Sie auf derselben Seite hinzufügen, bearbeiten und löschen können, ohne dass dabei widersprüchliche Formularmodelle auftreten.

Da ich die Formulare seralisieren wollte, ohne diese absolute Basisfunktionalität ausnutzen zu müssen, entschied ich mich, mein eigenes seralizeArray () zu schreiben:

        var $vals = {};

        $("#video_edit_form input").each(function(i){
            var name = $(this).attr("name").replace(/editSingleForm\[/i, '');

            name = name.replace(/\]/i, '');

            switch($(this).attr("type")){
                case "text":
                    $vals[name] = $(this).val();
                    break;
                case "checkbox":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                case "radio":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                default:
                    break;
            }
        });

Bitte beachten Sie: Dies funktioniert auch außerhalb von form submit (). Wenn also ein Fehler im Rest Ihres Codes auftritt, wird das Formular nicht gesendet, wenn Sie auf eine Link-Schaltfläche "Änderungen speichern" klicken.

Beachten Sie außerdem, dass diese Funktion niemals zum Überprüfen des Formulars verwendet werden sollte, um nur die Daten zu sammeln, die zur Überprüfung an den Server gesendet werden. Die Verwendung eines solchen schwachen und massenzugewiesenen Codes verursacht XSS usw.




Von einer older Antwort:

$('form input,select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})



I like samuels version, but I believe it has a small error. Normally JSON is sent as

{"coreSKU":"PCGUYJS","name_de":"whatever",...

NOT as

[{"coreSKU":"PCGUYJS"},{"name_de":"whatever"},...

so the function IMO should read:

App.toJson = function( selector ) {
    var o = {};
    $.map( $( selector ), function( n,i )
    {
        o[n.name] = $(n).val();
    });     
    return o;
}

and to wrap it in data array (as commonly expected, too), and finally send it as astring App.stringify( {data:App.toJson( '#cropform :input' )} )

For the stringify look at Question 3593046 for the lean version, at json2.js for the every-eventuality-covered version. That should cover it all :)




Es gibt wirklich keine Möglichkeit, dies zu tun, ohne jedes der Elemente zu untersuchen. Was Sie wirklich wissen möchten, ist "Hat jemand anderes bereits eine Methode geschrieben, die ein Formular in ein JSON-Objekt konvertiert?" So etwas wie das Folgende sollte funktionieren - beachten Sie, dass es Ihnen nur die Formularelemente gibt, die über einen POST zurückgegeben werden (muss einen Namen haben). Dies wird nicht getestet .

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



Diese Funktion sollte mehrdimensionale Arrays zusammen mit mehreren Elementen mit demselben Namen behandeln.

Ich benutze es seit ein paar Jahren:

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



Was ist falsch mit:

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



Du kannst das:

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

Siehe JSON .




Mit der Lösung von Maček änderte ich die Funktionsweise so, dass ASP.NET MVC ihre verschachtelten / komplexen Objekte auf demselben Formular behandelt. Alles, was Sie tun müssen, ist das Validierungsstück zu ändern:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

Dadurch werden Elemente mit Namen wie folgt zugeordnet und dann korrekt zugeordnet:

<input type="text" name="zooName" />

Und

<input type="text" name="zooAnimals[0].name" />






Ich mag es, Array.prototype.reduce weil es ein Array.prototype.reduce ist und nicht auf Underscore.js oder dergleichen beruht:

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

Dies ähnelt der Antwort mit Array.prototype.map , aber Sie müssen Ihren Bereich nicht mit einer zusätzlichen Objektvariable Array.prototype.map . One-Stop-Shopping.

WICHTIGER HINWEIS : Formulare mit Eingaben, die doppelte Namensattribute aufweisen, sind gültiges HTML und tatsächlich eine allgemeine Vorgehensweise. Die Verwendung einer der Antworten in diesem Thread ist in diesem Fall nicht geeignet (da Objektschlüssel eindeutig sein müssen).




Benutzen:

function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;
}

Ausgabe:

{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}



Ich bevorzuge diesen Ansatz, weil: Sie müssen nicht über 2 Sammlungen iterieren, Sie können andere Dinge als "Name" und "Wert" bekommen, wenn Sie müssen, und Sie können Ihre Werte bereinigen, bevor Sie sie im Objekt speichern ( wenn Sie Standardwerte haben, die Sie nicht speichern möchten, zum Beispiel).

$.formObject = function($o) {
    var o = {},
        real_value = function($field) {
            var val = $field.val() || "";

            // additional cleaning here, if needed

            return val;
        };

    if (typeof o != "object") {
        $o = $(o);
    }

    $(":input[name]", $o).each(function(i, field) {
        var $field = $(field),
            name = $field.attr("name"),
            value = real_value($field);

        if (o[name]) {
            if (!$.isArray(o[name])) {
                o[name] = [o[name]];
            }

            o[name].push(value);
        }

        else {
            o[name] = value;
        }
    });

    return o;
}

Verwenden Sie so:

var obj = $.formObject($("#someForm"));

Nur in Firefox getestet.




All diese Antworten schienen mir übertrieben. Es gibt etwas, das der Einfachheit halber gesagt werden muss. Solange alle Ihre Formulareingaben das Namensattribut haben, sollte dies nur jim dandy funktionieren.

$('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?)
});



For a quick, modern solution, use the JSONify jQuery plugin. The example below is taken verbatim from the GitHub README. All credit to Kushal Pandya, author of the plugin.

Gegeben:

<form id="myform">
    <label>Name:</label>
    <input type="text" name="name"/>
    <label>Email</label>
    <input type="text" name="email"/>
    <label>Password</label>
    <input type="password" name="password"/>
</form>

Laufen:

$('#myform').jsonify();

Produziert:

{"name":"Joe User","email":"[email protected]","password":"mypass"}

If you want to do a jQuery POST with this JSON object:

$('#mybutton').click(function() {
    $.post('/api/user', JSON.stringify($('#myform').jsonify()));
}



Die einfachste und genaueste Methode, die ich für dieses Problem gefunden habe, war die Verwendung von BBQ-Plugin oder dieses (die etwa 0,5 KB Größe ist).

Es funktioniert auch mit multidimensionalen Arrays.

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};




I wouldn't use this on a live site due to XSS attacks and probably plenty of other issues, but here's a quick example of what you could do:

$("#myform").submit(function(){
    var arr = $(this).serializeArray();
    var json = "";
    jQuery.each(arr, function(){
        jQuery.each(this, function(i, val){
            if (i=="name") {
                json += '"' + val + '":';
            } else if (i=="value") {
                json += '"' + val.replace(/"/g, '\\"') + '",';
            }
        });
    });
    json = "{" + json.substring(0, json.length - 1) + "}";
    // do something with json
    return false;
});



serializeArray macht genau das schon. Sie müssen nur die Daten in Ihr gewünschtes Format einmassieren:

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

Achten Sie auf versteckte Felder, die den gleichen Namen wie echte Eingaben haben, da sie überschrieben werden.




Wenn Sie versuchen, alle Formularfelder in JSON zu konvertieren, um dieses Formular über Ajax zu senden, hier ist ein jQuery-Formular-Plugin , das das tut.




Wenn Sie Underscore.js , können Sie das relativ übersichtliche verwenden:

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






Ein-Liner (keine anderen Abhängigkeiten als jQuery), verwendet die Bindung fester Objekte für die Funktion Pass-zu- map Methode.

$('form').serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]

Was es macht?

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

geeignet für progressive Web-Apps (sowohl reguläre Formular-Übermittlungsaktionen als auch Ajax-Anfragen können problemlos unterstützt werden)




Ich hatte das gleiche Problem in letzter Zeit und kam mit diesem .toJSON jQuery Plugin heraus , das ein Formular in ein JSON Objekt mit der gleichen Struktur umwandelt. Dies ist auch besonders nützlich für dynamisch generierte Formulare, bei denen der Benutzer mehr Felder an bestimmten Stellen hinzufügen soll.

Der Punkt ist, dass Sie tatsächlich ein Formular erstellen möchten, so dass es eine Struktur selbst hat. Sagen wir, Sie möchten ein Formular erstellen, in das der Benutzer seine Lieblingsorte in der Stadt einfügt: Sie können sich dieses Formular als <places>...</places> vorstellen <places>...</places> XML-Element, das eine Liste von Orten enthält, die der Benutzer mag, also eine Liste von <place>...</place> -Elementen, von denen jedes zum Beispiel ein <name>...</name> -Element enthält, a <type>...</type> und dann eine Liste von <activity>...</activity> -Elementen, um die Aktivitäten darzustellen, die Sie an einem solchen Ort ausführen können. Ihre XML-Struktur würde also so aussehen:

<places>

    <place>

        <name>Home</name>
        <type>dwelling</type>

        <activity>sleep</activity>
        <activity>eat</activity>
        <activity>watch TV</activity>

    </place>

    <place>...</place>

    <place>...</place>

</places>

Wie cool wäre es, ein JSON-Objekt zu haben, das genau diese Struktur repräsentiert, so dass Sie entweder:

  • Store this object as it is in any CouchDB -like database
  • Read it from your $_POST[] server side and retrive a correctly nested array you can then semantically manipulate
  • Use some server-side script to convert it into a well-formed XML file (even if you don't know its exact structure a-priori)
  • Just somehow use it as it is in any Node.js -like server script

OK, so now we need to think how a form can represent an XML file.

Of course the <form> tag is the root , but then we have that <place> element which is a container and not a data element itself, so we cannot use an input tag for it.

Here's where the <fieldset> tag comes in handy! We'll use <fieldset> tags to represent all container elements in our form/XML representation and so getting to a result like this:

<form name="places">

    <fieldset name="place">

        <input type="text" name="name"/>
        <select name="type">
            <option value="dwelling">Dwelling</option>
            <option value="restoration">Restoration</option>
            <option value="sport">Sport</option>
            <option value="administrative">Administrative</option>
        </select>

        <input type="text" name="activity"/>
        <input type="text" name="activity"/>
        <input type="text" name="activity"/>

    </fieldset>

</form>

As you can see in this form, we're breaking the rule of unique names, but this is OK because they'll be converted into an array of element thus they'll be referenced only by their index inside the array.

At this point you can see how there's no name="array[]" like name inside the form and everything is pretty, simple and semantic.

Now we want this form to be converted into a JSON object which will look like this:

{'places':{

    'place':[

        {

            'name': 'Home',
            'type': 'dwelling',

            'activity':[

                 'sleep',
                 'eat',
                 'watch TV'

            ]

        },

        {...},

        {...}

    ]

}}

To do this I have developed this jQuery plugin here which someone helped optimizing in this Code Review thread and looks like this:

$.fn.toJSO = function () {
    var obj = {},
        $kids = $(this).children('[name]');
    if (!$kids.length) {
        return $(this).val();
    }
    $kids.each(function () {
        var $el = $(this),
            name = $el.attr('name');
        if ($el.siblings("[name=" + name + "]").length) {
            if (!/radio|checkbox/i.test($el.attr('type')) || $el.prop('checked')) {
                obj[name] = obj[name] || [];
                obj[name].push($el.toJSO());
            }
        } else {
            obj[name] = $el.toJSO();
        }
    });
    return obj;
};

I also made this one blog post to explain this more.

This converts everything in a form to JSON (even radio and check boxes) and all you'll have left to do is call

$.post('script.php',('form').toJSO(), ...);

I know there's plenty of ways to convert forms into JSON objects and sure .serialize() and .serializeArray() work great in most cases and are mostly intended to be used, but I think this whole idea of writing a form as an XML structure with meaningful names and converting it into a well-formed JSON object is worth the try, also the fact you can add same-name input tags without worrying is very useful if you need to retrive dynamically generated forms data.

I hope this helps someone!




Ok, ich weiß, dass dies bereits eine stark aufgestockte Antwort hat, aber kürzlich wurde eine ähnliche Frage gestellt , und ich wurde auch auf diese Frage hingewiesen. Ich möchte auch meine Lösung anbieten, da sie einen Vorteil gegenüber der akzeptierten Lösung bietet: Sie können deaktivierte Formularelemente einbinden (was manchmal wichtig ist, je nachdem wie Ihre UI-Funktionen funktionieren)

Hier ist meine Antwort von der anderen SO-Frage :

Anfangs verwendeten wir die serializeArray() Methode von jQuery, die jedoch keine deaktivierten Formularelemente enthält. Wir werden häufig Formularelemente deaktivieren, die mit anderen Quellen auf der Seite "synchronisiert" sind, aber wir müssen immer noch die Daten in unser serialisiertes Objekt aufnehmen. Also serializeArray() ist out. Wir haben den :input Selektor verwendet, um alle Eingabeelemente (sowohl aktiviert als auch deaktiviert) in einem gegebenen Container zu erhalten, und dann $.map() , um unser Objekt zu erstellen.

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

Beachten Sie, dass dazu jede Ihrer Eingaben ein Namensattribut benötigt, das den Namen der Eigenschaft des resultierenden Objekts darstellt.

Das ist tatsächlich etwas modifiziert von dem, was wir verwendet haben. Wir mussten ein Objekt erstellen, das als .NET-IDictionary strukturiert war, also haben wir Folgendes verwendet: (Ich stelle es hier zur Verfügung, falls es nützlich ist)

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

Ich mag beide Lösungen, weil sie die $.map() Funktion einfach verwenden und Sie die Kontrolle über Ihren Selektor haben (also, welche Elemente Sie am Ende in Ihr resultierendes Objekt aufnehmen). Außerdem ist kein zusätzliches Plugin erforderlich. Einfaches altes jQuery.




Wenn Sie nur mit dem Scrollen zu einem Eingabeelement arbeiten, können Sie focus() . Wenn Sie beispielsweise zur ersten sichtbaren Eingabe blättern möchten:

$(':input:visible').first().focus();

Oder die erste sichtbare Eingabe in einem Container mit der Klasse .error :

$('.error :input:visible').first().focus();

Danke an Tricia Ball für den Hinweis!





jquery json serialization