简体   繁体   English

Summernote编辑器无法使用嵌套表单

[英]Summernote editor not working with nested forms

I'm trying to use cocoon-gem and summernote-gem in my ruby-on-rails app. 我正在尝试在我的ruby-on-rails应用程序中使用cocoon-gemsummernote-gem
This is my model: 这是我的模型:

class Dog < ApplicationRecord
    has_many :pictures, as: :imageable, dependent: :destroy
    accepts_nested_attributes_for :pictures, reject_if: :all_blank, allow_destroy: true
end

At first look new or edit page seems alright. 乍一看,新建或编辑页面似乎还不错。 First summary field render with summernote correctly. 第一个摘要字段正确显示了summernote。 And if I already have several pictures saved to my dog model, they all look perfectly fine on editing page. 而且,如果我已经保存了几张图片到我的模型中,那么在编辑页面上它们看起来都很好。 But when I click on "add picture" it creates new picture field with summary field not rendered properly with summernote. 但是,当我单击“添加图片”时,它将创建新图片字段,而摘要字段未使用summernote正确呈现。 In html page it looks like this: 在html页面中,它看起来像这样:

<div class="field">
    <label class="string optional" for="dog_pictures_attributes_1544609860934_summary">Summary</label>
    <textarea data-provider="summernote" name="dog[pictures_attributes][1544609860934][summary]" id="dog_pictures_attributes_1544609860934_summary"></textarea>
</div>

Instead of this: 代替这个:

<div class="field">
    <label class="string optional" for="dog_pictures_attributes_1_summary">Summary</label>
    <textarea data-provider="summernote" name="dog[pictures_attributes][1][summary]" id="dog_pictures_attributes_1_summary" style="display: none;"></textarea>
    <div class="note-editor note-frame">...</div>
</div>

This is my _form.erb: (if relevant) 这是我的_form.erb :(如果相关)

<%= simple_form_for @dog, defaults: { required: false } do |f| %>
  <div class="field">
    <%= f.label 'Note' %>
    <%= f.text_area :note, 'data-provider': :summernote %>
  </div>
  <h2> Add pictures </h2>
  <%= f.fields_for :pictures do |picture| %>
    <%= render 'picture_fields', :f => picture %>
  <% end %>
  <div class='links'>
    <%= link_to_add_association 'add picture', f, :pictures %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

And this is my _ picture_fields.erb: 这是我的_ picture_fields.erb:

<div class='nested-fields'>
  <div class="field">
    <%= f.file_field :image %>
  </div>
  <div class="field">
    <%= f.label :author %>
    <%= f.text_field :author %>
  </div>
  <div class="field">
    <%= f.label :summary %>
    <%= f.text_area :summary, 'data-provider': :summernote %>
  </div>
    <%= link_to_remove_association "remove picture", f %>
</div>

I also tried to build nested form from scratch with drifting ruby . 我还尝试使用漂移的红宝石从头开始构建嵌套表单。 But it cause the same problem 但这会引起同样的问题

When dynamically inserting items into the page, you will have to initialize the summernote editor on those items as well. 在项目中动态插入项目时,还必须在这些项目上初始化summernote编辑器。 Cocoon has callbacks to allow you to do this. Cocoon具有回调,可让您执行此操作。

When loading the page, to initialize summernote, you would do something like 加载页面时,要初始化summernote,您需要执行以下操作

$('[data-provider="summernote"]').each ->
    $(this).summernote

(copied from the summernote-rails gem documentation) (摘自summernote-rails gem文档)

But this only works for the "summernote"'s already on the page, it cannot initialize notes that are not yet there. 但这仅适用于页面上已存在的“ summernote”,它无法初始化尚不存在的注释。

So, after inserting a nested-items we have to use the same code to initialise the inserted notes. 因此,在插入嵌套项目之后,我们必须使用相同的代码来初始化插入的注释。 Something like this should work: 这样的事情应该起作用:

$('form').on('cocoon:after-insert', function(e, insertedItem) {
    insertedItem.find('[data-provider="summernote"]').each(function() {
      $(this).summernote();  
    })  
});

This will look for summernote items in the freshly nested-item and initialise those. 这将在新嵌套的项目中查找summernote项目并将其初始化。

[EDIT: improve javascript to extract it from view] [编辑:改进javascript以从视图中提取它]

Javascript files are generally grouped in app/assets/javascripts , if you are editing Dog s let's add a new file dogs.js and enter the following code: Javascript文件通常在app/assets/javascripts分组,如果您要编辑Dog ,那么我们添加一个新文件dogs.js并输入以下代码:

$(document).on('cocoon:after-insert', 'form', function(e, insertedItem) {
    insertedItem.find('[data-provider="summernote"]').each(function() {
      $(this).summernote();  
    })  
});

Then add this file to your application.js using require dogs . 然后使用require dogs将此文件添加到application.js

This code registers an event handler on the document, it will listen to any cocoon:after-insert event triggered on a form . 此代码在文档上注册了一个事件处理程序,它将侦听form上触发的任何cocoon:after-insert事件。 If you have multiple forms using cocoon, you might need a better/more precise css selector (eg add a class to the form and add that as well). 如果您使用茧形有多个表单,则可能需要一个更好/更精确的CSS选择器(例如,将一个类添加到表单中,并同时添加它)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM