在我的ActiveAdmin Rails6应用程序内部,我在下面得到了partial,它取代了editor.js的标准输入(后面有一些js魔法,与这个问题无关(。部分和渲染图如下所示:
# _editor.html.erb
<%= f.input field, as: :hidden, input_html: { id: :editor_field } %>
<div style='width: 100%; background: white;' id="editorjs"></div>
# example of a parital call for field :body
<%= render 'admin/editor_js', f: f, field: :body %>
因为ActiveAdmin是基于formaticgem而不是这个部分的,所以我想创建并使用基于:text字段的自定义输入。我试着做下面这样的事情。
module CustomInputs
class EditorJsInput < Formtastic::Inputs::TextInput
def input_html_options
super.merge(input_html: { id: 'editor_field' }).merge(as: :hidden)
end
end
end
(as: :hidden)
不起作用,也不知道如何在<div style='width: 100%; background: white;' id="editorjs"></div>
的末尾添加这个空div,这是非常关键的。
as: :hidden
不是input_html_option,它是一种将输入映射到Inputs:HiddenInput类型的输入样式/类型;它真正做的只是将输入字段呈现为隐藏列表项。此外,覆盖input_html_options
的方式不正确:
# Let's say this is a line in your form input:
input_html: { value: 'Eat plants.' }
# Your code is changing `input_html_options` to be the same as if you'd
# included this in your form input declaration, which doesn't make sense:
input_html: {
value: 'Eat plants.',
input_html: { id: 'editor_field' },
as: :hidden
}
请查看您试图覆盖的方法的文档和来源:
- Formtastic::输入::HiddenInput
- Formtastic::输入::TextInput
如果您希望覆盖现有ID:,则覆盖的input_html_options
方法将类似于此
# Don't recommend
def input_html_options
# Note: this is dangerous because the 'id' attribute should be unique
# and merging it here instead of passing it in the field's `input_html`
# hash forces every input of this type to have the same id
super.merge(id: 'editor_field')
end
假设你真的想可靠地知道ID,这样一些JS就可以找到元素并将其交换出去,你可以在声明表单输入时在input_html
哈希中指定它,或者更干净地说,只需使用自动生成的ID。通常,ID是用下划线分隔的表单对象根键+属性名;因此,如果您的表单对象是coffee: { name: 'Goblin Sludge', origin_country: 'Columbia' }
,我认为默认情况下f.input :name
使用id='coffee_name'
进行渲染,f.input :origin_country
使用id='coffee_origin_country'
进行渲染。这是你可以通过在呈现的表单上使用devtools检查器很容易地弄清楚的东西
您似乎真的想覆盖to_html。你需要这样的东西:
# app/input/editor_js_input.rb
class EditorJsInput < Formtastic::Inputs::TextInput
def to_html
input_wrapping do
builder.hidden_field(method, input_html_options)
end
end
end
# Variation that creates a div
class EditorJsInput < Formtastic::Inputs::TextInput
def to_html
input_wrapping do
builder.content_tag(
:div,
'',
style: 'width: 100%; background: white;',
id: "#{input_html_options[:id]}_editor"
) << builder.hidden_field(method, input_html_options)
end
end
end
# Example of what this would generate:
# "<div style="width: 100%; background: white;" id="coffee_name_editor"></div><input maxlength="255" id="coffee_name" value="" type="hidden" name="coffee[name]" />"
# PARTIAL
# This will render the div you have above:
div style: 'width: 100%; background: white;', id: 'editorjs'
# This (or a similar variant of form declaration) will render the form
active_admin_form_for resource do |f|
f.inputs do
f.input :name,
input_html: { value: f.object.name },
as: :editor_js
f.input :origin_country,
input_html: { value: f.object.origin_country },
as: :editor_js
end
end
这应该将f.object.name
的输入构建为类似<input id="coffee_name" type="hidden" value="Goblin Sludge" name="coffee[name]">
的内容(请参阅FormBuilder#hidden_field
其他想法:
- 尝试使用Pry之类的东西在这些方法中添加绑定,以更好地了解它们的外观和工作方式。请注意,您需要重新启动服务器才能加载对自定义输入类中重写方法的更改
- 阅读以上参考文件和Formtastic自述;这里有很多真正可以访问的信息可以帮助你。您还可以在这里学习如何从ActiveAdmin的docu中呈现div(以及ActiveAdmin.info中提供样式元素示例的其他页面(
- 评估是否需要实现自定义FormBuilder