Bob Greenalch Bob Greenalch - 7 months ago 35
Javascript Question

refresh page once checkbox is checked (in the background)

How can I refresh the page (in the background, seamlessly) when a user checks a checkbox so that once the checkbox is checked off, that div or task is then moved to another location because it's completed?

I have separated them like so

def home
if current_user
@todos = current_user.todos.where(completed: false)
end
end

def complete
if current_user
@todos = current_user.todos.where(completed: !false)
end
end


So that once the checkbox is checked it is moved, and this works - but the page has to be refreshed to see that the task has been moved.

In my todos controller where I mark the task complete it looks like this

def completed
if @todo.update_attribute(:completed, !@todo.completed)
flash[:success] = "Congratulations, it was successful."
redirect_to dashboard_path
else
flash.now[:error] = "ERROR: Please try again."
render :new
end
end


And my view is as so

<% @todos.each do |todo| %>
<div class="card hoverable">
<div class ="card-content mh-100">
<span class="card-title"><%= todo.title %></span>
<p><%= todo.item %></p>
</div>
<div class="card-action grey lighten-5">
<p style="margin: 0;">
<%= check_box_tag 'todo[completed]', todo.id, todo.completed, data: { remote: true, url: url_for(controller: :todos, action: :completed, id: todo), method: "POST" }, id: todo.id, :onclick => "Materialize.toast('Todo Completed, Grats!', 4000)" %>
<%= label_tag todo.id, "COMPLETE", :class => 'strikethrough' %>
</p>
</div>
</div>
<% end %>


But how can I refresh the page, or the div when the checkbox is checked so the task disappears seamlessly?

Answer

Give your div a unique ID based on the todo id value so that you can select it for removal:

<div class="card hoverable" id="todo_container_<%= todo.id %>">

Add a class to your check box so that you can specify a click handler:

check_box_tag 'todo[completed]', todo.id, todo.completed, class: 'todo_completed', data: { remote: true, url: url_for(controller: :todos, action: :completed, id: todo), method: "POST" }, id: todo.id, :onclick => "Materialize.toast('Todo Completed, Grats!', 4000)"

Then (assuming you are using jQuery) specify the click handler:

$(".todo_completed").click(function(){
  // it looks like you've got all the info you need for your ajax call in the data attributes attached to the checkbox, so I think the call just looks like this:
  $.ajax($(this).data());
});

Finally your controller needs to render a .js template instead of redirecting - just call it completed.js.erb and it should be rendered automatically. In that template put the javascript to remove the container div from the DOM:

// completed.js.erb
$("todo_container_<%= @todo.id %>").remove();
Comments