Reputation: 1576
How can I submit (post/put) checkbox values to a Rails 3 controller via ajax without wrapping the checkboxes in a form? In other words, how do I serialize the checkboxes to an array with no form.
Any help with this will be great appreciated. Thanks!
Here is what I am trying to do specifically:
View:
<ul>
<%= @items.each do |item|
<li>
<%= checkbox_tag_tag "item_ids[]", item.id, false,
:class => "item-checkbox" %>
<%= item.name %>
</li>
<% end %>
</ul>
Controller:
class ItemsController < ApplicationController
respond_to :html, :js, :json
.
.
.
def update_multiple_items
Item.update_all(
{ :category_id => params[:category_id] },
{ :id => params[:item_ids] }
)
end
end
Javascript (jQuery):
$("#update-link").click(function() {
var categoryId = 2;
var itemsArray = $(".item-checkbox:checked").serializeArray();
$.ajax({
type: "PUT",
url: "items/update_multiple_items",
data: {
category_id: categoryId,
items_ids: itemsArray
},
dataType: "script"
});
});
I get an Active Record error with the following info:
!ruby/hash:ActiveSupport::HashWithIndifferentAccessname: item_ids[]value: ''303'''
Here are the request parameters:
Parameters:
{"parent_id"=>"7", "item_ids"=>{"0"=>{"name"=>"item_ids[]", "value"=>"302"}, "1"=>
{"name"=>"item_ids[]", "value"=>"303"}}}
Upvotes: 1
Views: 1748
Reputation: 12495
I can't say for sure, but it sure seems like you might have an issue with your $(".item-checkbox:checked").serializeArray();
.. It doesn't produce a simple array of item ids. Instead it produces an array of objects representing each checkbox.
What data format it seems like you'd like to submit:
{"parent_id"=>"7", "item_ids"=> [1,2,3]}
What you are submitting:
{"parent_id"=>"7", "item_ids"=>{"0"=>{"name"=>"item_ids[]", "value"=>"302"}, "1"=> {"name"=>"item_ids[]", "value"=>"303"}}}
In other words, $(".item-checkbox:checked").serializeArray();
produces an array of hashes roughly of the format: [{name: "item_ids[]", value: "302"},{name: "item_ids[]", value: "303"}]
But you just want to submit [302,303]
or ["302","303"]
.
What I would do (using an underscore js example):
var serializedArray = $("input:checked").serializeArray();
var itemIdsArray = _.map(serializedArray, function(item){
return item["value"];
});
# itemIdsArray should now be ["302","303"].. you can check by a console.log
console.log(itemIdsArray);
Then submit this array in your ajax:
$.ajax({
type: "PUT",
url: "items/update_multiple_items",
data: {
category_id: categoryId,
items_ids: itemsIdsArray
},
dataType: "script"
});
* Non-underscorejs example *
If you don't use underscorejs, here's how you could write it. (However, I recommend that you check it out, it's great: http://underscorejs.org/. It's a small library of many easy to use basic functions that people constantly roll their own of).
var serializedArray = $("input:checked").serializeArray();
var itemIdsArray = [];
for (var i = 0, length = a.length; i < length; i++) {
itemIdsArray.push(serializedArray[i]['value']);
}
Upvotes: 2