Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails check_box_tag how to pass value when checked ajaxily

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
like image 937
Catfish Avatar asked Mar 29 '13 03:03

Catfish


4 Answers

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 },
} %>
like image 131
nates Avatar answered Nov 13 '22 18:11

nates


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 }
   });     
});
like image 35
Srikanth Jeeva Avatar answered Nov 13 '22 19:11

Srikanth Jeeva


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.

like image 31
Jim Meyer Avatar answered Nov 13 '22 19:11

Jim Meyer


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

like image 2
Konstantin Ilchenko Avatar answered Nov 13 '22 18:11

Konstantin Ilchenko