I'm trying to add the ability to complete a todo item by patching in :complete method. Is it possible to use a checkbox for this rather than the link_to I have below? I would very much like a checkbox so it feels like the task is ticked off.
My View
<%= link_to "Mark as complete", complete_todo_path(todo.id), method: :patch %>
My Controller
def complete
@todo.update_attribute(:completed_at, Time.now)
redirect_to dashboard_path, notice: "Todo item completed"
end
My Resources
resources :todos do
member do
patch :complete
end
end
EDIT:
I have gone about this another way but now face a different problem...
I have migrated a :completed boolean, I then added it to my form like so (simple_form)
<%= f.input :completed, as: :boolean %>
This allows me to update completed, not completed.
But how do I get this to show in my view? I don't want to have to click into each todo(edit) I want to do it from the index but not sure how to go about this?
From a RESTful standpoint there is no need for an additional route here.
Instead your would simply send a PATCH
request to the normal member route:
PATCH /todos/:id, { todo: { complete: true } }
Also you want to do it like a real rockstar you might want to use a enum instead of a boolean:
class AddStatusToTodo < ActiveRecord::Migration
def change
add_column :todos, :status, :integer, default: 0, index: true
remove_column :todos, :complete
end
end
class Todo < ActiveRecord::Base
enum status: [:incomplete, :complete, :removed] #etc
end
This lets you setup many states without creating several boolean columns and gives you a bunch of functionality almost for free.
To set this up on the view side you could simply create a form for each element:
<% @todos.each do |todo| %>
<%= form_for(todo) do |f| %>
<%= f.label :status %>
<%= f.check_box(:status, class: 'complete-todo') %>
<% end %>
<% end %>
We could use a classical submit button here but to give a good UX we want to use ajax. Having a form element gives us the perfect foundation since we can simply enhance its behavior:
// Setup jQuery to send the csrf-token
$.ajaxSetup({
beforeSend: function(xhr){
var token = $('meta[name="csrf-token"]').attr('content');
xhr.setRequestHeader('X-CSRF-Token', token);
}
});
// Handle clicks on the checkbox and send patch request in background
$().on('click', '.complete-todo', function(event){
var $input, $form, promise;
$input = $(this);
$form = $input.closest('form');
promise = $.ajax($form.attr('action'), {
method: 'PATCH',
data: {
todo: {
status: $input.is(':checked') ? 'complete' : 'incomplete'
}
}
});
// setup callbacks as needed
promise.done(function(data, textStatus, jqXHR){
console.log('Excellent!', data, textStatus, jqXHR);
});
promise.fail(function(jqXHR, textStatus, errorThrown){
console.log('Oh Noes!', jqXHR, textStatus, errorThrown);
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.