WorkForPizza
WorkForPizza

Reputation: 85

Checkbox in index view live updating

I'm currently learning rails and working on what I'm sure is everyone's first rails app, a simple todo list. I need to implement a checkbox next to the items to indicate whether they are complete or not. Each item has a boolean attribute called "completed" in their model. I have found a couple checkbox questions while searching but none explain the syntax very easily in the context of the index view.

Also, I really want the checkbox to work without a submit button. I know I could accomplish something like this using AngularJS's ng-model but I don't think it would be practical to implement angular for such a small thing and I don't know how angular works with rails.

If anyone could give me a pointer in the right direction, it would be greatly appreciated. Here's my index.html.erb for reference.

<h1>
  To Do List
</h1>
<table>
  <tr>
    <% @todo_items.each do |item| %>
      <!-- Checkbox here -->
      <tc style="<%= 'text-decoration: line-through' if item.completed %>">
        <%= link_to item.title, item %>
      </tc>
      <tc>
        <%= item.description %>
      </tc>
      <tc>
        <%= link_to "Edit", edit_todo_item_path(item) %>
      </tc>
      <tc>
        <%= link_to "Delete",item, data:{:confirm => "Are you sure you want to delete this item?"}, :method => :delete %>
      </tc>
      <hr/>
    <% end %>
  </tr>
</table>
<p>
  <%= link_to "Add Item", new_todo_item_path %>
</p>

Upvotes: 1

Views: 673

Answers (1)

rails_id
rails_id

Reputation: 8220

This is my way, I don't know this way is right direction or not but this works for me (also different case but same of concept).

views for checkbox

You could put an id item or something into attribute of checkbox for find an object in controller if you send data to controller for get record of object, and you could define if attribute completed of record is true or false:

<%= check_box_tag :completed_item, 1, item.completed? ? true : false, { class: 'name-of-class', data: { id: item.id} } %>

controller

You need two action call set_completed and remove_completed, and also you don't need templates for them, just use format as json:

  before_action :set_item, only [:set_completed, :remove_completed, :other_action]

  def set_completed
    @item.set_completed!
    respond_to do |format|
      format.json { render :json => { :success => true } }
    end
  end

  def remove_completed
    @item.remove_completed!
    respond_to do |format|
      format.json { render :json => { :success => true } }
    end
  end

  private

  def set_item
    @item = Item.find params[:id]
  end

Model

For set_completed! and remove_completed! you could define in your model

 def set_default!
   self.update_attributes(:completed => true)
 end

 def remove_default!
   self.update_attributes(:completed => false)
 end

routes

resources :address do
 collection do
   post 'set_completed'
   post 'remove_completed'
 end
end

Also, you need help JavaScript for handle send request from view to controller event click of checkbox:

jQuery

$(".completed_item").click(function(){
  var check = $(this).is(":checked");
  if (check == true){
    set_completed($(this).attr('data-id'));
  } else{
    remove_completed($(this).attr('data-id'));
  }
});


function set_completed(data_id) {
  $.ajax({
    type: 'POST',
    url: "/items/set_completed",
    data: { id: data_id},
    dataType: 'json',
    success: function(response){
      if(response){
      }else{
        alert('error');
      }
    }
  })
}

function remove_compelted(data_id) {
  $.ajax({
    type: 'POST',
    url: "/items/set_completed",
    data: { id: data_id},
    dataType: 'json',
    success: function(response){
      if(response){
      }else{
        alert('error');
      }
    } 
  })
}

Upvotes: 2

Related Questions