使用 RJS 注入后将 JavaScript 处理程序添加到远程表单对象

发布于 2024-09-29 17:09:37 字数 3202 浏览 4 评论 0原文

我有一个页面表单,我希望用户通过单击远程链接(“添加照片”,例如)来添加嵌套表单。单击按钮后,我使用 RJS 注入嵌套表单。注入的表单是远程表单,但注入后,表单没有附加 javascript 事件,因此它们只是使用 http 提交到嵌套对象的控制器。除此之外,一切正常。

我的问题是:

注入后是否可以通过 RJS 触发远程表单的 javascript 重新验证?

这样我的嵌套表单将获得正确的 javascript 事件处理并使用 AJAX 提交。

我的页面表单 (_form.html.erb):

<% javascript 'ckeditor/ckeditor' %>

<%= form_for @page, :html => { :multipart => true } do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.label :homepage %><br />
    <%= f.check_box :homepage %>
  </p>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 5, :cols => 80 %>
  </p>
  <p>
    <%= f.label :text %><br />
    <%= f.text_area :text, :class => 'html' %>
  </p>
  <p>
    <%= f.label :picture_class %><br />
    <%= f.select :picture_class, ['left','right','full'] %>
  </p>

 <% unless @page.new_record? %>
  <h2>Photos</h2>
  <%= link_to 'Add photo', add_photo_page_url(@page), :remote => true %>
  <div id="photos">
  <%= render :partial => 'shared/forms/photo', :collection => @page.photos %>
  </div>
  <h2>Snippets</h2>
  <%= link_to 'Add snippet', add_snippet_page_url(@page), :remote => true %>
  <div id="snippets">
  <%= render :partial => 'shared/forms/photo', :collection => @page.snippets %>
  </div>
  <h2>Downloads</h2>
  <%= link_to 'Add download', add_download_page_url(@page), :remote => true %>
  <div id="downloads">
  <%= render :partial => 'shared/forms/download', :collection => @page.downloads %>
  </div>
  <h2>Paragraphs</h2>
  <%= link_to 'Add paragraph', add_paragraph_page_url(@page), :remote => true %>
  <div id="paragraphs">
  <%= render :partial => 'shared/forms/paragraph', :collection => @page.paragraphs %>
  </div>
 <% end %>

  <p><%= f.submit %></p>
<% end %>

<%= javascript_tag 'CKEDITOR.replaceAll("html");' %>

用于构建嵌套照片对象的控制器代码:(page_controller.rb):

def add_photo
  @page = Page.find(params[:id])
  @photo = @page.photos.build
end

通过单击“添加照片”执行的 RJS 代码 (add_photo.js.rjs):

page.insert_html :bottom, :photos, :partial => 'shared/forms/photo', :object => @photo
page.visual_effect :highlight, :photos, :duration => 2

该部分/表单注入 RJS (_photo.html.erb):

<%= form_for [@page, photo], :remote => true do |f| %>
<p>
  <%= f.check_box :active %>
  <%= f.text_field :name %>
  <%= f.file_field :photo %>
  <%= f.submit 'Save' %>
</p>
<% end %>

任何帮助将不胜感激。我想用嵌套表单(不是嵌套属性)和 RJS 来解决这个问题,但无法通过 google 搜索到有关此问题的文档。

谢谢!!

——雅各布

I have a page form, where i want the user to add nested forms by clicking on a remote link ('add photo', f. ex). Upon clicking the button I inject the nested forms with RJS. The injected forms are remote forms, but after injection the forms have no javascript events attached so they just submit with http to the controller of the nested object. Beside that, everything works fine.

My question is:

Is it possible to trigger revalidation of javascript of remote forms via RJS, after injection??

That way my nested forms would get the proper javascript event handling and submit with AJAX.

My page form (_form.html.erb):

<% javascript 'ckeditor/ckeditor' %>

<%= form_for @page, :html => { :multipart => true } do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.label :homepage %><br />
    <%= f.check_box :homepage %>
  </p>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 5, :cols => 80 %>
  </p>
  <p>
    <%= f.label :text %><br />
    <%= f.text_area :text, :class => 'html' %>
  </p>
  <p>
    <%= f.label :picture_class %><br />
    <%= f.select :picture_class, ['left','right','full'] %>
  </p>

 <% unless @page.new_record? %>
  <h2>Photos</h2>
  <%= link_to 'Add photo', add_photo_page_url(@page), :remote => true %>
  <div id="photos">
  <%= render :partial => 'shared/forms/photo', :collection => @page.photos %>
  </div>
  <h2>Snippets</h2>
  <%= link_to 'Add snippet', add_snippet_page_url(@page), :remote => true %>
  <div id="snippets">
  <%= render :partial => 'shared/forms/photo', :collection => @page.snippets %>
  </div>
  <h2>Downloads</h2>
  <%= link_to 'Add download', add_download_page_url(@page), :remote => true %>
  <div id="downloads">
  <%= render :partial => 'shared/forms/download', :collection => @page.downloads %>
  </div>
  <h2>Paragraphs</h2>
  <%= link_to 'Add paragraph', add_paragraph_page_url(@page), :remote => true %>
  <div id="paragraphs">
  <%= render :partial => 'shared/forms/paragraph', :collection => @page.paragraphs %>
  </div>
 <% end %>

  <p><%= f.submit %></p>
<% end %>

<%= javascript_tag 'CKEDITOR.replaceAll("html");' %>

Controller code to build the nested photo object: (page_controller.rb):

def add_photo
  @page = Page.find(params[:id])
  @photo = @page.photos.build
end

RJS code that gets executed by clicking 'add photo' (add_photo.js.rjs):

page.insert_html :bottom, :photos, :partial => 'shared/forms/photo', :object => @photo
page.visual_effect :highlight, :photos, :duration => 2

The partial/form that gets injected with RJS (_photo.html.erb):

<%= form_for [@page, photo], :remote => true do |f| %>
<p>
  <%= f.check_box :active %>
  <%= f.text_field :name %>
  <%= f.file_field :photo %>
  <%= f.submit 'Save' %>
</p>
<% end %>

Any help would be appreciated. I would like to solve this with nested forms (not nested attributes) and RJS, but was unable to google my way to documentation on this.

Thanks!!

-- Jakob

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如梦亦如幻 2024-10-06 17:09:37

如果您想坚持使用 RJS,则需要查看内置的 javascript 以了解它们如何注册所有内容。他们可能只是在 DOM 就绪时执行此操作并绑定到 Submit() 事件。它很可能封装在一个方法中,该方法查找标记为 :remote => 的任何内容。 true 并绑定到submit() 事件,因此它将通过AJAX 提交。您可以执行相同的逻辑,但将其隔离到新表单中。因此,也许您的部分可能有一个 JavaScript 标记,它根据 id 或类名执行该表单的逻辑,忽略除最近添加的表单之外的所有内容。

If you want to stick with RJS, you'll need to look into the built-in javascript to see how they're registering everything. They probably just do it on DOM ready and bind to the submit() event. It's most likely encapsulated in a method which looks for anything marked :remote => true and binds to the submit() event so it will submit via AJAX. You can execute the same logic but isolate it to your new form. So maybe your partial could have a JavaScript tag which executes that logic for that form, based on the id, or based on the classname, ignoring everything but the most recently added form.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文