views:

352

answers:

3

I've set up a Rails form roughly following the instructions in this Railscast.

Here's the code for the form:

<% form_tag complete_todos_path, :method => :put do %>
    <ul>
    <div id="incomplete_todos">
    <% @incomplete_todos.each do |todo| %>
     <%= render :partial => todo %>
    <% end %>
    </div>
    </ul>
    <%= submit_tag "Mark as completed" %>
<% end %>

And here's the code for the todo partial:

<div class="todo">
    <li>
     <%= check_box_tag "todo_ids[]", todo.id %>
     <%=h todo.name %>
     <%= link_to 'edit', edit_todo_path(todo) %>
     <%= link_to 'delete', todo, :confirm => 'Are you sure?', :method => :delete %>
    </li>
</div>

It's working great, but I'm looking to start implementing AJAX and I need each checkbox to have a unique id. Right now, the input tags generated look something like this:

<input id="todo_ids_" name="todo_ids[]" type="checkbox" value="7" />

Every check box has the same id ("todo_ids_"), which is a problem. I suspect the solution is embarrassingly simple, but I'm not seeing it. Any tips?

+1  A: 

Can you try this and let us know if it works:

check_box_tag "todo_ids[#{todo.id}]", todo.id %>
Ryan Oberoi
Generates the following:<input id="todo_ids_7" name="todo_ids[7]" type="checkbox" value="7" />The ids are all unique, which is great, but it sends the parameters in a weird way:todo_ids"=>{"5"=>"5"}I ended up using:Todo.update_all(["completed_at = ?", Time.now], :id => params[:todo_ids].keys) as a workaround and it works great (though it seems like a kind of messy solution). Thanks!
Grant Heaslip
Ryan Oberoi
A: 

<%= check_box_tag "todo_ids[]", todo.id, :id => "todo_id_#{todo.id}" -%> or whatever you want the id to be.

I consider this a bug with check_box_tag caused by the seemingly hackish nature of manually giving it the name todo_ids[] and the method code calling sanitize_to_id(name). I just ran into this yesterday and I'm contemplating a patch.

BJ Clark
This doesn't seem to work properly. I end up getting input tags like the following:<input checked="checked" id="todo_ids_" name="todo_ids[]" type="checkbox" value="7" />The form still works, but every input is checked off by default.
Grant Heaslip
For this to work you need to supply the checked parameter before the hash parameters. When calling check_box_tag("todo_ids[]", todo.id, false, :id => "todo_id_#{todo.id}") you'll get: <input id="todo_id_7" name="todo_ids[]" type="checkbox" value="7" />
Vincent
A: 

I ended up using a solution similar to Ryan's, but as I wrote in the comment I had to make a further change. In the form:

<%= check_box_tag "todo_ids[#{todo.id}]", todo.id %>

In the action called by the form:

Todo.update_all(["completed_at = ?", Time.now], :id => params[:todo_ids].keys)

Note the "params[:todo_ids].keys" at the end, which was a workaround to deal with the odd way the parameters were formatted:

"todo_ids" => {"5"=>"5"}
Grant Heaslip