Class: Uchi::Field::Select

Inherits:
Field
  • Object
show all
Defined in:
app/components/uchi/field/select.rb

Defined Under Namespace

Classes: Edit, Index, Show

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Select

Returns a new instance of Select.



61
62
63
64
# File 'app/components/uchi/field/select.rb', line 61

def initialize(name)
  super
  @options = {}
end

Instance Method Details

#flat_optionsObject

Resolves and memoizes the options as a flat value => label Hash, keyed by the string representation of each option's value so #label_for can look up a label in constant time. Memoized so that a Proc given to #options is only called once per field instance - see #resolved_options for details. The memo is cleared whenever #options is called with a new value.

When the same value appears in more than one group, the first matching label wins - matching how a browser's <select> element only ever selects the first option with a matching value.



45
46
47
48
49
50
51
52
53
# File 'app/components/uchi/field/select.rb', line 45

def flat_options
  @flat_options ||= resolved_options.each_with_object({}) { |(key, value), flat|
    if value.is_a?(Hash)
      value.each { |group_key, group_label| flat[group_key.to_s] = group_label unless flat.key?(group_key.to_s) }
    else
      flat[key.to_s] = value unless flat.key?(key.to_s)
    end
  }
end

#grouped?Boolean

Returns true if the configured options are grouped, ie. a non-empty Hash whose values are all themselves Hashes of options.

Returns:



57
58
59
# File 'app/components/uchi/field/select.rb', line 57

def grouped?
  resolved_options.present? && resolved_options.values.all? { |value| value.is_a?(Hash) }
end

#label_for(value) ⇒ Object

Returns the label to display for the given value, or nil if the value doesn't match any of the configured options.

Values are compared using their string representation, matching how a <select> element compares its options' values against the persisted attribute value.



72
73
74
75
76
# File 'app/components/uchi/field/select.rb', line 72

def label_for(value)
  return if value.nil?

  flat_options[value.to_s]
end

#options(options = Configuration::Unset) ⇒ self, Hash

Sets or gets the options to choose between.

When called with an argument, sets the options and returns self for chaining. When called without arguments, returns the current options, resolved to a Hash.

Examples:

Setting with a Hash

Field::Select.new(:size).options({s: "Small", m: "Medium", l: "Large"})

Setting with an Array

Field::Select.new(:size).options(["Small", "Medium", "Large"])

Setting with a Proc

Field::Select.new(:size).options(-> { Size.pluck(:key, :name).to_h })

Setting grouped options

Field::Select.new(:size).options({
  "Letters" => {s: "Small", m: "Medium", l: "Large"},
  "Numbers" => ["32", "34", "36"]
})

Getting

field.options # => {s: "Small", m: "Medium", l: "Large"}

Parameters:

  • options (Hash, Array, Proc) (defaults to: Configuration::Unset)

    A hash mapping stored values to their human-readable labels. An array can be given instead, in which case each item is used as both the stored value and its label. A proc can also be given; it's called with no arguments and should return a Hash or an Array as described above.

    To group options, pass a Hash whose values are themselves a Hash or Array of options, keyed by the group label.

Returns:

  • (self, Hash)

    Returns self for method chaining when setting, or the options hash when getting



112
113
114
115
116
117
118
119
# File 'app/components/uchi/field/select.rb', line 112

def options(options = Configuration::Unset)
  return resolved_options if options == Configuration::Unset

  @options = options
  @resolved_options = nil
  @flat_options = nil
  self
end