Rails check_box_tag how to pass value when checked

2019-02-07 11:28发布

问题:

On my index page for my Task model, I want to show a checkbox for every row that corresponds to the boolean field "complete" in my Task database table.

Currently my code gets into the method "Complete", but it does not contain the value of the checkbox that the user just did (i.e. if they just checked the box, it does not pass true to my "Complete" method).

How can i pass the value that the user just performed - either checked or un checked?

/views/tasks/index.html.erb

<% @tasks.each_with_index do |task, i| %>
    <tr>
        <td><%= check_box_tag 'Complete', task.complete, task.complete, :data => {:remote => true, :url => url_for( :action => 'complete', :id => task.id, :complete => task.complete ), :method => :put}, :class => 'input-large' %></td>
    </tr>
<% end %>

/controllers/tasks_controller#complete

# PUT /complete/1
  def complete
    @task = Task.find(params[:id])
    p "inside complete"
    p "complete = #{params[:complete]}"
    @task.complete = 

      if @task.update_attributes(params[:task])
        p "inside update"
        render :text => "success" 
      else
        p "inside error"
      end

  end

回答1:

If you are using jQuery, you can write a click event.

$('.input-large').click(function() {
  var checked; 
  if ($(this).is(':checked')) {
    checked = true;
  } else {
    checked = false;
  } 
  $.ajax({
      type: "POST",
      url: "/tasks/complete",
      data: { id: $(this).data('post-id'), checked: checked }
   });     
});


回答2:

As of Rails 4, you should be able to ditch all the JS from the original answer. The code in your question should just work due to jQuery UJS magic.

It turns out that adding remote: true to an input causes jquery-ujs to make it ajax-y in all the nice ways. Thoughtbot's "A Tour of Rails jQuery UJS" briefly touches this (and many other good things available); the "Unobtrusive scripting support for jQuery" page in the jQuery UJS wiki does a thorough job on this as well.



回答3:

The suggestion from this issue in rails/jquery-ujs github repo worked for me: https://github.com/rails/jquery-ujs/issues/440#issuecomment-197029277

For you it would be:

<%= check_box_tag 'complete', '1', task.complete, {
  onchange: "$(this).data('params', 'complete=' + this.checked)",
  data: { url: url_for(action: 'complete', id: task.id,), remote: true, method: :patch },
} %>


回答4:

check_box_tag 'complete', task.complete ? 'false' : 'true', task.complete, ...
:url => url_for( :action => 'complete', :id => task.id )

This way in your controller you can get params[:complete]. And you should implement complete.js.erb to rerender checkbox, so next click will send inverse value

Or you can implement js on click event

$('.input-large').on('click', function() {
  $.ajax({
    type: "PUT",
    url: "/tasks/complete/" + $(this).data('post-id')
    data: { complete: $(this).is(':checked') }
  });
});

and don't forget to place data-post-id param to your checkbox