开发者

check_box_tag displaying checks incorrectly

开发者 https://www.devze.com 2023-04-10 19:59 出处:网络
I have a form that displays whether tasks are complete or not. You can check the box to set the model\'s :is_complete attribute to true, and check it again to set it as false. Or so that\'s how it\'s

I have a form that displays whether tasks are complete or not. You can check the box to set the model's :is_complete attribute to true, and check it again to set it as false. Or so that's how it's supposed to work. I can mark tasks as complete, hit the Update button, and the tasks get marked as complete just fine. But when I try to uncheck the tasks afterwards, nothing gets sent to the update action until I hit the update button again, when they finally get marked as incomplete.

Form

<%= form_tag '/day_tasks/update', :method => :put do %>                                    
  <% @day_tasks.each do |day_task| %>     
    <%= check_box_tag "day_tasks[]", day_task.id, day_task.is_complete? %>       开发者_如何转开发        
    <%= day_task.task.content %><br />                                                            
  <% end %>                                                                                       
  <%= submit_tag "Update" %>                                                                      
<% end %>

Update action

def update
  params[:day_tasks] ||= []
  params[:day_tasks].each do |x| 
    DayTask.find(x).toggle(:is_complete).save
  end 
  redirect_to day_tasks_path 
end 

I'm pretty sure the issue is with the logic behind displaying whether or not a box is checked ( day_task.is_complete? ) because if I remove that snippet of code, although boxes never appear checked, the tasks are checking and unchecking perfectly fine on the back end. It's only when this snippet is included that I run into the problem of nothing being sent after I hit Update a second time. Any ideas on why this is occurring?


The problem is that a not-checked checkbox will never be sent to the server.

There's a trick: Add a hidden input field with the same name right before the check_box_tag and give it the false value like:

<%= form_tag '/day_tasks/update', :method => :put do %>                                    
  <% @day_tasks.each do |day_task| %>     
    <%= hidden_field_tag "day_tasks[#{day_task.id}]", "0" %>
    <%= check_box_tag "day_tasks[#{day_task.id}]", "1", day_task.is_complete? %>               
    <%= day_task.task.content %><br/>                                                            
  <% end %>                                                                                       
  <%= submit_tag "Update" %>                                                                      
<% end %>

So now if the check box is not checked, the value will be 0 (false) when the check box is checked, the checkbox "overwrites" the hidden field and sets the value to 1 (true)

You have to adapt your update action since you will get a hash like:

day_tasks[task_id] = 0/1 (not completed / completed)

your update action:

def update
  params[:day_tasks] ||= {}
  params[:day_tasks].each do |task_id, completed| 
    DayTask.find(task_id).update_attribute(:is_complete, completed)
  end 
  redirect_to day_tasks_path 
end 
0

精彩评论

暂无评论...
验证码 换一张
取 消