Skip to content

Create an "input" just for displaying attribute value

Humberto edited this page Nov 3, 2016 · 3 revisions

Create an input just for displaying an attribute value

Purpose

Sometimes you just want to display something (like email or user ID) that cannot be changed or can only be changed in another page But you still want to show it as part of the form

If you use readonly, users might still manipulate the input value (well rails4 is not out yet when I am typing) If you (re)create a similar structure like the one generated by simple_form, it's stupid and you need to change it again when you change the generated structure


Code

Only tested with string Improve and UPDATE this page when necessary

app/inputs/display_input.rb:

class DisplayInput < SimpleForm::Inputs::Base
  # This method usually returns input's html like <input ... />
  # but in this case it returns just a value of the attribute.
  def input
    # label code from https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/components/labels.rb#28
    template.label_tag(nil, object.send(attribute_name), label_html_options)
  end

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

If you don't want label, use span instead:

template.content_tag(:span, object.send(attribute_name))

Custom labels from association objects attributes

Just pass an association_label option with the attribute you need to use. Like this:

f.association :payoff_parameter, as: :display, association_label: 'name', label: false

change the code above to:

template.label_tag(nil, label_content, label_html_options)

And add

def label_content
  attributes = []
  attributes << reflection_or_attribute_name
  attributes << options[:association_label] if options[:association_label]

  attributes.inject(object) do |obj, attribute|
    obj.public_send(attribute)
  end
end

Fake Input

Create a fake input that does NOT read attributes