フォームに複数の入力配列フィールドが含まれる場合、jQuery関数serialize()によって既にシリアル化されているフォームデータを変換するより良いソリューションはありますか。フォームデータを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' /> // [email protected]
<!--duplicated fields below to add more friends -->
<input name='friendname[]' type='text' /> // Andy
<input name='fiendemail[]' type='text' /> // [email protected]
<input name='friendname[]' type='text' /> // Adam
<input name='fiendemail[]' type='text' /> // [email protected]
</form>
データを取得するために適用されるjqueryメソッド
var MyForm = $("#sampleform").serialize();
/** result : MyName=Raf&friendname[]=Billy&fiendemail[][email protected]&friendname[]=Andy&fiendemail[][email protected]&friendname[]=Adam&fiendemail[][email protected]
*/
このデータをJSONオブジェクトにするにはどうすればよいですか?上記のフォームからの次のJSONデータの例が必要です。
{
"MyName":"raf",
"friendname":[
{"0":"Bily"},
{"1":"Andy"},
{"2":"Adam"}
],
"friendemail":[
{"0":"[email protected]"},
{"1":"[email protected]"},
{"2":"[email protected]"}
]
}
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 paramsオブジェクトにあるものと同じ形式を使用してフォームを変換します。これは非常に標準的で十分にテストされています。
DocumentCloudから拡張したこの非常に小さなjQueryプラグインを使用しています。
基本的には2行のコードですが、reduce
関数に基づいているため、_。js(Underscore.js)が必要です。
$.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"]
に渡すことにより、一部の入力を除外できますDanilo Colasso's と同等の解決策で、.serializeArray()
と同じ長所と短所があります(基本的には.reduce
の代わりに $.each
)。
少しの労力で、拡張機能を必要とせずにS.C.の回答に追加機能を実装できます。
$(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
}
);
ここには良い答えがたくさんあると思うので、これらの答えに基づいて独自の機能を作成しました。
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のインデックスの値として直接格納されます...これは、Danilo Colassoの答えと異なるところです。返されるJSONは配列値のみに基づいています...
したがって、contentという名前のテキストエリアと複数authorsという名前のフォームがある場合、この関数はあなたに戻ります:
{
content : 'This is The Content',
authors :
[
0: 'me',
1: 'you',
2: 'him',
]
}
アンダースコアと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"}
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);
});
すべての与えられた答えであるいくつかの問題...
名前が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;
});