Corey Quillen
Corey Quillen

Reputation: 1576

Submit checkboxes via ajax without a form in Rails

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

Answers (1)

jay
jay

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

Related Questions