所以我试图在目标中创建一个任务列表,为了完成它们,我创建了一个带有隐藏字段的form_for,它将在单击提交时更新每个任务记录的值。 我正在尝试向表单添加ajax,以便当用户点击提交时,它将更新任务的记录,并且它将使用div表示“完成!”来部分替换此表单。
goals_controller.rb
def show @goal = Goal.where(user_id: current_user, id: params[:id]).first @goal_tasks = @goal.tasks # This is where the AJAX request will happen respond_to do |format| format.html {} format.js {} end endshow.html.erb for Goals
<% @goal_tasks.each do |task| %> <div class="complete-button"> <% if task.completed == false %> <%= form_for([@goal,task], remote: true) do |f| %> <%= f.hidden_field :completed , :value => true %> <%= f.submit "Complete" , :class => "submit-complete" %> <% end %> <% else %> <%= render partial: "goals/taskcompleted" %> <% end %> <div> <% end %>show.js.erb
$(".complete-button").html("<%= j(render partial: 'goals/taskcompleted') %>")
发生的行为是,如果有多个任务,html中有多个具有唯一id="edit_task_unique_id"表单,但因为我在show.js.erb中抓取.complete .complete-button类。 它用完整的div替换所有表单。 我试图以某种方式抓住表单创建的唯一ID,但没有运气。 任何帮助或反馈表示赞赏!
So I am trying to create a list of tasks within a goal and in order to complete them, I am creating a form_for with a hidden field that will update the value for the each task record when clicking submit. I'm trying to add ajax to the form so that when a user hits submit, it will update the record for the task and it will render a partial replacing this form with a div saying "complete!".
goals_controller.rb
def show @goal = Goal.where(user_id: current_user, id: params[:id]).first @goal_tasks = @goal.tasks # This is where the AJAX request will happen respond_to do |format| format.html {} format.js {} end endshow.html.erb for Goals
<% @goal_tasks.each do |task| %> <div class="complete-button"> <% if task.completed == false %> <%= form_for([@goal,task], remote: true) do |f| %> <%= f.hidden_field :completed , :value => true %> <%= f.submit "Complete" , :class => "submit-complete" %> <% end %> <% else %> <%= render partial: "goals/taskcompleted" %> <% end %> <div> <% end %>show.js.erb
$(".complete-button").html("<%= j(render partial: 'goals/taskcompleted') %>")
The behavior that is happening is that if there are multiple tasks, there are multiple forms with unique id="edit_task_unique_id" in the html but since I'm grabbing the .complete-button class in the show.js.erb. It is replace all of the forms with the complete div. I've tried to somehow grab the unique id's the form creates with each task but no luck. Any help or feedback is appreciated!
最满意答案
Show是GET类型,你做的是PUT类型。 您可以使用更新方法或创建自定义方法。 您甚至不需要表单,因为您不希望用户键入任何内容。 最重要的是,我将使用:completed_at字段, datetime类型。 如果它是零,那么它没有完成,如果它不是零(有一个日期时间)那么它就完成了。
的routes.rb
resources :goals do resources :tasks do member do patch :complete end end end目标/ show.html.erb
.... <%= render @tasks %> # this is a rails convention. Basically it iterates thru the @tasks and renders each task based on _task.html.erb which represents a single task. ....任务/ _task.html.erb
#You use task instead of @task as you do within a @tasks.each |task| do block. <%= task.name %> <%= task.content %> <% if task.completed_at.nil? %> #here you only need to pass task.id to the path (rails convention again) <%= link_to "Complete Task", complete_goal_task_path(id: task.id), action: :complete, remote: true, method: :patch %> <% end %>目标控制器
def show # I don't know why you wrote this: @goal = Goal.where(user_id: current_user, id: params[:id]).first #It should be just this since you are on the show page (You should define the current_user in the view link helper that takes the user on this page.) @goal = Goal.find(params[:id]) @tasks = @goal.tasks end任务控制器
def complete @task = Task.find(params[:id]) @task.update_attribute(:completed_at, Time.zone.now) respond_to do |format| format.html format.js end end任务/ complete.js.erb
//You remove the completed task from the DOM (I guess you wanna do that.) $("#task_<%= @task.id %>").fadeOut(400, function(){ $(this).remove(); }); //For flash checkout a stackoverflow question. Something like "how to use flash in js.erb"schema.rb
create_table "tasks", force: :cascade do |t| t.integer "goal_id", null: false t.string "name" t.text "content", null: false t.datetime "deadline", null: false t.datetime "completed_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false endShow is a GET type, what you do is a PUT type. You could use update method or create a custom one. You don't even need form, since you don't expect the users to type anything. On the top of that I would use :completed_at field with datetime type. If it's nil then it's not completed, if it's not nil (there is a datetime) then it's completed.
routes.rb
resources :goals do resources :tasks do member do patch :complete end end endgoals/show.html.erb
.... <%= render @tasks %> # this is a rails convention. Basically it iterates thru the @tasks and renders each task based on _task.html.erb which represents a single task. ....tasks/_task.html.erb
#You use task instead of @task as you do within a @tasks.each |task| do block. <%= task.name %> <%= task.content %> <% if task.completed_at.nil? %> #here you only need to pass task.id to the path (rails convention again) <%= link_to "Complete Task", complete_goal_task_path(id: task.id), action: :complete, remote: true, method: :patch %> <% end %>goals controller
def show # I don't know why you wrote this: @goal = Goal.where(user_id: current_user, id: params[:id]).first #It should be just this since you are on the show page (You should define the current_user in the view link helper that takes the user on this page.) @goal = Goal.find(params[:id]) @tasks = @goal.tasks endtasks controller
def complete @task = Task.find(params[:id]) @task.update_attribute(:completed_at, Time.zone.now) respond_to do |format| format.html format.js end endtasks/complete.js.erb
//You remove the completed task from the DOM (I guess you wanna do that.) $("#task_<%= @task.id %>").fadeOut(400, function(){ $(this).remove(); }); //For flash checkout a stackoverflow question. Something like "how to use flash in js.erb"schema.rb
create_table "tasks", force: :cascade do |t| t.integer "goal_id", null: false t.string "name" t.text "content", null: false t.datetime "deadline", null: false t.datetime "completed_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false end更多推荐
发布评论