Class: Forms::Field
- Inherits:
-
Object
- Object
- Forms::Field
- Defined in:
- lib/forms/field.rb
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
Instance Method Summary collapse
-
#apply_validations(options) ⇒ Object
Merge a per-call
validate:override into the field's option hash. - #checkbox(*modifiers) ⇒ Object (also: #check_box)
-
#choices_select(choices = nil, *modifiers, **options) ⇒ Object
Enhanced select: choices.js-backed when searchable, native otherwise.
- #control(label: nil, hint: nil, required: false) ⇒ Object
- #field_id ⇒ Object
-
#field_label ⇒ Object
Humanized label text: the model's human_attribute_name when available.
- #field_name ⇒ Object
-
#field_value ⇒ Object
Ransack-safe getter: dispatches through method_missing consumers (e.g. Ransack::Search predicate getters) but only swallows the direct dispatch miss.
- #file(*modifiers) ⇒ Object
- #hidden ⇒ Object
-
#initialize(name:, model:, scope:, errors:, form:) ⇒ Field
constructor
A new instance of Field.
-
#input(*modifiers, type: :text) ⇒ Object
--- leaf component builders (return component instances to render) ---.
- #invalid? ⇒ Boolean
- #label(text = nil, *modifiers, &block) ⇒ Object
- #radio(value, *modifiers, **options) ⇒ Object (also: #radio_button)
-
#required? ⇒ Boolean
Inferred from the model's presence validators (ActiveModel).
- #rich_textarea(*modifiers) ⇒ Object (also: #rich_text_area)
- #select(choices = nil, **options) ⇒ Object
- #textarea(*modifiers) ⇒ Object (also: #text_area)
- #toggle(*modifiers) ⇒ Object
-
#wrapped_input(*modifiers, type: :text) ⇒ Object
daisyui v5 "icon/text inside the field" wrapper.
Constructor Details
#initialize(name:, model:, scope:, errors:, form:) ⇒ Field
Returns a new instance of Field.
12 13 14 15 16 17 18 |
# File 'lib/forms/field.rb', line 12 def initialize(name:, model:, scope:, errors:, form:) @name = name @model = model @scope = scope @errors = errors @form = form end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
10 11 12 |
# File 'lib/forms/field.rb', line 10 def errors @errors end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
10 11 12 |
# File 'lib/forms/field.rb', line 10 def model @model end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
10 11 12 |
# File 'lib/forms/field.rb', line 10 def name @name end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
10 11 12 |
# File 'lib/forms/field.rb', line 10 def scope @scope end |
Instance Method Details
#apply_validations(options) ⇒ Object
Merge a per-call validate: override into the field's option hash. Strips
:validate and, when rules apply, merges the Stimulus data into data:.
Falls back to the form-level introspector when :validate is absent.
validate: false → opt this field out
validate: true → the form-level introspector
validate: { length: {…} } → explicit inline rules
152 153 154 155 156 157 158 159 |
# File 'lib/forms/field.rb', line 152 def apply_validations() return consume_validate() if .key?(:validate) data = form_introspector.data_attributes_for(@name) return if data.empty? .merge(data: merge_data([:data], data)) end |
#checkbox(*modifiers) ⇒ Object Also known as: check_box
50 51 52 |
# File 'lib/forms/field.rb', line 50 def checkbox(*modifiers, **) Forms::Checkbox.new(*modifiers, checked: field_value, **field_attributes.except(:value), **) end |
#choices_select(choices = nil, *modifiers, **options) ⇒ Object
Enhanced select: choices.js-backed when searchable, native otherwise.
74 75 76 77 78 79 80 81 82 |
# File 'lib/forms/field.rb', line 74 def choices_select(choices = nil, *modifiers, **) searchable = .delete(:searchable) { false } opts = () if searchable Forms::ChoicesSelect.new(*modifiers, choices:, selected: field_value, searchable: true, **opts) else Forms::Select.new(*modifiers, choices:, selected: field_value, **opts) end end |
#control(label: nil, hint: nil, required: false) ⇒ Object
88 89 90 |
# File 'lib/forms/field.rb', line 88 def control(label: nil, hint: nil, required: false, **, &) Forms::FormControl.new(label:, hint:, error: , for: field_id, required:, **, &) end |
#field_id ⇒ Object
123 124 125 126 127 128 129 |
# File 'lib/forms/field.rb', line 123 def field_id if @scope "#{@scope.tr('[', '_').delete(']')}_#{@name}" else @name.to_s end end |
#field_label ⇒ Object
Humanized label text: the model's human_attribute_name when available.
95 96 97 98 99 100 101 |
# File 'lib/forms/field.rb', line 95 def field_label if @model.respond_to?(:class) && @model.class.respond_to?(:human_attribute_name) @model.class.human_attribute_name(@name) else @name.to_s.tr("_", " ").capitalize end end |
#field_name ⇒ Object
119 120 121 |
# File 'lib/forms/field.rb', line 119 def field_name @scope ? "#{@scope}[#{@name}]" : @name.to_s end |
#field_value ⇒ Object
Ransack-safe getter: dispatches through method_missing consumers (e.g. Ransack::Search predicate getters) but only swallows the direct dispatch miss.
133 134 135 136 137 138 139 140 141 |
# File 'lib/forms/field.rb', line 133 def field_value return nil unless @model @model.public_send(@name) rescue NoMethodError => e raise unless e.receiver.equal?(@model) && e.name == @name nil end |
#file(*modifiers) ⇒ Object
46 47 48 |
# File 'lib/forms/field.rb', line 46 def file(*modifiers, **) Forms::FileInput.new(*modifiers, **field_attributes.except(:value), **) end |
#hidden ⇒ Object
36 37 38 |
# File 'lib/forms/field.rb', line 36 def hidden(**) Forms::Input.new(type: :hidden, **field_attributes, **) end |
#input(*modifiers, type: :text) ⇒ Object
--- leaf component builders (return component instances to render) ---
22 23 24 |
# File 'lib/forms/field.rb', line 22 def input(*modifiers, type: :text, **) Forms::Input.new(*modifiers, type:, **field_attributes, **) end |
#invalid? ⇒ Boolean
115 116 117 |
# File 'lib/forms/field.rb', line 115 def invalid? @errors&.include?(@name) end |
#label(text = nil, *modifiers, &block) ⇒ Object
84 85 86 |
# File 'lib/forms/field.rb', line 84 def label(text = nil, *modifiers, **, &block) Forms::Label.new(*modifiers, text: text || (block ? nil : field_label), for: field_id, **, &block) end |
#radio(value, *modifiers, **options) ⇒ Object Also known as:
59 60 61 62 63 64 65 66 |
# File 'lib/forms/field.rb', line 59 def radio(value, *modifiers, **) Forms::Radio.new( *modifiers, value:, checked: field_value == value, **field_attributes.merge().merge(id: "#{field_id}_#{value}") ) end |
#required? ⇒ Boolean
Inferred from the model's presence validators (ActiveModel). False when the model doesn't expose validators.
105 106 107 108 109 110 111 112 113 |
# File 'lib/forms/field.rb', line 105 def required? return false unless @model.respond_to?(:class) && @model.class.respond_to?(:validators_on) @model.class.validators_on(@name).any? do |v| v.is_a?(ActiveModel::Validations::PresenceValidator) && !conditional?(v) end rescue StandardError false end |
#rich_textarea(*modifiers) ⇒ Object Also known as: rich_text_area
31 32 33 |
# File 'lib/forms/field.rb', line 31 def rich_textarea(*modifiers, **) Forms::RichTextarea.new(*modifiers, name: field_name, id: field_id, value: field_value, **) end |
#select(choices = nil, **options) ⇒ Object
69 70 71 |
# File 'lib/forms/field.rb', line 69 def select(choices = nil, **) Forms::Select.new(choices:, selected: field_value, **()) end |
#textarea(*modifiers) ⇒ Object Also known as: text_area
26 27 28 |
# File 'lib/forms/field.rb', line 26 def textarea(*modifiers, **) Forms::Textarea.new(*modifiers, **field_attributes, **) end |
#toggle(*modifiers) ⇒ Object
55 56 57 |
# File 'lib/forms/field.rb', line 55 def toggle(*modifiers, **) Forms::Toggle.new(*modifiers, checked: field_value, **field_attributes.except(:value), **) end |
#wrapped_input(*modifiers, type: :text) ⇒ Object
daisyui v5 "icon/text inside the field" wrapper. The block renders the leading content (icon, prefix); the bare input is wired to this field.
42 43 44 |
# File 'lib/forms/field.rb', line 42 def wrapped_input(*modifiers, type: :text, **, &) Forms::WrappedInput.new(*modifiers, type:, **field_attributes.except(:error), error: invalid?, **, &) end |