在每个循环内的窗体上使用嵌套资源和html类来管理Ajax(Rails Ajax on a form inside an each loop with nested resources and htm

编程入门 行业动态 更新时间:2024-10-24 18:28:08
在每个循环内的窗体上使用嵌套资源和html类来管理Ajax(Rails Ajax on a form inside an each loop with nested resources and html class)

所以我试图在目标中创建一个任务列表,为了完成它们,我创建了一个带有隐藏字段的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 end

show.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 end

show.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 end

Show 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 end

goals/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 end

tasks 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 end

tasks/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

更多推荐

本文发布于:2023-04-28 01:50:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1330260.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:嵌套   窗体   资源   在每个   html

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!