Rails6在现有的基础上创建了自定义的formtastic输入



在我的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

最新更新