suin.io

Rails: simple_formで値の表示だけ行う

suin2016年9月7日

SimpleFormでかゆい所のひとつに、入力系のコンポーネント以外がデフォルトで提供されていない点があります。例えば、ユーザが変更する必要がないけど、フォームに表示しておきたい値。具体的にどういうことかというと次のような例です。

= simple_form_for @job do |f|
  = f.association :project, as: :display, text: @project.display_name

と書いたら

<input class="form-control" type="hidden" value="2" name="job[project_id]">
<div>ShouldBee</div>

が描画されるようにしたい。

これを実現するには自分でカスタムコンポーネントを作る必要があります。次のapp/inputs/display_input.rbがそのコンポーネントです。これを作っておけば、simple_formで値の表示だけ行えるようになります。SimpleFormに習いMITライセンスにするので自由にお使いください。

app/inputs/display_input.rb
class DisplayInput < SimpleForm::Inputs::Base
  disable :errors, :hint, :required
  def input(wrapper_options = nil)
    text_tag = label_tag(nil, options[:text].present? ? options[:text] : object.send(attribute_name), label_html_options)
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    @builder.hidden_field(attribute_name, merged_input_options) + text_tag
  end

  def additional_classes
    @additional_classes ||= [input_type].compact # original is `[input_type, required_class, readonly_class, disabled_class].compact`
  end

  private

  def label_tag(name = nil, content_or_options = nil, options = nil, &block)
    if block_given? && content_or_options.is_a?(Hash)
      options = content_or_options = content_or_options.stringify_keys
    else
      options ||= {}
      options = options.stringify_keys
    end
    options['class'] = 'form-control-static'
    content_tag :div, content_or_options || name.to_s.humanize, options, &block
  end
end
RELATED POSTS