Rails check_box_tag how to pass value when checked ajaxily

13,911

Solution 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 }
   });     
});

Solution 2

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 },
} %>

Solution 3

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.

Solution 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

Share:
13,911
Catfish
Author by

Catfish

Old enough to party. Nerdy by nature. Codementor Blog

Updated on June 30, 2022

Comments

  • Catfish
    Catfish almost 2 years

    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