Class: Brut::FrontEnd::Form
- Inherits:
-
Object
- Object
- Brut::FrontEnd::Form
- Extended by:
- Brut::FrontEnd::Forms::InputDeclarations
- Defined in:
- lib/brut/front_end/form.rb
Overview
Base class for forms you create to process an HTML form. Generally, your form subclasses will only declare their inputs using methods from Brut::FrontEnd::Forms::InputDeclarations. That said, you will likely create instances of forms as part of the logic for processing them or for testing.
Direct Known Subclasses
Instance Method Summary collapse
-
#constraint_violations(server_side_only: false) ⇒ Hash<String|Array[2]>
Returns a map of any input with a constraint violation and the list of violations.
-
#constraint_violations? ⇒ Boolean
Returns true if this form has constraint violations.
-
#initialize(params: {}) ⇒ Form
constructor
Create an instance of this form, optionally initialized with the given values for its params.
-
#input(input_name, index: nil) ⇒ Brut::FrontEnd::Forms::Input
Access an input with the given name.
-
#inputs(input_name) ⇒ Brut::FrontEnd::Forms::Input
Return all inputs for the given name.
-
#new? ⇒ Boolean
Returns true if this form represents a new, empty, untouched form.
-
#params_empty?(params) ⇒ Boolean
Template method that is used to determine if the params given to the form's initializer represent an empty value.
-
#server_side_constraint_violation(input_name:, key:, index: nil, context: {}) ⇒ Object
Set a server-side constraint violation on a given input's name.
-
#to_h ⇒ Hash<String,nil|String|Array<String>>
Return this form as a hash, which is a map of its parameters' current values.
Methods included from Brut::FrontEnd::Forms::InputDeclarations
inputs_from, radio_button_group, select
Constructor Details
#initialize(params: {}) ⇒ Form
Create an instance of this form, optionally initialized with the given values for its params. Because any values can be posted to a form endpoint, the initializer does not use kewyord arguments. Instead, it's initialize with whatever parameters were received. This intializer will then set only those values defined.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/brut/front_end/form.rb', line 32 def initialize(params: {}) params = convert_to_string_or_nil(params.to_h) unknown_params = params.keys.map(&:to_s).reject { |key| self.class.input_definitions.key?(key) } if unknown_params.any? Brut.container.instrumentation.add_attributes(prefix: :brut, ignored_unknown_params: unknown_params.join(",")) end @params = params.except(*unknown_params).map { |name,value| input_definition = begin self.class.input_definitions[name] || self.class.input_definitions.fetch(name.to_s) rescue KeyError raise "cannot find input definition for '#{name}'. Have these: #{self.class.input_definitions.keys.inspect}" end if value.kind_of?(Array) input_definition = begin self.class.input_definitions[name] || self.class.input_definitions.fetch(name.to_s) rescue KeyError raise "cannot find input definition for '#{name}'. Have these: #{self.class.input_definitions.keys.inspect}" end if input_definition.respond_to?(:type) && input_definition.type == "checkbox" if value.all? { it.to_s =~ /^\d+$/ } # the values represent the indexes of which checkboxes were checked new_values = [] value.each do |index_as_string| index = Integer(index_as_string) new_values[index] = true end value = new_values.map { !!it } end end end [ name, value ] }.to_h @new = params_empty?(@params) @inputs = self.class.input_definitions.map { |name,input_definition| value = @params[name] || @params[name.to_sym] inputs = if value.kind_of?(Array) value.map.with_index { |one_value, index| input_definition.make_input(value: one_value, index:) } else [ input_definition.make_input(value:, index: nil) ] end [ name, inputs ] }.to_h end |
Instance Method Details
#constraint_violations(server_side_only: false) ⇒ Hash<String|Array[2]>
Returns a map of any input with a constraint violation and the list of violations. The keys in the hash are input names and the values are arrays of Brut::FrontEnd::Forms::ValidityState instances.
array is the validity state for the input, which is a Brut::FrontEnd::Forms::ValidityState instance. The second element is the index of the input in the array. This index is used when you have more than one field with the same name.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/brut/front_end/form.rb', line 148 def constraint_violations(server_side_only: false) @inputs.map { |input_name, inputs| inputs.map.with_index { |input,index| if input.valid? nil else [ input_name, [ input.validity_state.select { |constraint| if server_side_only !constraint.client_side? else true end }, index ] ] end }.compact }.select { !it.empty? }.flatten(1).to_h end |
#constraint_violations? ⇒ Boolean
Returns true if this form has constraint violations.
117 |
# File 'lib/brut/front_end/form.rb', line 117 def constraint_violations? = !@inputs.values.flatten.all?(&:valid?) |
#input(input_name, index: nil) ⇒ Brut::FrontEnd::Forms::Input
Access an input with the given name
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/brut/front_end/form.rb', line 95 def input(input_name, index: nil) index ||= 0 inputs = self.inputs(input_name) input = inputs[index] if input.nil? input_definition = self.class.input_definitions.fetch(input_name.to_s) input = input_definition.make_input(value:"", index:) inputs[index] = input end input end |
#inputs(input_name) ⇒ Brut::FrontEnd::Forms::Input
Return all inputs for the given name.
110 111 112 113 114 |
# File 'lib/brut/front_end/form.rb', line 110 def inputs(input_name) @inputs.fetch(input_name.to_s) rescue KeyError => ex raise Brut::Framework::Errors::Bug, "Form does not define the input '#{input_name}'. You must add this to your form. Found these inputs: #{@inputs.keys.join(', ')}" end |
#new? ⇒ Boolean
Returns true if this form represents a new, empty, untouched form. This is useful for determining if this form has never been submitted and thus any required values don't represent an intentional omission by the user. Generally, don't override this. Instead, override #params_empty?.
88 |
# File 'lib/brut/front_end/form.rb', line 88 def new? = @new |
#params_empty?(params) ⇒ Boolean
Template method that is used to determine if the params given to the form's initializer represent an empty value. By default, this returns true if those params were nil or empty. You'd override this if there are values you want to initialize a form with that aren't considered values provided by the user. This can allow a form with values in it to be considered un-submitted.
176 |
# File 'lib/brut/front_end/form.rb', line 176 def params_empty?(params) = params.nil? || params.empty? |
#server_side_constraint_violation(input_name:, key:, index: nil, context: {}) ⇒ Object
Set a server-side constraint violation on a given input's name.
to form the entire key.
125 126 127 128 |
# File 'lib/brut/front_end/form.rb', line 125 def server_side_constraint_violation(input_name:, key:, index: nil, context:{}) index ||= 0 self.input(input_name, index:).server_side_constraint_violation(key,context) end |
#to_h ⇒ Hash<String,nil|String|Array<String>>
Return this form as a hash, which is a map of its parameters' current values. This is not simply
a filtered version of what was passed into the initializer. This will only have the keys for the inputs
this form defines. Those keys will be strings, not symbols. The values will be
either nil
, a String, or an array of strings. Not every input defined by this form
will be represented as a key in the resulting hash—only those keys that were passed to the initializer.
184 185 186 187 188 |
# File 'lib/brut/front_end/form.rb', line 184 def to_h @params.map { |key,value| [ key.to_s, value ] }.to_h end |