Class: Lifeform::Form
- Inherits:
-
Object
- Object
- Lifeform::Form
- Extended by:
- Sequel::Inflections
- Includes:
- Streamlined::Renderable
- Defined in:
- lib/lifeform/form.rb
Overview
A form object which stores field definitions and can be rendered as a component
Constant Summary collapse
- MODEL_PATH_HELPER =
:polymorphic_path
Class Attribute Summary collapse
Instance Attribute Summary collapse
- #emit_form_tag ⇒ Boolean readonly
- #library ⇒ Class<Libraries::Default> readonly
- #model ⇒ Object readonly
- #parameters ⇒ Hash readonly
- #parent_name ⇒ Boolean readonly
- #url ⇒ String readonly
Class Method Summary collapse
- .configuration ⇒ Object
- .field(name, type: :text, library: self.library, **parameters) ⇒ Object
- .fields(&block) ⇒ Hash<Symbol, FieldDefinition>
- .inherited(subclass) ⇒ Object
- .initialize_field_definitions! ⇒ Object
- .library(library_name = nil) ⇒ Object
- .name_of_model(model) ⇒ Object
- .param_keys ⇒ Array<Symbol>
- .param_string_keys ⇒ Array<String>
- .parameters_to_attributes(kwargs) ⇒ Object
- .process_value(key, value) ⇒ Object
- .subform(name, klass, parent_name: nil) ⇒ Object
- .subforms ⇒ Object
-
.t ⇒ Object
Helper to point to ‘I18n.t` method.
Instance Method Summary collapse
- #add_authenticity_token ⇒ Object
- #attributes ⇒ Object
- #auto_render_fields ⇒ Object
- #field(name, **field_parameters) ⇒ Object
-
#initialize(model = nil, url: nil, library: self.class.library, emit_form_tag: true, parent_name: nil, **parameters) ⇒ Form
constructor
rubocop:disable Metrics/ParameterLists.
- #render(field_object) ⇒ Object
- #subform(name, model = nil) ⇒ Object
-
#template(&block) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity.
- #verify_method ⇒ Object
Constructor Details
#initialize(model = nil, url: nil, library: self.class.library, emit_form_tag: true, parent_name: nil, **parameters) ⇒ Form
rubocop:disable Metrics/ParameterLists
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/lifeform/form.rb', line 132 def initialize( # rubocop:disable Metrics/ParameterLists model = nil, url: nil, library: self.class.library, emit_form_tag: true, parent_name: nil, **parameters ) @model, @url, @library_name, @parameters, @emit_form_tag, @parent_name = model, url, library, parameters, emit_form_tag, parent_name @library = Libraries.const_get(self.class.send(:camelize, @library_name)) @subform_instances = {} self.class.initialize_field_definitions! @method = parameters[:method] ||= model.respond_to?(:persisted?) && model.persisted? ? :patch : :post parameters[:accept_charset] ||= "UTF-8" verify_method end |
Class Attribute Details
.rodauth ⇒ Object
29 |
# File 'lib/lifeform/form.rb', line 29 def rodauth = Form.instance_variable_get(:@rodauth) |
Instance Attribute Details
#emit_form_tag ⇒ Boolean (readonly)
127 128 129 |
# File 'lib/lifeform/form.rb', line 127 def emit_form_tag @emit_form_tag end |
#library ⇒ Class<Libraries::Default> (readonly)
121 122 123 |
# File 'lib/lifeform/form.rb', line 121 def library @library end |
#model ⇒ Object (readonly)
115 116 117 |
# File 'lib/lifeform/form.rb', line 115 def model @model end |
#parameters ⇒ Hash (readonly)
124 125 126 |
# File 'lib/lifeform/form.rb', line 124 def parameters @parameters end |
#parent_name ⇒ Boolean (readonly)
130 131 132 |
# File 'lib/lifeform/form.rb', line 130 def parent_name @parent_name end |
#url ⇒ String (readonly)
118 119 120 |
# File 'lib/lifeform/form.rb', line 118 def url @url end |
Class Method Details
.configuration ⇒ Object
31 |
# File 'lib/lifeform/form.rb', line 31 def configuration = @configuration ||= HashWithDotAccess::Hash.new |
.field(name, type: :text, library: self.library, **parameters) ⇒ Object
50 51 52 53 |
# File 'lib/lifeform/form.rb', line 50 def field(name, type: :text, library: self.library, **parameters) parameters[:name] = name.to_sym fields[name] = FieldDefinition.new(type, Libraries.const_get(camelize(library)), parameters) end |
.fields(&block) ⇒ Hash<Symbol, FieldDefinition>
35 36 37 38 39 40 |
# File 'lib/lifeform/form.rb', line 35 def fields(&block) @fields ||= {} @fields_setup_block = block if block @fields end |
.inherited(subclass) ⇒ Object
18 19 20 21 |
# File 'lib/lifeform/form.rb', line 18 def inherited(subclass) super subclass.library library end |
.initialize_field_definitions! ⇒ Object
42 43 44 45 46 |
# File 'lib/lifeform/form.rb', line 42 def initialize_field_definitions! return unless @fields_setup_block @fields_setup_block.(configuration) end |
.library(library_name = nil) ⇒ Object
59 60 61 62 |
# File 'lib/lifeform/form.rb', line 59 def library(library_name = nil) @library = library_name.to_sym if library_name @library ||= :default end |
.name_of_model(model) ⇒ Object
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/lifeform/form.rb', line 96 def name_of_model(model) return "" if model.nil? if model.respond_to?(:to_model) model.to_model.model_name.param_key else # Or just use basic underscore underscore(model.class.name).tr("/", "_") end end |
.param_keys ⇒ Array<Symbol>
108 |
# File 'lib/lifeform/form.rb', line 108 def param_keys = fields.keys |
.param_string_keys ⇒ Array<String>
111 |
# File 'lib/lifeform/form.rb', line 111 def param_string_keys = fields.keys.map(&:to_s) |
.parameters_to_attributes(kwargs) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/lifeform/form.rb', line 80 def parameters_to_attributes(kwargs) attributes = {} kwargs.each do |key, value| case value when Hash value.each do |inner_key, inner_value| attributes[:"#{key}_#{inner_key}"] = process_value(inner_key, inner_value) end else attributes[key] = process_value(key, value) unless value.nil? end end attributes end |
.process_value(key, value) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/lifeform/form.rb', line 64 def process_value(key, value) return value if key == :if case value when TrueClass key.to_s when FalseClass nil when Symbol, Integer value.to_s else value end end |
.subform(name, klass, parent_name: nil) ⇒ Object
55 56 57 |
# File 'lib/lifeform/form.rb', line 55 def subform(name, klass, parent_name: nil) subforms[name.to_sym] = { class: klass, parent_name: parent_name } end |
.subforms ⇒ Object
48 |
# File 'lib/lifeform/form.rb', line 48 def subforms = @subforms ||= {} |
.t ⇒ Object
Helper to point to ‘I18n.t` method
24 |
# File 'lib/lifeform/form.rb', line 24 def t(...) = I18n.t(...) |
Instance Method Details
#add_authenticity_token ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/lifeform/form.rb', line 161 def add_authenticity_token if helpers.respond_to?(:token_tag, true) # Rails helpers.send(:token_tag, nil, form_options: { action: parameters[:action].to_s, method: parameters[:method].to_s.downcase, }) elsif helpers.respond_to?(:csrf_tag, true) # Roda helpers.send(:csrf_tag, parameters[:action].to_s, @method.to_s) else raise Lifeform::Error, "Missing token tag helper. Override `add_authenticity_token' in your Form object" end end |
#attributes ⇒ Object
174 175 176 |
# File 'lib/lifeform/form.rb', line 174 def attributes @attributes ||= self.class.parameters_to_attributes(parameters) end |
#auto_render_fields ⇒ Object
210 |
# File 'lib/lifeform/form.rb', line 210 def auto_render_fields = html_map(self.class.fields) { |k, _v| render(field(k)) } |
#field(name, **field_parameters) ⇒ Object
178 179 180 181 182 183 184 185 186 |
# File 'lib/lifeform/form.rb', line 178 def field(name, **field_parameters) # @type [FieldDefinition] field_definition = self.class.fields[name.to_sym] # @type [Class<Libraries::Default>] field_library = field_definition.library field_library.object_for_field_definition( self, field_definition, self.class.parameters_to_attributes(field_parameters) ) end |
#render(field_object) ⇒ Object
212 213 214 |
# File 'lib/lifeform/form.rb', line 212 def render(field_object) field_object.render_in(helpers || self) end |
#subform(name, model = nil) ⇒ Object
188 189 190 191 192 193 194 |
# File 'lib/lifeform/form.rb', line 188 def subform(name, model = nil) @subform_instances[name.to_sym] ||= self.class.subforms[name.to_sym][:class].new( model, emit_form_tag: false, parent_name: self.class.subforms[name.to_sym][:parent_name] || self.class.name_of_model(self.model) ) end |
#template(&block) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/lifeform/form.rb', line 196 def template(&block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity form_tag = library::FORM_TAG parameters[:action] ||= url || (model ? helpers.send(self.class.const_get(:MODEL_PATH_HELPER), model) : nil) html -> { <<~HTML # rubocop:disable Bridgetown/InsecureHeredoc <#{form_tag} #{html_attributes attributes}> #{add_authenticity_token unless parameters[:method].to_s.casecmp("get").zero?} #{@method_tag&.() || ""} #{block ? capture(self, &block) : auto_render_fields} </#{form_tag}> HTML } end |
#verify_method ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/lifeform/form.rb', line 147 def verify_method return if %w[get post].include?(parameters[:method].to_s.downcase) method_value = @parameters[:method].to_s.downcase @method_tag = -> { <<~HTML <input type="hidden" name="_method" value="#{text -> { method_value }}" autocomplete="off"> HTML } parameters[:method] = :post end |