Javascript Rails/Ajax在提交后将表单从创建更改为更新
所以我想玩一个明星评级页面,在那里我有5个评级问题,你可以评级一次(创建)并在任何给定时间更新你的评级。评级表单是ajaxified的,但问题是表单元素在提交后仍然是一个Create方法,而不是update方法 我遵循了一个非常酷的教程,但是表单更新为正确的方法时缺少了一个部分 这是密码 我有一个部分Javascript Rails/Ajax在提交后将表单从创建更改为更新,javascript,jquery,ruby-on-rails,ajax,forms,Javascript,Jquery,Ruby On Rails,Ajax,Forms,所以我想玩一个明星评级页面,在那里我有5个评级问题,你可以评级一次(创建)并在任何给定时间更新你的评级。评级表单是ajaxified的,但问题是表单元素在提交后仍然是一个Create方法,而不是update方法 我遵循了一个非常酷的教程,但是表单更新为正确的方法时缺少了一个部分 这是密码 我有一个部分rating\u questions/\u quick\u form.html.erb中的表单,每个评级表单都有一个嵌套表单。请注意,表单路由使用帮助器来定义它是否应该是创建或更新操作 <di
rating\u questions/\u quick\u form.html.erb中的表单,每个评级表单都有一个嵌套表单。请注意,表单路由使用帮助器来定义它是否应该是创建或更新操作
<div class="rating_questions">
<% @rating_questions.each do |rating_question| %>
<%= render partial: "rating_questions/rating_form", :locals => {:rating_question => rating_question} %>
<% end %>
</div>
然后在我的create.js.erb
中,我添加了一行代码,用部分
$('#<%= params[:temp_id] %>').replaceWith("<%= j render(partial: 'rating_questions/rating_form', locals: {:rating_question => @rating_question}) %>");
我的ratings\u controller.rb
调用create.js.erb
和update.js.erb
def create
@rating_question = RatingQuestion.find_by_id(params[:rating_question_id])
@rating = Rating.new(params[:rating])
@rating.user_id = current_user.id
if @rating.save
respond_to do |format|
format.html { redirect_to rating_questions_path, :notice => "Your rating has been saved"}
format.js
end
end
end
def update
@rating_question = RatingQuestion.find_by_id(params[:rating_question_id])
@rating = current_user.ratings.find_by_rating_question_id(@rating_question.id)
if @rating.update_attributes(params[:rating])
respond_to do |format|
format.html { redirect_to rating_questions_path, :notice => "Your rating has been updated"}
format.js
end
end
end
显然,我只想更新刚刚提交的表单,而不是其他表单。
您知道如何在create.js.erb和update.js.erb中使用Javascript以正确的方法重新加载表单吗
多谢各位
编辑~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(请参见上面的编辑)
我采纳了您的建议,将随机id添加到表单中,并更改了create.js.erb,但遇到了以下问题:
1) 在评级表被替换后,Javascript不再适用于该部分
这也是明星动态互动的咖啡脚本(实际上是无线电标签的形式)
编辑2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
更新操作正在提交所有表单的事实已更正。如果我没弄错的话
1。将生成的ID作为隐藏字段添加到表单中
该ID实际上不必是模型的虚拟属性,但可以是。另一个选项是将其置于质量分配数组之外,例如params[:controller]
也是
示例:
。有关创建随机字符串的其他可能性,请参阅
还要确保表单(或在表单部分中呈现的第一个元素)将生成的随机字符串作为id
或data-
属性,以便在下一步中无需使用复杂的选择器即可访问它
2。更新您的create.js.erb
我假设您的创建操作中的format.js
传递给create.js.erb
。因此,在这里,您通过搜索提交时传递的临时id,将整个表单替换为一个新表单
示例:$('#')。替换为(''代码>
确保不要忽略它,因为它会对呈现的表单进行编码,以便在javascript中保存使用。当您呈现您的常用表单时,create操作完成了它的常规业务,现在还用一个新的呈现表单替换了表单,其中自动调用了“update”操作(路由中常见的rails“魔术”功能,就像您呈现另一个常用的编辑表单一样)
Javascript
在评级表被替换后,Javascript不再适用于该部分
当然不是。您正在将事件绑定到文档加载时的特定元素。之后插入的元素(通过创建/更新)是新添加的,因此没有该事件绑定,因为它们在事件绑定发生时不可用
因为,您需要将代码绑定到一个容器,该容器在js修改过程中是持久的。假设您的create.js只更新/替换#rating_questions_container
中的元素,您需要将js重写为例如
$('#rating_questions_container').on('click', 'form.rating_ballot > label', function(e) {
# code
});
$(“#评级_问题_容器”)
是页面上的“持久”容器,可以捕获事件
.on('click'、'form.rating\u ballot>label'
监视与第二个参数中的选择器匹配的元素上的单击事件,此处为form.rating\u ballot>label
这允许在#rating_questions\u container
中动态附加/删除DOM节点,而不会丢失事件侦听器。您好,谢谢您的快速回答,我想我的问题不是很清楚,分为两部分。如果我理解正确,随机id将帮助定义我希望更新的特定表单?这将肯定会有帮助,因为我有5个类似的表单。在使用Ajax深入挖掘之后,当它重新加载表单时,它不会使用helper方法rating\u ballot
,该方法定义表单的路径rating\u questions/1/ratings\35; create
或rating\u questions/1/ratings/1#update
。我将尝试您的解决方案,看看它是否能解决问题这是我问题的一半:)是的,这就是随机id的意图。我看到了你的助手,这应该可以工作,因为你传递了一个包含两个对象的数组来构建路径。您只需要将表单放入一个分部,该分部可以同时处理创建
和更新
,现在应该是这样。因此,我按照您的建议进行了操作,但遇到了进一步的问题。1) 当我提交一个评分(无论是创建还是更新)时,它会为他们重新加载部分评分。2) 重新加载分部后,不再使用Coffescript文件中的jQuery。在我的原始帖子中查看我的编辑。更新我的答案以解决您的javascript问题。但我不明白你的第一个问题;你想更新部分,是吗?因为这会更新表单标记及其内部的所有内容,这是正常工作的update-form所必需的。好吧,这有点疯狂,但我结束了在所有地方添加.on()函数。现在一切都好了!非常感谢你,普德斯特勒!(由于某种原因,我必须等一个小时才能给赏金-。-)
def create
@rating_question = RatingQuestion.find_by_id(params[:rating_question_id])
@rating = Rating.new(params[:rating])
@rating.user_id = current_user.id
if @rating.save
respond_to do |format|
format.html { redirect_to rating_questions_path, :notice => "Your rating has been saved"}
format.js
end
end
end
def update
@rating_question = RatingQuestion.find_by_id(params[:rating_question_id])
@rating = current_user.ratings.find_by_rating_question_id(@rating_question.id)
if @rating.update_attributes(params[:rating])
respond_to do |format|
format.html { redirect_to rating_questions_path, :notice => "Your rating has been updated"}
format.js
end
end
end
$ ->
# Add the "Bright class" to the stars for each checked radio button before the document is ready.
$("form.rating_ballot").each ->
checkedId = undefined
checkedId = $(this).find("input:checked").attr("id")
$(this).find("label[for=" + checkedId + "]").prevAll().andSelf().addClass "bright"
$(document).ready ->
# makes stars glow on hover.
$("form.rating_ballot > label").hover (-> # mouseover
$(this).prevAll().andSelf().addClass "glow"
), -> # mouseout
$(this).siblings().andSelf().removeClass "glow"
# makes stars stay glowing after click.
$("form.rating_ballot > label").click ->
$(this).siblings().removeClass "bright"
$(this).prevAll().andSelf().addClass "bright"
# Submits the form (saves data) after user makes a change.
$(".rating_ballot").change ->
$(this).submit()
$('#rating_questions_container').on('click', 'form.rating_ballot > label', function(e) {
# code
});