Rails:无法提交通过Ajax加载的远程表单 [英] Rails: cannot submit a remote form that was loaded via Ajax
问题描述
我有一个页面,其中列出了来自Rails后端的项目.我希望能够通过Rails UJS使用Ajax调用来编辑该列表中的一行.
I have a page with a list of items, coming from a Rails backend. I want to be able to edit a row in that list, using Ajax calls via Rails UJS.
我在每一行的末尾添加了一个编辑按钮.编辑按钮是一个
link_to ... :remote => true
.单击它会再次加载列表,但已选择
在编辑模式下的行.可编辑行嵌入在form ... :remote => true
中.
该行中的保存"按钮是submit
按钮.
I've added an edit button to the end of each row. The edit button is a
link_to ... :remote => true
. Clicking it loads the list again, but with the selected
row in edit mode. The editable row is embedded in a form ... :remote => true
.
The save button in that row is a submit
button.
index.html.haml
#editor
%table
- @items.each do |item|
%tr
= render :partial => 'row', :locals => { :item => item }
_row.html.haml
...
%td // a number of columns with attributes
...
%td
= link_to t("actions.edit"), edit_item_path(item), :remote => true
= link_to t("actions.delete"), item_path(item), :remote => true, :method => :delete, :data => { :confirm => "Are you sure?" }
edit.html.haml
#editor
%table
- @items.each do |item|
%tr
- if item == @item
= form_for @item, :url => item_path(@item), :remote => true, do |f|
= render :partial => "row_form", :locals => { :f => f }
- else
= render :partial => 'row', :locals => { :item => item }
_row_form.html.haml
...
%td // a number of columns with editable attributes
...
%td
%button{ :type => "submit" }=t("actions.save")
= link_to t("actions.cancel"), items_path, :remote => true
Ajax响应处理
$("#editor").on("ajax:success", function(event, data, status, xhr) {
$("#editor").html($(data).find("#editor").html());
});
问题
当我以编辑模式/items/12/edit
加载列表页面时,项目12的行为
可编辑的.单击保存按钮可通过Ajax正确提交表单并加载
/items
索引部分,将可编辑列表替换为jQuery.点击
再次点击编辑按钮,然后再次加载编辑页面(例如/items/12/edit
),
嵌入式表格.仅这次,表单不再在以下情况下提交
单击保存按钮.似乎Submit事件处理程序未附加到
动态加载的远程表单.
Problem
When I load a list page in edit mode /items/12/edit
, the row of item 12 is
editable. Clicking the save button submits the form via Ajax correctly and loads
the /items
index partial, replacing the editable list with jQuery. Clicking
the edit button again, loads the edit page again (e.g. /items/12/edit
), with
the embedded form. Only this time, the form does not get submitted anymore when
the save button is clicked. It seems the submit event handler is not attached to the
dynamically loaded remote form.
如何提交通过Ajax加载的远程表单,最好使用Rails UJS方法?
How can I submit a remote form loaded via Ajax, preferrably using the Rails UJS approach?
我知道这个问题有重复的地方,但是没有一个被回答.我希望有人最终能给出明确的答案.
I know there are duplicates of this question, but none of them were answered. I hope someone finally comes up with a definite answer.
- Rails remote form loaded via Ajax after document ready is not submitting
- :remote => true/data-remote on a form loaded via ajax
推荐答案
我发现了问题!感谢@Jake Smith和@Parandroid的答案中的提示.这是我通过两个步骤发现的.
I found the problem! Thanks to the hints in the answers of both @Jake Smith and @Parandroid. Here's what I found in two steps.
虽然触发ajax:success
似乎不是问题,但确实看起来仅在$("#editor")
选择器上,表单处理不能正确地100%正常工作.至少必须是$("#editor form")
,但是如果我们从还不包含表单的索引页开始,那可能就行不通了.因此,@ Jake Smith建议的方法毕竟是最可靠的方法.结果是:
While getting the ajax:success
to be fired did not seem to be the problem, it did look like the form handling did not work 100% correctly just on the $("#editor")
selector. At the very least that needed to be $("#editor form")
, but that might not work if we start from the index page, which doesn't contain the form yet. So the approach suggested by @Jake Smith seemed to be the most robust way to go after all. This resulted in:
edit.html.haml
#editor
= render :partial => "edit"
edit.js.erb
$('#editor').html('<%= escape_javascript render("edit") %>');
_edit.html.haml(仍然无法运行)
%table
- @items.each do |item|
%tr
- if item == @item
= form_for @item, :url => item_path(@item), :remote => true, do |f|
= render :partial => "row_form", :locals => { :f => f }
- else
= render :partial => 'row', :locals => { :item => item }
但是,这仍然没有导致提交按钮正常工作.直到我发现出了什么问题...
But still this did not result in a working submit button. Until I discovered what went wrong...
以上解决方案确实使提交按钮具有普通的POST
行为,而服务器不喜欢这种行为,因为服务器希望PUT
达到update
动作. Rails通过生成值为PUT
的隐藏的_method
字段来做到这一点.我发现,rails在_edit.html.haml
部分的顶部和form
标签内的 not 的顶部中生成了该字段(以及其他一些重要的隐藏字段). !因此,我将表单移到了部分表单的顶部,并且成功了!
The solution above did give the submit button plain old POST
behavior, which the server did not like, since it expected a PUT
to reach the update
action. Rails does this by generating a hidden _method
field with the value PUT
. I found out that rails generates this field (and a couple of other crucial hidden fields) on the very top of the _edit.html.haml
partial and not inside the form
tag! So I moved the form to the top of the partial and it worked!
_edit.html.haml(工作!)
= form_for @item, :url => item_path(@item), :remote => true, do |f|
%table
- @items.each do |item|
%tr
- if item == @item
= render :partial => "row_form", :locals => { :f => f }
- else
= render :partial => 'row', :locals => { :item => item }
谁会猜到...
这篇关于Rails:无法提交通过Ajax加载的远程表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!