Summernote 编辑器不支持嵌套表单
Summernote editor not working with nested forms
我正在尝试在我的 ruby-on-rails 应用
这是我的模型:
class Dog < ApplicationRecord
has_many :pictures, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :pictures, reject_if: :all_blank, allow_destroy: true
end
乍一看新建或编辑页面似乎还不错。第一个 summary 字段使用 summernote 正确渲染。如果我已经将几张照片保存到我的 dog 模型中,它们在编辑页面上看起来都非常好。
但是,当我单击 "add picture" 时,它会创建新的图片字段,其中 summary 字段无法使用 summernote 正确呈现。在 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>
而不是这个:
<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>
这是我的 _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 %>
这是我的_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>
我还尝试使用 drifting ruby 从头开始构建嵌套表单。但它会导致同样的问题
在页面中动态插入项目时,您还必须在这些项目上初始化 summernote 编辑器。 Cocoon 具有允许您执行此操作的回调。
加载页面时,要初始化 summernote,您可以执行类似
的操作
$('[data-provider="summernote"]').each ->
$(this).summernote
(从summernote-rails gem文档中复制)
但这只适用于页面上已有的 "summernote",它不能初始化 还不存在的注释。
因此,在插入嵌套项目后,我们必须使用相同的代码来初始化插入的注释。这样的事情应该有效:
$('form').on('cocoon:after-insert', function(e, insertedItem) {
insertedItem.find('[data-provider="summernote"]').each(function() {
$(this).summernote();
})
});
这将在新嵌套项目中查找 summernote 项目并初始化它们。
[编辑:改进 javascript 以从视图中提取它]
Javascript 文件通常分组在 app/assets/javascripts
中,如果您正在编辑 Dog
s 让我们添加一个新文件 dogs.js
并输入以下代码:
$(document).on('cocoon:after-insert', 'form', function(e, insertedItem) {
insertedItem.find('[data-provider="summernote"]').each(function() {
$(this).summernote();
})
});
然后使用 require dogs
将此文件添加到您的 application.js
。
此代码在文档上注册了一个事件处理程序,它将侦听在 form
上触发的任何 cocoon:after-insert
事件。如果您有多个使用 cocoon 的表单,您可能需要一个 better/more 精确的 css 选择器(例如,向表单添加一个 class 并将其也添加)。
我正在尝试在我的 ruby-on-rails 应用
这是我的模型:
class Dog < ApplicationRecord
has_many :pictures, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :pictures, reject_if: :all_blank, allow_destroy: true
end
乍一看新建或编辑页面似乎还不错。第一个 summary 字段使用 summernote 正确渲染。如果我已经将几张照片保存到我的 dog 模型中,它们在编辑页面上看起来都非常好。 但是,当我单击 "add picture" 时,它会创建新的图片字段,其中 summary 字段无法使用 summernote 正确呈现。在 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>
而不是这个:
<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>
这是我的 _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 %>
这是我的_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>
我还尝试使用 drifting ruby 从头开始构建嵌套表单。但它会导致同样的问题
在页面中动态插入项目时,您还必须在这些项目上初始化 summernote 编辑器。 Cocoon 具有允许您执行此操作的回调。
加载页面时,要初始化 summernote,您可以执行类似
的操作$('[data-provider="summernote"]').each ->
$(this).summernote
(从summernote-rails gem文档中复制)
但这只适用于页面上已有的 "summernote",它不能初始化 还不存在的注释。
因此,在插入嵌套项目后,我们必须使用相同的代码来初始化插入的注释。这样的事情应该有效:
$('form').on('cocoon:after-insert', function(e, insertedItem) {
insertedItem.find('[data-provider="summernote"]').each(function() {
$(this).summernote();
})
});
这将在新嵌套项目中查找 summernote 项目并初始化它们。
[编辑:改进 javascript 以从视图中提取它]
Javascript 文件通常分组在 app/assets/javascripts
中,如果您正在编辑 Dog
s 让我们添加一个新文件 dogs.js
并输入以下代码:
$(document).on('cocoon:after-insert', 'form', function(e, insertedItem) {
insertedItem.find('[data-provider="summernote"]').each(function() {
$(this).summernote();
})
});
然后使用 require dogs
将此文件添加到您的 application.js
。
此代码在文档上注册了一个事件处理程序,它将侦听在 form
上触发的任何 cocoon:after-insert
事件。如果您有多个使用 cocoon 的表单,您可能需要一个 better/more 精确的 css 选择器(例如,向表单添加一个 class 并将其也添加)。