1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
# require 'bootstrap_form/aliasing'
module BootstrapForm
class FormBuilder < ActionView::Helpers::FormBuilder
attr_reader :layout, :label_col, :control_col, :has_error, :inline_errors,
:label_errors, :acts_like_form_tag
include BootstrapForm::Helpers::Field
include BootstrapForm::Helpers::Bootstrap
include BootstrapForm::FormGroupBuilder
include BootstrapForm::FormGroup
include BootstrapForm::Components
include BootstrapForm::Inputs::Base
include BootstrapForm::Inputs::CheckBox
include BootstrapForm::Inputs::CollectionCheckBoxes
include BootstrapForm::Inputs::CollectionRadioButtons
include BootstrapForm::Inputs::CollectionSelect
include BootstrapForm::Inputs::ColorField
include BootstrapForm::Inputs::DateField
include BootstrapForm::Inputs::DateSelect
include BootstrapForm::Inputs::DatetimeField
include BootstrapForm::Inputs::DatetimeLocalField
include BootstrapForm::Inputs::DatetimeSelect
include BootstrapForm::Inputs::EmailField
include BootstrapForm::Inputs::FileField
include BootstrapForm::Inputs::GroupedCollectionSelect
include BootstrapForm::Inputs::MonthField
include BootstrapForm::Inputs::NumberField
include BootstrapForm::Inputs::PasswordField
include BootstrapForm::Inputs::PhoneField
include BootstrapForm::Inputs::RadioButton
include BootstrapForm::Inputs::RangeField
include BootstrapForm::Inputs::RichTextArea
include BootstrapForm::Inputs::SearchField
include BootstrapForm::Inputs::Select
include BootstrapForm::Inputs::Submit
include BootstrapForm::Inputs::TelephoneField
include BootstrapForm::Inputs::TextArea
include BootstrapForm::Inputs::TextField
include BootstrapForm::Inputs::TimeField
include BootstrapForm::Inputs::TimeSelect
include BootstrapForm::Inputs::TimeZoneSelect
include BootstrapForm::Inputs::UrlField
include BootstrapForm::Inputs::WeekField
include ActionView::Helpers::OutputSafetyHelper
delegate :content_tag, :capture, :concat, :tag, to: :@template
def initialize(object_name, object, template, options)
warn_deprecated_layout_value(options)
@layout = options[:layout] || default_layout
@label_col = options[:label_col] || default_label_col
@control_col = options[:control_col] || default_control_col
@label_errors = options[:label_errors] || false
@inline_errors = options[:inline_errors].nil? ? @label_errors != true : options[:inline_errors] != false
@acts_like_form_tag = options[:acts_like_form_tag]
add_default_form_attributes_and_form_inline options
super
end
def add_default_form_attributes_and_form_inline(options)
options[:html] ||= {}
options[:html].reverse_merge!(BootstrapForm.config.default_form_attributes)
return unless options[:layout] == :inline
options[:html][:class] =
safe_join(([*options[:html][:class]&.split(/\s+/)] + %w[row row-cols-auto g-3 align-items-center])
.compact.uniq, " ")
end
def fields_for_with_bootstrap(record_name, record_object=nil, fields_options={}, &block)
fields_options = fields_for_options(record_object, fields_options)
record_object = nil if record_object.is_a?(Hash) && record_object.extractable_options?
fields_for_without_bootstrap(record_name, record_object, fields_options, &block)
end
bootstrap_alias :fields_for
# the Rails `fields` method passes its options
# to the builder, so there is no need to write a `bootstrap_form` helper
# for the `fields` method.
private
def fields_for_options(record_object, fields_options)
field_options = fields_options
field_options = record_object if record_object.is_a?(Hash) && record_object.extractable_options?
%i[layout control_col inline_errors label_errors].each do |option|
field_options[option] ||= options[option]
end
field_options[:label_col] = field_options[:label_col].present? ? (field_options[:label_col]).to_s : options[:label_col]
field_options
end
def default_layout
# :vertical, :horizontal or :inline
:vertical
end
def default_label_col
"col-sm-2"
end
def offset_col(label_col)
[*label_col].flat_map { |s| s.split(/\s+/) }.grep(/^col-/).join(" ").gsub(/\bcol-(\w+)-(\d)\b/, 'offset-\1-\2')
end
def default_control_col
"col-sm-10"
end
def hide_class
"visually-hidden" # still accessible for screen readers
end
def control_class
"form-control"
end
def feedback_class
"has-feedback"
end
def control_specific_class(method)
"rails-bootstrap-forms-#{method.to_s.tr('_', '-')}"
end
end
end
|