Class: DryCrud::Form::Builder
- Inherits:
-
ActionView::Helpers::FormBuilder
- Object
- ActionView::Helpers::FormBuilder
- DryCrud::Form::Builder
- Defined in:
- app/helpers/dry_crud/form/builder.rb
Overview
A form builder that automatically selects the corresponding input field for ActiveRecord column types. Convenience methods for each column type allow one to customize the different fields.
All field methods may be prefixed with labeled_
in order to render a standard label, required mark and an optional help block with them.
Use #labeled_input_field or #input_field to render a input field corresponding to the given attribute.
See the Control class for how to customize the html rendered for a single input field.
Instance Attribute Summary collapse
-
#template ⇒ Object
readonly
Returns the value of attribute template.
Instance Method Summary collapse
-
#belongs_to_field(attr, **html_options) ⇒ Object
Render a select element for a :belongs_to association defined by attr.
-
#boolean_field(attr, **html_options) ⇒ Object
Render a boolean field.
-
#cancel_link(url = nil) ⇒ Object
Render a cancel link pointing to the given url.
- #decimal_field(attr, **html_options) ⇒ Object
-
#error_messages ⇒ Object
Render the error messages for the current form.
- #float_field(attr, **html_options) ⇒ Object
-
#has_many_field(attr, **html_options) ⇒ Object
Render a multi select element for a :has_many or :has_and_belongs_to_many association defined by attr.
-
#help_block(text) ⇒ Object
Generates a help block for fields.
-
#input_field(attr, **html_options) ⇒ Object
Render a corresponding input control for the given attribute.
- #integer_field(attr, **html_options) ⇒ Object
-
#labeled(attr, content = {}, options = {}, &block) ⇒ Object
Render a label for the given attribute with the passed content.
-
#labeled_input_field(attr, **html_options) ⇒ Object
Render a corresponding input control and label for the given attribute.
-
#labeled_input_fields(*attrs, **options) ⇒ Object
Render multiple input controls together with a label for the given attributes.
-
#method_missing(name, *args) ⇒ Object
Dispatch methods starting with ‘labeled_’ to render a label and the corresponding input field.
-
#required?(attr) ⇒ Boolean
Returns true if the given attribute must be present.
-
#respond_to_missing?(name, include_private = false) ⇒ Boolean
Overriden to fullfill contract with method_missing ‘labeled_’ methods.
-
#select_options(attr, **options) ⇒ Object
Depending if the given attribute must be present, return only an initial selection prompt or a blank option, respectively.
-
#standard_actions(submit_label = ti('button.save'), cancel_url = nil) ⇒ Object
Render a submit button and a cancel link for this form.
-
#static_text(text) ⇒ Object
Renders a static text where otherwise form inputs appear.
-
#string_field(attr, **html_options) ⇒ Object
Render a standard string field with column contraints.
-
#submit_button(label = ti('button.save')) ⇒ Object
Render a standard submit button with the given label.
-
#text_area(attr, **html_options) ⇒ Object
Customize the standard text area to have 5 rows by default.
-
#with_addon(content, addon) ⇒ Object
Renders the given content with an addon.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Dispatch methods starting with ‘labeled_’ to render a label and the corresponding input field. E.g. labeled_boolean_field(:checked, class: ‘bold’) To add an additional help text, use the help option. E.g. labeled_boolean_field(:checked, help: ‘Some Help’)
249 250 251 252 253 254 255 256 |
# File 'app/helpers/dry_crud/form/builder.rb', line 249 def method_missing(name, *args) field_method = labeled_field_method?(name) if field_method build_labeled_field(field_method, *args) else super end end |
Instance Attribute Details
#template ⇒ Object (readonly)
Returns the value of attribute template.
21 22 23 |
# File 'app/helpers/dry_crud/form/builder.rb', line 21 def template @template end |
Instance Method Details
#belongs_to_field(attr, **html_options) ⇒ Object
Render a select element for a :belongs_to association defined by attr. Use additional html_options for the select element. To pass a custom element list, specify the list with the :list key or define an instance variable with the pluralized name of the association.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'app/helpers/dry_crud/form/builder.rb', line 118 def belongs_to_field(attr, **) list = association_entries(attr, **).to_a if list.present? add_css_class(, 'form-control') collection_select(attr, list, :id, :to_s, (attr, **), **) else # rubocop:disable Rails/OutputSafety none = ta(:none_available, association(@object, attr)).html_safe # rubocop:enable Rails/OutputSafety static_text(none) end end |
#boolean_field(attr, **html_options) ⇒ Object
Render a boolean field.
72 73 74 75 76 77 78 79 |
# File 'app/helpers/dry_crud/form/builder.rb', line 72 def boolean_field(attr, **) tag.div(class: 'checkbox') do tag.label do detail = .delete(:detail) || ' '.html_safe safe_join([check_box(attr, ), ' ', detail]) end end end |
#cancel_link(url = nil) ⇒ Object
Render a cancel link pointing to the given url.
189 190 191 192 |
# File 'app/helpers/dry_crud/form/builder.rb', line 189 def cancel_link(url = nil) url ||= cancel_url link_to(ti('button.cancel'), url, class: 'cancel') end |
#decimal_field(attr, **html_options) ⇒ Object
100 101 102 103 104 |
# File 'app/helpers/dry_crud/form/builder.rb', line 100 def decimal_field(attr, **) [:step] ||= (10**-column_property(object, attr, :scale)).to_f number_field(attr, **) end |
#error_messages ⇒ Object
Render the error messages for the current form.
151 152 153 154 155 |
# File 'app/helpers/dry_crud/form/builder.rb', line 151 def @template.render('shared/error_messages', errors: @object.errors, object: @object) end |
#float_field(attr, **html_options) ⇒ Object
95 96 97 98 |
# File 'app/helpers/dry_crud/form/builder.rb', line 95 def float_field(attr, **) [:step] ||= 'any' number_field(attr, **) end |
#has_many_field(attr, **html_options) ⇒ Object
Render a multi select element for a :has_many or :has_and_belongs_to_many association defined by attr. Use additional html_options for the select element. To pass a custom element list, specify the list with the :list key or define an instance variable with the pluralized name of the association.
141 142 143 144 145 |
# File 'app/helpers/dry_crud/form/builder.rb', line 141 def has_many_field(attr, **) [:multiple] = true add_css_class(, 'multiselect') belongs_to_field(attr, **) end |
#help_block(text) ⇒ Object
Generates a help block for fields
170 171 172 |
# File 'app/helpers/dry_crud/form/builder.rb', line 170 def help_block(text) tag.p(text, class: 'help-block') end |
#input_field(attr, **html_options) ⇒ Object
Render a corresponding input control for the given attribute. The input field is chosen based on the ActiveRecord column type.
The following options may be passed:
-
:addon
- Addon content displayd just after the input field. -
:help
- A help text displayd below the input field. -
:span
- Number of columns the input field should span. -
:field_method
- Different method to create the input field.
Use additional html_options for the input element.
61 62 63 |
# File 'app/helpers/dry_crud/form/builder.rb', line 61 def input_field(attr, **) control_class.new(self, attr, **).render_content end |
#integer_field(attr, **html_options) ⇒ Object
90 91 92 93 |
# File 'app/helpers/dry_crud/form/builder.rb', line 90 def integer_field(attr, **) [:step] ||= 1 number_field(attr, **) end |
#labeled(attr, content = {}, options = {}, &block) ⇒ Object
Render a label for the given attribute with the passed content. The content may be given as an argument or as a block:
labeled(:attr) { #content }
labeled(:attr, content)
The following options may be passed:
-
:span
- Number of columns the content should span. -
:caption
- Different caption for the label.
235 236 237 238 239 240 241 242 |
# File 'app/helpers/dry_crud/form/builder.rb', line 235 def labeled(attr, content = {}, = {}, &block) if block_given? = content content = capture(&block) end control = control_class.new(self, attr, **) control.render_labeled(content) end |
#labeled_input_field(attr, **html_options) ⇒ Object
Render a corresponding input control and label for the given attribute. The input field is chosen based on the ActiveRecord column type.
The following options may be passed:
-
:addon
- Addon content displayd just after the input field. -
:help
- A help text displayd below the input field. -
:span
- Number of columns the input field should span. -
:caption
- Different caption for the label. -
:field_method
- Different method to create the input field.
Use additional html_options for the input element.
47 48 49 |
# File 'app/helpers/dry_crud/form/builder.rb', line 47 def labeled_input_field(attr, **) control_class.new(self, attr, **).render_labeled end |
#labeled_input_fields(*attrs, **options) ⇒ Object
Render multiple input controls together with a label for the given attributes.
32 33 34 |
# File 'app/helpers/dry_crud/form/builder.rb', line 32 def labeled_input_fields(*attrs, **) safe_join(attrs) { |a| labeled_input_field(a, **.dup) } end |
#required?(attr) ⇒ Boolean
Returns true if the given attribute must be present.
216 217 218 219 220 221 222 223 224 225 |
# File 'app/helpers/dry_crud/form/builder.rb', line 216 def required?(attr) attr, attr_id = assoc_and_id_attr(attr) validators = @object.class.validators_on(attr) + @object.class.validators_on(attr_id) validators.any? do |v| v.kind == :presence && !v..key?(:if) && !v..key?(:unless) end end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
Overriden to fullfill contract with method_missing ‘labeled_’ methods.
259 260 261 |
# File 'app/helpers/dry_crud/form/builder.rb', line 259 def respond_to_missing?(name, include_private = false) labeled_field_method?(name).present? || super end |
#select_options(attr, **options) ⇒ Object
Depending if the given attribute must be present, return only an initial selection prompt or a blank option, respectively.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'app/helpers/dry_crud/form/builder.rb', line 196 def (attr, **) prompt = .delete(:prompt) blank = .delete(:include_blank) if [:multiple] {} elsif prompt { prompt: prompt } elsif blank { include_blank: blank } else assoc = association(@object, attr) if required?(attr) { prompt: ta(:please_select, assoc) } else { include_blank: ta(:no_entry, assoc) } end end end |
#standard_actions(submit_label = ti('button.save'), cancel_url = nil) ⇒ Object
Render a submit button and a cancel link for this form.
175 176 177 178 179 180 181 |
# File 'app/helpers/dry_crud/form/builder.rb', line 175 def standard_actions(submit_label = ti('button.save'), cancel_url = nil) tag.div(class: 'col-md-offset-2 col-md-8') do safe_join([(submit_label), cancel_link(cancel_url)], ' ') end end |
#static_text(text) ⇒ Object
Renders a static text where otherwise form inputs appear.
165 166 167 |
# File 'app/helpers/dry_crud/form/builder.rb', line 165 def static_text(text) tag.p(text, class: 'form-control-static') end |
#string_field(attr, **html_options) ⇒ Object
Render a standard string field with column contraints.
66 67 68 69 |
# File 'app/helpers/dry_crud/form/builder.rb', line 66 def string_field(attr, **) [:maxlength] ||= column_property(@object, attr, :limit) text_field(attr, **) end |
#submit_button(label = ti('button.save')) ⇒ Object
Render a standard submit button with the given label.
184 185 186 |
# File 'app/helpers/dry_crud/form/builder.rb', line 184 def (label = ti('button.save')) (label, class: 'btn btn-primary', data: { disable_with: label }) end |
#text_area(attr, **html_options) ⇒ Object
Customize the standard text area to have 5 rows by default.
107 108 109 110 111 |
# File 'app/helpers/dry_crud/form/builder.rb', line 107 def text_area(attr, **) add_css_class(, 'form-control') [:rows] ||= 5 super(attr, **) end |
#with_addon(content, addon) ⇒ Object
Renders the given content with an addon.
158 159 160 161 162 |
# File 'app/helpers/dry_crud/form/builder.rb', line 158 def with_addon(content, addon) tag.div(class: 'input-group') do content + tag.span(addon, class: 'input-group-text') end end |