Как преобразовать данные 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:
В основном это две строки кода, но для этого требуется _.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>
Если вы используете запросы AJAX, то нет необходимости делать это json-object
только $('#sampleform').serialize()
работает отлично, или если у вас есть другая цель, вот мое решение:
var formserializeArray = $("#sampleform").serializeArray();
var jsonObj = {};
jQuery.map(formserializeArray , function (n, i) {
jsonObj[n.name] = n.value;
});