在simple form的github中 https://github.com/plataformatec/simple_form
Custom inputs
It is very easy to add custom inputs to Simple Form. For instance, if you want to add a custom input that extends the string one, you just need to add this file:
# app/inputs/currency_input.rb class CurrencyInput < SimpleForm::Inputs::Base def input(wrapper_options) merged_input_options = merge_wrapper_options(input_html_options, wrapper_options) "$ #{@builder.text_field(attribute_name, merged_input_options)}".html_safe end end
And use it in your views:
f.input :money, as: :currency
Note, you may have to create the app/inputs/
directory and restart your webserver.
现在有个需求,我需要上传图片并预览,所以需要自定义表单
第一步: 在app目录下新建inputs目录
第二步: 新建表单文件, 如image_media_input.rb, 需要有_input
第三步: 复制示例代码,并把class改为自己的名字,如ImageMediaInput
通常我们在自定义是,需要获取data属性,和value值
data = options[:data] || {}
value = object.send(attribute_name)
可以使用content_tag新建dom,当然也可以用html拼接
如tap_text = content_tag :small, hint_text, class: 'form-text text-muted'
如images = "<li><img src='#{value}' /><span class='delete-image'></span><p>#{value}</p></li>"
对于多个dom可以用template.concat组合,也可以用[].join&.html_safe组合
因为样式问题,我同时自定义了hint属性
代码:
class ImageMediaInput < SimpleForm::Inputs::Base
def input(wrapper_options = nil)
# 获取data属性
data = options[:data] || {}
class_name = self.class.name.underscore.dasherize
# [link, spinner, hidden, list_panel].join&.html_safe
template.content_tag(:div, class: "media #{class_name} media-picker") do
# 获取值
value = object.send(attribute_name)
value_v = value.to_json if value.is_a?(Array)
# 上传按钮
picker_button = content_tag :button,
'',
class: "button media-picker-button",
id: attribute_name.to_s + '_uploader',
type: 'button',
data: data
template.concat picker_button
# 隐藏域
input_field = @builder.hidden_field(attribute_name, value: value_v)
template.concat input_field
end
end
def hint(wrapper_options = nil)
# 获取data属性
data = options[:data] || {}
hint_text = '图片格式: jpg, png, gif, jpeg'
# 获取值
value = object.send(attribute_name)
images = ''
if value.present?
if data[:multipe].present?
hint_text = '支持多图上传,图片格式: jpg, png, gif, jpeg'
value.each do |image|
images += "<li><img src='#{image}' /><span class='delete-image'></span><p>#{image}</p></li>"
end
else
images = "<li><img src='#{value}' /><span class='delete-image'></span><p>#{value}</p></li>"
end
end
template.content_tag(:div, class: 'media-list-box') do
# 提示
tap_text = content_tag :small, hint_text, class: 'form-text text-muted'
template.concat tap_text
# 图片列表
ulsd = content_tag :ul, images&.html_safe, class: 'clearfix'
image_list = content_tag :div, ulsd, class: 'image-list'
template.concat image_list
end
end
end