Reputation: 4685
Taking from a HTML setup that looks like this:
<nav data-filters class="">
<input type="radio" name="type" value="company" checked>Company
<input type="radio" name="type" value="product">Product
<input type="radio" name="type" value="service">Service
<select name="category_1" multiple>
<option value="a" selected>a</option>
<option value="b">b</option>
<option value="c" selected>c</option>
</select>
<select name="category_2" multiple>
<option value="a" selected>a</option>
<option value="b" selected>b</option>
<option value="c">c</option>
</select>
<input type="radio" name="startswith" value="a" checked>a
<input type="radio" name="startswith" value="b">b
<input type="radio" name="startswith" value="c">c
<input type="radio" name="startswith" value="num">#
<input name="keyword" type="text">
</nav>
The goal is to achieve this result:
obj = {
"type": {
"values": [
"company"
]
},
"category_1": {
"values": [
"a",
"c"
]
},
"category_2": {
"values": [
"a",
"b"
]
},
"startswith": {
"values": [
"a"
]
}
}
This is my current setup ( note: this.$el just refers to $(nav) ):
var obj = {};
this.$el.find('[name]').each(function(i, input) {
var val = (function() {
if ( input.type == "radio" || input.type == "checkbox" )
return $(input).filter(':checked').val();
return $(input).val()
})(),
name = input.name;
if (val) {
obj[name] = {
values: _.flatten([val]) // Always return an array
}
}
});
return obj;
This seems error prone, and I don't think it's the best way to do it. How should I really be doing this?
Notes on the background of this question:
I'm building a small directory with backbone. This happens in the Filters
view, where the current criteria is turned into an object, which is going to be passed to the collection as data for the fetch() function.
Upvotes: 0
Views: 340
Reputation: 2631
You can use $.serializeArray
method (https://api.jquery.com/serializeArray/) to serialize your form into an array of names and values. Then you just need to convert the result to the desired form:
var inputs = $('nav :input').serializeArray();
var obj = {};
_.each(inputs, function(val){
if(obj[val.name]){
obj[val.name].values.push(val.value);
}else{
obj[val.name] = {values: [val.value]};
}
});
JSBin demo: http://jsbin.com/zidanata/2/edit?html,js,console
Upvotes: 1