Class: InlineForms::AttributeList
- Inherits:
-
Array
- Object
- Array
- InlineForms::AttributeList
- Defined in:
- lib/inline_forms/attribute_list.rb
Overview
A structured, mutable view over a model's inline_forms_attribute_list.
The list has always been (and remains) an Array of positional rows:
[ :name, :text_field ]
[ :priority, :dropdown_with_values, { 1 => 'low', 2 => 'high' } ]
[ :priority2, :dropdown_with_values, { 1 => 'low', 2 => 'high' }, [ 2 ] ]
where index 0 is the attribute, index 1 the form element, index 2 an optional values hash, and index 3 an optional disabled-options array.
Every downstream consumer relies on that shape: the views destructure
|attribute, form_element|, and the helpers/validator fetch the values
hash positionally with list.assoc(attr)[2]. AttributeList therefore
subclasses Array and keeps rows as plain arrays — so an AttributeList
IS a valid attribute list everywhere the old literal array was, with zero
migration. What it adds is a small DSL/API for building and editing the
list procedurally (append / insert / remove / move / replace) instead of
hand-editing an array literal or regex-surgery on model source.
Build fresh:
InlineForms::AttributeList.build do
header :basics
field :name, :text_field
field :priority, :dropdown_with_values, values: { 1 => 'low', 2 => 'high' }
info :created_at, :updated_at
end
Wrap and edit an existing list (what generators / the staging pipeline do):
InlineForms::AttributeList.wrap(model.inline_forms_attribute_list)
.insert_after(:name, :internal_note, :text_field)
.remove(:legacy_field)
Mutating methods return self, so calls chain.
Class Method Summary collapse
-
.build(&block) ⇒ Object
Build a list from a block evaluated in the list's context.
-
.wrap(rows) ⇒ Object
Return
rowsas an AttributeList without copying when it already is one.
Instance Method Summary collapse
-
#field(name, form_element, values: nil, disabled: nil) ⇒ Object
(also: #add)
Append a row.
-
#form_element_for(name) ⇒ Object
The form element symbol for
name, or nil. -
#header(name) ⇒ Object
Append a
:headerpseudo-row (no column, no form element behavior). - #include_attribute?(name) ⇒ Boolean
-
#index_of(name) ⇒ Object
-- queries ----------------------------------------------------------.
-
#info(*names) ⇒ Object
Append one or more read-only
:inforows. -
#insert_after(anchor, name, form_element, values: nil, disabled: nil) ⇒ Object
-- insertion --------------------------------------------------------.
- #insert_before(anchor, name, form_element, values: nil, disabled: nil) ⇒ Object
-
#move_after(name, anchor) ⇒ Object
-- reordering -------------------------------------------------------.
- #move_before(name, anchor) ⇒ Object
- #names ⇒ Object
-
#remove(name) ⇒ Object
Remove every row for
name. -
#replace_element(name, form_element, values: nil, disabled: nil) ⇒ Object
Swap the form element (and optional values/disabled) for an existing attribute, preserving its position.
- #row_for(name) ⇒ Object
-
#values_for(name) ⇒ Object
The values hash for
name(row index 2), or nil.
Class Method Details
.build(&block) ⇒ Object
Build a list from a block evaluated in the list's context.
42 43 44 45 46 |
# File 'lib/inline_forms/attribute_list.rb', line 42 def self.build(&block) list = new list.instance_eval(&block) if block list end |
.wrap(rows) ⇒ Object
Return rows as an AttributeList without copying when it already is one.
49 50 51 52 53 |
# File 'lib/inline_forms/attribute_list.rb', line 49 def self.wrap(rows) return rows if rows.is_a?(self) new(rows || []) end |
Instance Method Details
#field(name, form_element, values: nil, disabled: nil) ⇒ Object Also known as: add
Append a row. values becomes index 2, disabled index 3 (disabled
requires values, since the slot is positional).
59 60 61 62 |
# File 'lib/inline_forms/attribute_list.rb', line 59 def field(name, form_element, values: nil, disabled: nil) push(build_row(name, form_element, values, disabled)) self end |
#form_element_for(name) ⇒ Object
The form element symbol for name, or nil.
134 135 136 137 |
# File 'lib/inline_forms/attribute_list.rb', line 134 def form_element_for(name) row = row_for(name) row && row[1] end |
#header(name) ⇒ Object
Append a :header pseudo-row (no column, no form element behavior).
66 67 68 |
# File 'lib/inline_forms/attribute_list.rb', line 66 def header(name) field(name, :header) end |
#include_attribute?(name) ⇒ Boolean
124 125 126 |
# File 'lib/inline_forms/attribute_list.rb', line 124 def include_attribute?(name) !index_of(name).nil? end |
#index_of(name) ⇒ Object
-- queries ----------------------------------------------------------
119 120 121 122 |
# File 'lib/inline_forms/attribute_list.rb', line 119 def index_of(name) sym = name.to_sym index { |row| row_name(row) == sym } end |
#info(*names) ⇒ Object
Append one or more read-only :info rows.
71 72 73 74 |
# File 'lib/inline_forms/attribute_list.rb', line 71 def info(*names) names.each { |n| field(n, :info) } self end |
#insert_after(anchor, name, form_element, values: nil, disabled: nil) ⇒ Object
-- insertion --------------------------------------------------------
78 79 80 |
# File 'lib/inline_forms/attribute_list.rb', line 78 def insert_after(anchor, name, form_element, values: nil, disabled: nil) insert_relative(anchor, 1, build_row(name, form_element, values, disabled)) end |
#insert_before(anchor, name, form_element, values: nil, disabled: nil) ⇒ Object
82 83 84 |
# File 'lib/inline_forms/attribute_list.rb', line 82 def insert_before(anchor, name, form_element, values: nil, disabled: nil) insert_relative(anchor, 0, build_row(name, form_element, values, disabled)) end |
#move_after(name, anchor) ⇒ Object
-- reordering -------------------------------------------------------
97 98 99 |
# File 'lib/inline_forms/attribute_list.rb', line 97 def move_after(name, anchor) relocate(name, anchor, 1) end |
#move_before(name, anchor) ⇒ Object
101 102 103 |
# File 'lib/inline_forms/attribute_list.rb', line 101 def move_before(name, anchor) relocate(name, anchor, 0) end |
#names ⇒ Object
145 146 147 |
# File 'lib/inline_forms/attribute_list.rb', line 145 def names map { |row| row_name(row) } end |
#remove(name) ⇒ Object
Remove every row for name. Idempotent: absent name is a no-op.
89 90 91 92 93 |
# File 'lib/inline_forms/attribute_list.rb', line 89 def remove(name) sym = name.to_sym reject! { |row| row_name(row) == sym } self end |
#replace_element(name, form_element, values: nil, disabled: nil) ⇒ Object
Swap the form element (and optional values/disabled) for an existing attribute, preserving its position. No-op if the attribute is absent.
109 110 111 112 113 114 115 |
# File 'lib/inline_forms/attribute_list.rb', line 109 def replace_element(name, form_element, values: nil, disabled: nil) idx = index_of(name) return self unless idx self[idx] = build_row(name, form_element, values, disabled) self end |
#row_for(name) ⇒ Object
128 129 130 131 |
# File 'lib/inline_forms/attribute_list.rb', line 128 def row_for(name) sym = name.to_sym find { |row| row_name(row) == sym } end |
#values_for(name) ⇒ Object
The values hash for name (row index 2), or nil.
140 141 142 143 |
# File 'lib/inline_forms/attribute_list.rb', line 140 def values_for(name) row = row_for(name) row && row[2] end |