Преобразование данных формы в объект JavaScript с помощью jQuery

Как преобразовать все элементы моей формы в объект JavaScript?

Я хотел бы иметь способ автоматического создания объекта JavaScript из моей формы, без необходимости перебирать каждый элемент. Мне не нужна строка, возвращаемая $('#formid').serialize();, и мне не нужна карта, возвращаемая $('#formid').serializeArray();

Ответ 1

serializeArray уже делает именно это. Вам просто нужно массировать данные в требуемый формат:

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

Следите за скрытыми полями, которые имеют то же имя, что и реальные входы, поскольку они будут перезаписаны.

Ответ 2

Преобразование форм в JSON LIKE A BOSS


Текущий источник находится на GitHub и bower.

$bower install jquery-serialize-object


Следующий код теперь устарел.

Следующий код может работать со всеми типами имен ввода; и обрабатывать их так, как вы ожидали.

Например:

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

Использование

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

Волшебство (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);

Ответ 3

Что случилось с:

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

Ответ 4

Фиксированная версия решения Тобиаса Коэна. Он правильно обрабатывает значения фальши, такие как 0 и ''.

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

И версия CoffeeScript для удобства кодирования:

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

Ответ 5

Мне нравится использовать Array.prototype.reduce, потому что это однострочный, и он не полагается на Underscore.js или тому подобное:

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

Это похоже на ответ с помощью Array.prototype.map, но вам не нужно загромождать вашу область с помощью дополнительной переменной объекта. Одноразовые покупки.

ВАЖНОЕ ПРИМЕЧАНИЕ. Формы со вставками, которые имеют повторяющиеся атрибуты name, являются допустимыми HTML и на самом деле являются общим подходом. Использование любого из ответов в этом потоке будет неуместным в этом случае (поскольку объектные ключи должны быть уникальными).

Ответ 6

Все эти ответы казались мне слишком верными. Что-то нужно сказать для простоты. Пока все ваши входы формы имеют атрибут атрибута имени, это должно работать только джим-денди.

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

Ответ 7

Если вы используете Underscore.js, вы можете использовать относительно краткий:

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

Ответ 8

Невозможно сделать это без изучения каждого из элементов. То, что вы действительно хотите знать, "кто-то еще уже написал метод, который преобразует форму в объект JSON?" Что-то вроде следующего должно работать - обратите внимание, что он даст вам только элементы формы, которые будут возвращены через POST (должно иметь имя). Это не проверено.

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

Ответ 9

Хорошо, я знаю, что у этого уже есть очень высокий ответ, но в то же время был задан еще один аналогичный вопрос, и я тоже был направлен на этот вопрос. Я также хотел бы предложить свое решение, потому что оно дает преимущество перед принятым решением: вы можете включать отключенные элементы формы (что иногда важно, в зависимости от того, как ваши функции пользовательского интерфейса)

Вот мой ответ из другого вопроса SO:

Вначале мы использовали метод jQuery serializeArray(), но это не включает в себя элементы формы, которые отключены. Мы часто будем отключать элементы формы, которые "синхронизируются" с другими источниками на странице, но нам все равно нужно включать данные в наш сериализованный объект. Итак, serializeArray() отсутствует. Мы использовали селектор :input, чтобы получить все входные элементы (оба включены и отключены) в данном контейнере, а затем $.map() для создания нашего объекта.

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

Обратите внимание, что для этого для каждого из ваших входов потребуется атрибут name, который будет именем свойства результирующего объекта.

На самом деле это немного изменилось из того, что мы использовали. Нам нужно было создать объект, который был структурирован как .NET IDictionary, поэтому мы использовали это: (я предоставляю его здесь, если это полезно)

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

Мне нравятся оба этих решения, потому что они - простое использование функции $.map(), и у вас есть полный контроль над вашим селектором (так, какие элементы вы в конечном итоге включаете в свой результирующий объект). Кроме того, дополнительный плагин не требуется. Обычный старый jQuery.

Ответ 10

Эта функция должна обрабатывать многомерные массивы вместе с несколькими элементами с тем же именем.

Я использую его уже пару лет:

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

Ответ 11

Вы можете сделать это:

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

См. JSON.

Ответ 12

  Со всем заданным ответом возникает некоторая проблема, которая..., если входное имя в виде массива, как name[key], но оно будет сгенерировано следующим образом

name:{ key : value }

Например: Если у меня есть такая форма.

<form>
    <input name="name" value="value" >
    <input name="name1[key1]" value="value1" >
    <input name="name2[key2]" value="value2" >
    <input name="name3[key3]" value="value3" >
</form>

Затем он сгенерирует объект, подобный этому, со всеми данными ответа.

Object {
    name : 'value',
    name1[key1] : 'value1',
    name2[key2] : 'value2',
    name3[key3] : 'value3', 
}

Но это должно генерироваться, как показано ниже, любой хочет получить, как это показано ниже.

Object {
    name : 'value',
    name1 : { key1 : 'value1' },
    name2 : { key2 : 'value2' },
    name3 : { key2 : 'value2' }
}

Тогда попробуйте это ниже js code.

(function($){
    $.fn.getForm2obj = function(){
        var _ = {},_t=this;
        this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
        this.b = function(k,v,a = 0){ if(a) eval(k+".push("+v+");"); else eval(k+"="+v+";"); };
        $.map(this.serializeArray(),function(n){
            if(n.name.indexOf('[') > -1 ){
                var keys = n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g),le = Object.keys(keys).length,tmp = '_';
                $.map(keys,function(key,i){
                    if(key == ''){
                        eval("ale = Object.keys("+tmp+").length;");
                        if(!ale) _t.b(tmp,'[]');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'",1);
                        else _t.b(tmp += "["+ale+"]",'{}');
                    }else{
                        _t.c(tmp += "['"+key+"']",'{}');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'");
                    }
                });
            }else _t.b("_['"+n['name']+"']","'"+n['value']+"'");
        });
        return _;
    }
})(jQuery);
console.log($('form').getForm2obj());
$('form input').change(function(){
    console.clear();
    console.log($('form').getForm2obj());
});
<!DOCTYPE html><html><head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <title>Convert form data to JavaScript object with jQuery</title>
</head>
<body>
    <form>
        <input type="checkbox" name="name4[]" value="1" checked="checked">1
        <input type="checkbox" name="name4[]" value="2">2
        <input type="checkbox" name="name4[]" value="3">3<br>
        <input type="radio" name="gender" value="male" checked="checked">male 
        <input type="radio" name="gender" value="female"> female
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" ><br><br>
        <input name="one[another][another_one]" value="value4" >
    </form>
</body></html>

Ответ 13

Однострочный (без зависимостей, кроме jQuery), использует привязку фиксированного объекта для функции, переданной в метод map.

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

Что он делает?

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

подходит для прогрессивных веб-приложений (можно легко поддерживать как регулярное представление формы, так и запросы ajax)

Ответ 14

Использование:

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

Вывод:

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

Ответ 15

Простота здесь лучше. Я использовал замену простой строки с регулярным выражением, и до сих пор они работали как шарм. Я не специалист по регулярному выражению, но я уверен, вы даже можете заполнить очень сложные объекты.

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});

Ответ 16

Из более старого ответа:

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

Ответ 17

Используя решение maček, я изменил его, чтобы работать с тем, как ASP.NET MVC обрабатывает свои вложенные/сложные объекты в одной и той же форме. Все, что вам нужно сделать, это изменить часть проверки:

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

Это будет соответствовать, а затем правильно отображать элементы с такими именами, как:

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

и

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

Ответ 18

Я нашел проблему с кодом Тобиаса Коэна (у меня недостаточно очков, чтобы прокомментировать это напрямую), что в противном случае работает для меня. Если у вас есть два варианта выбора с тем же именем, оба со значением = ", исходный код будет генерировать" имя ":" "вместо" name ": [" "," "]

Я думаю, что это может быть исправлено добавлением "|| o [this.name] == ''" в первое условие if:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

Ответ 19

Самый простой и самый точный способ, который я нашел для этой проблемы, - использовать плагин bbq или этот один (размер около 0,5 КБ).

он также работает с многомерными массивами.

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

Ответ 20

Если вы пытаетесь преобразовать все поля формы в JSON, чтобы отправить эту форму через Ajax, здесь плагин формы jQuery, который делает что.

Ответ 21

Существует плагин для JQuery, jquery.serializeJSON. Я успешно использовал его в нескольких проектах. Отлично работает.

Ответ 22

Я предпочитаю этот подход, потому что: вам не нужно перебирать более двух коллекций, вы можете получить доступ к вещам, отличным от "name" и "value", если вам нужно, и вы можете дезинфицировать свои ценности, прежде чем хранить их в объект (если у вас есть значения по умолчанию, которые вы не хотите хранить, например).

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

Используйте так:

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

Проверено только в Firefox.

Ответ 23

Я нашел проблему с выбранным решением.

При использовании форм с именами на основе массива функция jQuery serializeArray() фактически умирает.

У меня есть фреймворк PHP, который использует имена полей на основе массива, чтобы одна и та же страница могла быть помещена на одну и ту же страницу несколько раз в нескольких представлениях. Это может быть удобно для добавления и редактирования и удаления на одной странице без конфликтов моделей форм.

Поскольку я хотел серализовать формы без необходимости использовать эту абсолютную базовую функциональность, я решил написать свой собственный seralizeArray():

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

Обратите внимание: это также работает вне формы submit(), поэтому, если в остальной части вашего кода будет возникать ошибка, форма не будет отправлена, если вы поместите ссылку на ссылку "Сохранить изменения".

Также обратите внимание, что эта функция никогда не должна использоваться для проверки формы только для сбора данных для отправки на сервер для проверки. Использование такого слабого и массового кода приведет к XSS и т.д.

Ответ 24

Повернуть что-нибудь в объект (не тестировалось)

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

Выход теста:

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

о

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

даст:

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

Ответ 25

У меня была такая же проблема в последнее время и вышла с этот .toJSON jQuery плагин, который преобразует форму в объект JSON с той же структурой, Это также чрезвычайно полезно для динамически создаваемых форм, где вы хотите, чтобы ваш пользователь добавлял больше полей в определенные места.

Суть в том, что вы можете на самом деле захотеть создать форму, чтобы она имела саму структуру, поэтому позвольте сказать, что вы хотите создать форму, в которой пользователь вставляет свои любимые места в городе: вы можете представить эту форму для представления <places>...</places> XML-элемент, содержащий список мест, которым пользователю нравится, таким образом, список элементов <place>...</place>, каждый из которых содержит, например, элемент <name>...</name>, элемент <type>...</type>, а затем список элементов <activity>...</activity> для представления действий, которые вы может выступать в таком месте. Таким образом, ваша структура XML будет выглядеть следующим образом:

<places>

    <place>

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

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

    </place>

    <place>...</place>

    <place>...</place>

</places>

Как здорово было бы иметь объект JSON из этого, который будет представлять эту точную структуру, чтобы вы могли:

  • Сохраните этот объект, как он есть в любой CouchDB-like database
  • Прочитайте его со своей серверной стороны $_POST [] и извлеките правильно вложенный массив, который вы можете затем семантически манипулировать
  • Используйте некоторую серверную script, чтобы преобразовать ее в хорошо сформированный XML файл (даже если вы не знаете его точной структуры a-priori)
  • Просто как-то используйте его, как в любом Node.js-like server script

ОК, так что теперь нам нужно подумать, как форма может представлять XML файл.

Конечно, тег <form> - это root, но тогда мы имеем этот элемент <place>, который является контейнером, а не самим элементом данных, поэтому мы не можем использовать для него тег ввода.

Здесь тег <fieldset> пригодится! Мы будем использовать теги <fieldset> для представления всех элементов контейнера в нашем представлении формы /XML и, таким образом, для получения такого результата:

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

Как вы можете видеть в этой форме, мы нарушаем правило уникальных имен, но это нормально, потому что они будут преобразованы в массив элементов, поэтому на них будет ссылаться только их индекс внутри массива.

В этот момент вы видите, как внутри формы нет name="array[]" имени, и все довольно, просто и семантично.

Теперь мы хотим, чтобы эта форма была преобразована в объект JSON, который будет выглядеть следующим образом:

{'places':{

    'place':[

        {

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

            'activity':[

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

            ]

        },

        {...},

        {...}

    ]

}}

Для этого я разработал этот плагин jQuery здесь, который кто-то помог оптимизировать этот код Просмотрите нить и выглядите так:

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

Я также сделал это одно сообщение в блоге, чтобы объяснить это больше.

Это преобразует все в форму в JSON (даже радио и флажки), и все, что вам нужно сделать, это вызвать

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

Я знаю, что существует множество способов конвертировать формы в объекты JSON, и, в большинстве случаев, .serialize() и .serializeArray() отлично работают и в основном предназначены для использования, но я думаю, что вся эта идея написания формы как XML структура со значимыми именами и преобразование ее в хорошо сформированный объект JSON стоит попробовать, а также тот факт, что вы можете добавлять теги ввода с одним и тем же именем, не беспокоясь, очень полезно, если вам нужно извлекать динамически созданные данные форм.

Надеюсь, это поможет кому-то!

Ответ 26

Я сам кодировал форму для многомерного JavaScript-объекта, чтобы использовать ее в процессе производства. Результатом является https://github.com/serbanghita/formToObject.js.

Ответ 27

Мне нравится версия samuels, но я считаю, что у нее небольшая ошибка. Обычно JSON отправляется как

{ "coreSKU": "PCGUYJS", "name_de": "все, что"...

НЕ как

[{ "coreSKU": "PCGUYJS" }, { "name_de": "все" },...

поэтому функция IMO должна читать:

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

и обернуть его в массив данных (как обычно ожидается), и, наконец, отправить его как вяжущий App.stringify({data: App.toJson('#cropform: input')})

Для строкового просмотра вопроса 3593046 для скудной версии, json2.js для каждой версии, охваченной событиями. Это должно охватывать все это:)

Ответ 28

Для быстрого, современного решения используйте плагин JSONify jQuery. Пример ниже приведен дословно из GitHub README. Весь кредит Кушалу Пандии, автору плагина.

Дано:

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

Продолжительность:

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

Выдает:

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

Если вы хотите сделать POST JQuery с этим объектом JSON:

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

Ответ 29

используя lodash # set

let serialized = [
  { key: 'data[model][id]', value: 1 },
  { key: 'data[model][name]', value: 'product' },
  { key: 'sid', value: 'dh0un1hr4d' }
];

serialized.reduce(function(res, item) {
  _.set(res, item.key, item.value);
  return res;
}, {});

// returns
{
  "data": {
    "model": {
      "id": 1,
      "name": "product"
    }
  },
  "sid": "dh0un1hr4d"
}

Ответ 30

Другой ответ

document.addEventListener("DOMContentLoaded", function() {
  setInterval(function() {
    var form = document.getElementById('form') || document.querySelector('form[name="userprofile"]');
    var json = Array.from(new FormData(form)).map(function(e,i) {this[e[0]]=e[1]; return this;}.bind({}))[0];
    
    console.log(json)
    document.querySelector('#asJSON').value = JSON.stringify(json);
  }, 1000);
})
<form name="userprofile" id="form">
  <p>Name <input type="text" name="firstname" value="John"/></p>
  <p>Family name <input name="lastname" value="Smith"/></p>
  <p>Work <input name="employment[name]" value="inc, Inc."/></p>
  <p>Works since <input name="employment[since]" value="2017" /></p>
  <p>Photo <input type="file" /></p>
  <p>Send <input type="submit" /></p>
</form>

JSON: <textarea id="asJSON"></textarea>