Class: Charming::Components::Form
- Inherits:
-
Charming::Component
- Object
- View
- Charming::Component
- Charming::Components::Form
- Defined in:
- lib/charming/presentation/components/form.rb,
lib/charming/presentation/components/form/note.rb,
lib/charming/presentation/components/form/field.rb,
lib/charming/presentation/components/form/input.rb,
lib/charming/presentation/components/form/select.rb,
lib/charming/presentation/components/form/builder.rb,
lib/charming/presentation/components/form/confirm.rb,
lib/charming/presentation/components/form/textarea.rb,
lib/charming/presentation/components/form/multiselect.rb
Overview
Form is a multi-field form component with built-in focus traversal, validation, and
submit/cancel handling. Fields are produced by Form::Builder (see controller.form)
and bound to a per-form mutable state hash. Tab/Shift+Tab cycles focus through
focusable fields, Enter advances to the next field (or submits on the last), Escape
cancels, and Ctrl+S submits from any field.
Exception: inside a Textarea field, Enter inserts a newline (it's a text editor) — leave it with Tab and submit with Ctrl+S, matching charm.sh's huh behavior.
Defined Under Namespace
Classes: Builder, Confirm, Field, Input, Multiselect, Note, Select, Textarea
Instance Attribute Summary collapse
-
#fields ⇒ Object
readonly
The list of field objects and the mutable state hash the form is bound to.
-
#state ⇒ Object
readonly
The list of field objects and the mutable state hash the form is bound to.
Instance Method Summary collapse
-
#captures_text? ⇒ Boolean
Forms accept free-typed text (their input/textarea fields do), so printable characters route here before global/content key bindings.
-
#handle_key(event) ⇒ Object
Handles key events: Escape cancels, Ctrl+S submits, Tab cycles focus, Enter advances or submits, and unhandled keys are passed to the focused field.
-
#handle_paste(event) ⇒ Object
Forwards pasted text to the currently focused field.
-
#initialize(fields:, state: nil, theme: nil) ⇒ Form
constructor
fields is the array of form field objects.
-
#render ⇒ Object
Renders each field on its own line, marking the active field with
active: true. -
#values ⇒ Object
Returns a hash of
{field_name => value}for the current field values.
Methods inherited from View
Constructor Details
#initialize(fields:, state: nil, theme: nil) ⇒ Form
fields is the array of form field objects. state is a hash for storing field
values/errors and the current focus index; usually session[:forms][form_name].
19 20 21 22 23 24 25 |
# File 'lib/charming/presentation/components/form.rb', line 19 def initialize(fields:, state: nil, theme: nil) super(theme: theme) @fields = fields @state = normalize_state(state || {}) bind_fields clamp_focus end |
Instance Attribute Details
#fields ⇒ Object (readonly)
The list of field objects and the mutable state hash the form is bound to.
15 16 17 |
# File 'lib/charming/presentation/components/form.rb', line 15 def fields @fields end |
#state ⇒ Object (readonly)
The list of field objects and the mutable state hash the form is bound to.
15 16 17 |
# File 'lib/charming/presentation/components/form.rb', line 15 def state @state end |
Instance Method Details
#captures_text? ⇒ Boolean
Forms accept free-typed text (their input/textarea fields do), so printable characters route here before global/content key bindings.
49 50 51 |
# File 'lib/charming/presentation/components/form.rb', line 49 def captures_text? true end |
#handle_key(event) ⇒ Object
Handles key events: Escape cancels, Ctrl+S submits, Tab cycles focus, Enter advances or submits, and unhandled keys are passed to the focused field.
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/charming/presentation/components/form.rb', line 29 def handle_key(event) key = Charming.key_of(event) return :cancelled if key == :escape return submit if submit_shortcut?(event) return move_focus(tab_direction(event)) if key == :tab result = handle_current_field(event) return result if result advance_or_submit if key == :enter end |
#handle_paste(event) ⇒ Object
Forwards pasted text to the currently focused field. Text fields insert it at their cursor; other fields ignore it.
43 44 45 |
# File 'lib/charming/presentation/components/form.rb', line 43 def handle_paste(event) current_field&.handle_paste(event) end |
#render ⇒ Object
Renders each field on its own line, marking the active field with active: true.
59 60 61 62 63 |
# File 'lib/charming/presentation/components/form.rb', line 59 def render fields.each_with_index.map do |field, index| field.render(active: index == state[:focus_index]) end.join("\n") end |
#values ⇒ Object
Returns a hash of {field_name => value} for the current field values.
54 55 56 |
# File 'lib/charming/presentation/components/form.rb', line 54 def values state[:values] end |