Rails:无法提交通过Ajax加载的远程表单 [英] Rails: cannot submit a remote form that was loaded via Ajax

查看:115
本文介绍了Rails:无法提交通过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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆