Как преобразовать данные jQuery.serialize() в объект JSON?

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

<form id='sampleform'>
    <input name='MyName' type='text' /> // Raf

    <!--array input fields below-->
    <input name='friendname[]' type='text' /> // Bily
    <input name='fiendemail[]' type='text' /> // bily@someemail.com

    <!--duplicated fields below to add more friends -->
    <input name='friendname[]' type='text' /> // Andy
    <input name='fiendemail[]' type='text' /> // Andy@somwhere.com

    <input name='friendname[]' type='text' /> // Adam
    <input name='fiendemail[]' type='text' /> // Adam@herenthere.com
</form>

Метод jquery, применяемый для получения данных

var MyForm = $("#sampleform").serialize();
/** result : MyName=Raf&friendname[]=Billy&fiendemail[]=bily@someemail.com&friendname[]=Andy&fiendemail[]=Andy@somwhere.com&friendname[]=Adam&fiendemail[]=Adam@herenthere.com
*/

как мне сделать эти данные в объект JSON? который должен иметь следующий пример JSON-данных из вышеуказанной формы.

{
    "MyName":"raf",
    "friendname":[
        {"0":"Bily"},
        {"1":"Andy"},
        {"2":"Adam"}
    ],
    "friendemail":[
        {"0":"bily@someemail.com"},
        {"1":"Andy@somwhere.com"},
        {"2":"Adam@herenthere.com"}
    ]
}

13 ответов

var formdata = $("#myform").serializeArray();
var data = {};
$(formdata ).each(function(index, obj){
    data[obj.name] = obj.value;
});

Просто и быстро;)

У меня недавно была именно эта проблема. Первоначально мы использовали 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.

Используйте плагин jQuery.serializeJSON. Он преобразует формы, используя тот же формат, который вы найдете в объекте параметров Rails, который очень стандартен и хорошо протестирован.

Я использую этот очень маленький плагин jQuery, который я расширил из DocumentCloud:

https://github.com/documentcloud/documentcloud/blob/master/public/javascripts/lib/jquery_extensions.js

В основном это две строки кода, но для этого требуется _.js (Underscore.js), поскольку он основан на reduce функция.

$.fn.extend({
  serializeJSON: function(exclude) {
    exclude || (exclude = []);
    return _.reduce(this.serializeArray(), function(hash, pair) {
      pair.value && !(pair.name in exclude) && (hash[pair.name] = pair.value);
      return hash;
    }, {});
  }
});

Расширения:

  • Это не сериализует входное значение, если это нуль
  • Он может исключать некоторые входные данные, передавая массив входных имен exclude аргумент i.e. ["password_confirm"]

Я думаю, что здесь есть много хороших ответов, и я сделал свою собственную функцию на основе этих ответов.

function formToJSON(f) {
    var fd = $(f).serializeArray();
    var d = {};
    $(fd).each(function() {
        if (d[this.name] !== undefined){
            if (!Array.isArray(d[this.name])) {
                d[this.name] = [d[this.name]];
            }
            d[this.name].push(this.value);
        }else{
            d[this.name] = this.value;
        }
    });
    return d;
}

//The way to use it :
$('#myForm').submit(function(){
    var datas = formToJSON(this);
    return false;
});

Хорошо, позвольте мне объяснить, в основном, почему я предпочитаю это решение... Если у вас есть несколько входных данных с одинаковым именем, все значения будут сохранены в массиве, но если нет, то значение будет сохранено непосредственно как значение индекса в JSON .... Это отличается от ответа Данило Колассо, когда возвращаемый JSON основан только на значениях массива...

Так что если у вас есть Форма с текстовой областью с именем content и несколькими авторами, эта функция вернется к вам:

{
    content : 'This is The Content',
    authors : 
        [
            0: 'me',
            1: 'you',
            2: 'him',
        ]
}

Если вы можете использовать ES6, вы могли бы сделать

const obj = arr.reduce((acc, {name, value}) => ({...acc, [name]: value}), {})

для сериализованного массива работает очень хорошо.

Эквивалентное решение Данило Колассо с теми же плюсами и минусами .serializeArray() (в основном это использует .reduce вместо $.each).

Без особых усилий это позволяет реализовать дополнительные функции в ответах SC, не требуя расширений.

$(selector).serializeArray()
    .reduce(function(accum, item) {
        // This 'if' allows ignoring some values
        if (-1 === [ 'ignoreThis', 'andThat' ].indexOf(item.name)) {
            // This allows ignoring NULL values
            if (item.value !== null) {
                accum[item.name] = item.value;
            }
        }
        return accum;
    },
    {
        // By supplying some initial values, we can add defaults
        // for, say, disabled form controls.
        preFilledName:  preFilledValue, // optional
        defaultName  :  defaultValue    // optional
    }
);
var formdata = $("#myform").serializeArray();

var data = {};

$(formdata ).each(function(index, obj){

         if(data[obj.name] === undefined)
              data[obj.name] = [];

          data[obj.name].push(obj.value);

});

Используя силу функции уменьшения!

$(form).serializeArray().reduce(function (output, value) {
        output[value.name] = value.value

        return output
}, {})

Использование подчеркивания и jQuery

var formdata = $("#myform").serializeArray();
var data = {};
_.each(formdata, function(element){
// Return all of the values of the object's properties.
  var value = _.values(element);
// name : value 
  data[value[0]] = value[1];
});
console.log(data); //Example => {name:"alex",lastname:"amador"}

Со всем данным ответом есть некоторая проблема, которая...

Если ввести имя как массив, например 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.

(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());
<!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 name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
        <input type="checkbox" name="name4[]" value="1" checked="checked">
        <input type="checkbox" name="name4[]" value="2">
        <input type="checkbox" name="name4[]" value="3">
    </form>
</body></html>

Используйте JSON.stringify () и serializeArray ():

Если вы используете запросы AJAX, то нет необходимости делать это json-object только $('#sampleform').serialize() работает отлично, или если у вас есть другая цель, вот мое решение:

var formserializeArray = $("#sampleform").serializeArray();   
var jsonObj = {};
jQuery.map(formserializeArray , function (n, i) {
    jsonObj[n.name] = n.value;
});
Другие вопросы по тегам