如何解决Rails 6 基于现有输入创建自定义表单输入
在我的 ActiveAdmin Rails6 应用程序中,我得到了以下部分,它用 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 基于 formatic gem 而不是这个部分我想创建和使用基于 :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,它是一个 input style/type 将输入映射到 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
}
请查看有关您尝试覆盖的方法的文档和来源:
如果您希望覆盖现有 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 README;这里有很多真正可访问的信息可以帮助您。您还可以从 ActiveAdmin 的文档 here(以及 activeadmin.info 中提供样式元素示例的其他页面)中了解如何呈现 div
- 评估您是否需要实施Custom FormBuilder
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。