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
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
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/lifeform/form.rb', line 127 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 |
Instance Attribute Details
#emit_form_tag ⇒ Boolean (readonly)
122 123 124 |
# File 'lib/lifeform/form.rb', line 122 def emit_form_tag @emit_form_tag end |
#library ⇒ Class<Libraries::Default> (readonly)
116 117 118 |
# File 'lib/lifeform/form.rb', line 116 def library @library end |
#model ⇒ Object (readonly)
110 111 112 |
# File 'lib/lifeform/form.rb', line 110 def model @model end |
#parameters ⇒ Hash (readonly)
119 120 121 |
# File 'lib/lifeform/form.rb', line 119 def parameters @parameters end |
#parent_name ⇒ Boolean (readonly)
125 126 127 |
# File 'lib/lifeform/form.rb', line 125 def parent_name @parent_name end |
#url ⇒ String (readonly)
113 114 115 |
# File 'lib/lifeform/form.rb', line 113 def url @url end |
Class Method Details
.configuration ⇒ Object
26 |
# File 'lib/lifeform/form.rb', line 26 def configuration = @configuration ||= HashWithDotAccess::Hash.new |
.field(name, type: :text, library: self.library, **parameters) ⇒ Object
45 46 47 48 |
# File 'lib/lifeform/form.rb', line 45 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>
30 31 32 33 34 35 |
# File 'lib/lifeform/form.rb', line 30 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
37 38 39 40 41 |
# File 'lib/lifeform/form.rb', line 37 def initialize_field_definitions! return unless @fields_setup_block @fields_setup_block.(configuration) end |
.library(library_name = nil) ⇒ Object
54 55 56 57 |
# File 'lib/lifeform/form.rb', line 54 def library(library_name = nil) @library = library_name.to_sym if library_name @library ||= :default end |
.name_of_model(model) ⇒ Object
91 92 93 94 95 96 97 98 99 100 |
# File 'lib/lifeform/form.rb', line 91 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>
103 |
# File 'lib/lifeform/form.rb', line 103 def param_keys = fields.keys |
.param_string_keys ⇒ Array<String>
106 |
# File 'lib/lifeform/form.rb', line 106 def param_string_keys = fields.keys.map(&:to_s) |
.parameters_to_attributes(kwargs) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/lifeform/form.rb', line 75 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
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/lifeform/form.rb', line 59 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
50 51 52 |
# File 'lib/lifeform/form.rb', line 50 def subform(name, klass, parent_name: nil) subforms[name.to_sym] = { class: klass, parent_name: parent_name } end |
.subforms ⇒ Object
43 |
# File 'lib/lifeform/form.rb', line 43 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
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/lifeform/form.rb', line 156 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
169 170 171 |
# File 'lib/lifeform/form.rb', line 169 def attributes @attributes ||= self.class.parameters_to_attributes(parameters) end |
#auto_render_fields ⇒ Object
205 |
# File 'lib/lifeform/form.rb', line 205 def auto_render_fields = html_map(self.class.fields) { |k, _v| render(field(k)) } |
#field(name, **field_parameters) ⇒ Object
173 174 175 176 177 178 179 180 181 |
# File 'lib/lifeform/form.rb', line 173 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
207 208 209 |
# File 'lib/lifeform/form.rb', line 207 def render(field_object) field_object.render_in(helpers || self) end |
#subform(name, model = nil) ⇒ Object
183 184 185 186 187 188 189 |
# File 'lib/lifeform/form.rb', line 183 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
191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/lifeform/form.rb', line 191 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/HTMLEscapedHeredoc <#{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
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/lifeform/form.rb', line 142 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 |