I am new to rails and trying to change the value of a boolean via a checkbox and using jquery ajax:
<%- @tasks.each do |task| %>
<div class="task-wrapper">
<%= check_box_tag 'completed', task.id , task.completed, :class => "task-check" %>
<%= content_tag :span, task.task %>
<%= content_tag :span, task.deadline %>
</div>
<% end %>
and the javascript:
$(".task-check").bind('change', function(){
if (this.checked){
var bool = this.checked ? 1 : 0;
$.ajax({
url: '/todos/toggle',
type: 'POST',
data: '{"task_id":"'+ this.value +'", "bool":"'+ bool +'"}'
});
}
else {
alert("no");
}
});
then the controller:
def toggle(task_id, bool)
@task = Todo.find_by_id(task_id)
if @task != nil?
@task.update_attributes(:completed => bool)
else
set_flash "Error, please try again"
end
end
finally the routes:
resources :todos do
member do
post 'toggle'
end
end
also tried collection but gives the same error.
when ever i try it i get a 404 error
on the action.
what is the problem?
thanks
Try the following (leaving everything else as is):
the javascript:
$(".task-check").bind('change', function(){
if (this.checked){
$.ajax({
url: '/todos/'+this.value+'/toggle',
type: 'POST',
data: {"completed": this.checked}
});
}
else {
alert("no");
}
});
the controller:
def toggle
@task = Todo.find(params[:id])
if @task.update_attributes(:completed => params[:completed])
# ... update successful
else
# ... update failed
end
end
Take a look at bundle exec rake routes
to show you the paths that rails generates. In the case of your post 'toggle'
which is a member you get a path like /todos/:id/toggle
, hence the updated url in the ajax.
In the controller the :id
from the path ends up in params[:id]
. The data from the ajax request also ends up in the params
hash, hence params[:completed]
.
As of Rails 4, there's a way to do this without needing any additional JS or CSS:
<%= check_box_tag 'completed', task.id, task.completed,
data: {
remote: true,
url: url_for(action: :toggle, id: task.id),
method: "POST"
} %>
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.