rails_bootstrap_form 0.4.2 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5874a38745d73c1b0bb05c751711cdc380be8684c71187069e07224e9d40333a
4
- data.tar.gz: ffe2043c13700e6015d7741b51550c52642098c412f29b1921a7e98ed20ec9cf
3
+ metadata.gz: 75f1c7df21987622c3341031991186ceff26dc21f48c301ee2017fb47dd1074a
4
+ data.tar.gz: e84fbf45f5bcff4bfad1904253c5e549fa616ebc9d646b762facb78cca121ce7
5
5
  SHA512:
6
- metadata.gz: 657b116576955954f11ecd923cd61277613bd732d7b986effe3d5b908ed38531549413baa47436167fd7d675fb5aab709863cc53bfb19f99d4a39abb2148de63
7
- data.tar.gz: '09d24eb35c72a56c834d0031ce85152e1a0241a1d4614dc69ebb5bc820b45780380d80132a9c882086b6524d8bb9fd5826d41c339f45bd87b335fcb0ceb97eeb'
6
+ metadata.gz: ee6cf0a877cff1e96ccc3e95495c331f41c5af536a23332b58669a10f6c6db6c3f1dc9f5fd3cd2fc2e51c0040380e18a7477231f4b108d306593dfc1f6844fa7
7
+ data.tar.gz: 39f8e46ae208727fd81127cb3c8de3f32878c16b957ff21fc882f6a250e7972bd00f573dd4dd6a958140d7564e57a4e70e1a86eb30c484e73b3ab42ece3a2bb5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_bootstrap_form (0.4.2)
4
+ rails_bootstrap_form (0.5.1)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  label.is-invalid, .invalid-feedback {
2
- color: var(--bs-danger);
2
+ color: var(--bs-form-invalid-color);
3
3
  }
4
4
  label.required::after {
5
- color: var(--bs-danger);
5
+ color: var(--bs-form-invalid-color);
6
6
  content: "*";
7
7
  padding-left: .25rem;
8
8
  top: -2px;
@@ -3,6 +3,8 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  class Address < ApplicationRecord
6
+ validates :street, :city, :country_id, presence: true
7
+
6
8
  belongs_to :user
7
9
  belongs_to :country
8
10
 
@@ -4,7 +4,15 @@
4
4
 
5
5
  class User < ApplicationRecord
6
6
  validates :name, presence: true, length: {in: 2..50}
7
- validates :email, presence: true
7
+ validates :terms, acceptance: true
8
+ validates :email,
9
+ :password,
10
+ :mobile_number,
11
+ :birth_date,
12
+ :favorite_color,
13
+ :fruit_id,
14
+ :skill_ids,
15
+ presence: true
8
16
 
9
17
  has_one :address, dependent: :destroy
10
18
 
@@ -9,19 +9,16 @@
9
9
  <%= form.text_field :password, autocomplete: "new-password" %>
10
10
  <%= form.phone_field :mobile_number %>
11
11
  <%= form.date_field :birth_date %>
12
- <%= form.check_box :terms %>
12
+ <%= form.check_box :terms, bootstrap_form: {switch: false}, required: true %>
13
13
  <%= form.range_field :excellence %>
14
14
  <%= form.url_field :blog_url %>
15
+ <%= form.collection_radio_buttons :fruit_id, ::Fruit.all, :id, :name, {bootstrap_form: {layout: :inline}, checked: form.object.fruit_id} %>
15
16
  <%= form.color_field :favorite_color %>
16
- <%= form.select :fruit_id, options_for_select(::Fruit.pluck(:name, :id), form.object.fruit_id),
17
- {include_blank: "Select Favorite Fruit"} %>
18
- <%= form.collection_check_boxes :skill_ids, ::Skill.all, :id, :name do |b| %>
19
- <%= b.check_box + b.text %>
20
- <% end %>
17
+ <%= form.collection_check_boxes :skill_ids, ::Skill.all, :id, :name, {bootstrap_form: {layout: :inline}} %>
21
18
  <%= form.fields_for :address, include_id: false do |address_form| %>
22
19
  <%= address_form.text_area :street %>
23
20
  <%= address_form.text_field :state %>
24
- <%= address_form.grouped_collection_select :city, ::Country.all, :cities, :name, :id, :name %>
21
+ <%= address_form.grouped_collection_select :city, ::Country.all, :cities, :name, :id, :name, {include_blank: "Select city"} %>
25
22
  <%= address_form.text_field :postal_code %>
26
23
  <%= address_form.select :country_id, options_for_select(::Country.pluck(:name, :id), address_form.object.country_id),
27
24
  {include_blank: "Select Country", bootstrap_form: {}} %>
@@ -42,7 +42,10 @@
42
42
  },
43
43
  help_texts: {
44
44
  user: {
45
- email: "Please use official email address"
45
+ email: "Please use official email address",
46
+ terms: "You must first accept terms and conditions in order to continue",
47
+ skill_ids: "Select your strong skills",
48
+ fruit_id: "Select your favorite fruit"
46
49
  }
47
50
  },
48
51
  }
@@ -25,10 +25,6 @@ module RailsBootstrapForm
25
25
  options[:html].reverse_merge!(RailsBootstrapForm.config.default_form_attributes)
26
26
  end
27
27
 
28
- def control_specific_class(field_tag_name)
29
- "rails-bootstrap-forms-#{field_tag_name.to_s.tr("_", "-")}"
30
- end
31
-
32
- private :apply_default_form_options, :control_specific_class
28
+ private :apply_default_form_options
33
29
  end
34
30
  end
@@ -86,6 +86,10 @@ module RailsBootstrapForm
86
86
  # Default is `form-control-plaintext`.
87
87
  attr_accessor :static_field_class
88
88
 
89
+ # Option to control whether the check box should look like bootstrap switches.
90
+ # Default is `false`.
91
+ attr_accessor :switch
92
+
89
93
  def initialize(options = {})
90
94
  set_defaults
91
95
  set_bootstrap_form_options(options)
@@ -146,6 +150,8 @@ module RailsBootstrapForm
146
150
  @floating = false
147
151
 
148
152
  @static_field_class = "form-control-plaintext"
153
+
154
+ @switch = false
149
155
  end
150
156
 
151
157
  private :set_defaults
@@ -0,0 +1,66 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ module RailsBootstrapForm
6
+ module Components
7
+ module CheckBox
8
+ extend ActiveSupport::Concern
9
+
10
+ def self.included(base_class)
11
+ def check_box_label(attribute, checked_value, options, bootstrap_options, &block)
12
+ unless bootstrap_options.skip_label
13
+ label_options = {
14
+ class: check_box_label_class(attribute, bootstrap_options, options)
15
+ }
16
+ label_options[:for] = options[:id] if options[:id].present?
17
+
18
+ label_name = if options[:multiple]
19
+ check_box_value(attribute, checked_value)
20
+ else
21
+ attribute
22
+ end
23
+
24
+ label_text = check_box_label_text(attribute, options, bootstrap_options, &block)
25
+
26
+ label(label_name, label_text, label_options)
27
+ end
28
+ end
29
+
30
+ def check_box_label_text(attribute, options, bootstrap_options, &block)
31
+ block ? capture(&block) : label_text(attribute, bootstrap_options)
32
+ end
33
+
34
+ def check_box_value(attribute, value)
35
+ # label's `for` attribute needs to match checkbox tag's id,
36
+ # IE sanitized value, IE
37
+ # https://github.com/rails/rails/blob/5-0-stable/actionview/lib/action_view/helpers/tags/base.rb#L123-L125
38
+ "#{attribute}_#{value.to_s.gsub(/\s/, "_").gsub(/[^-[[:word:]]]/, "").mb_chars.downcase}"
39
+ end
40
+
41
+ def check_box_classes(attribute, options)
42
+ classes = Array(options[:class]) << "form-check-input"
43
+ classes << "is-invalid" if is_invalid?(attribute)
44
+ classes.flatten.compact
45
+ end
46
+
47
+ def check_box_label_class(attribute, bootstrap_options, options)
48
+ classes = Array("form-check-label") << bootstrap_options.additional_label_class
49
+ classes << "required" if is_field_required?(attribute, options) && !bootstrap_options.inline?
50
+ classes << "is-invalid" if is_invalid?(attribute)
51
+ classes << bootstrap_options.hide_class if bootstrap_options.hide_label
52
+ classes.flatten.compact
53
+ end
54
+
55
+ def check_box_wrapper_class(bootstrap_options)
56
+ classes = Array("form-check")
57
+ classes << "form-switch" if bootstrap_options.switch
58
+ classes << "form-check-inline" if bootstrap_options.inline?
59
+ classes.flatten.compact
60
+ end
61
+
62
+ private :check_box_label, :check_box_classes, :check_box_label_class, :check_box_wrapper_class
63
+ end
64
+ end
65
+ end
66
+ end
@@ -13,7 +13,7 @@ module RailsBootstrapForm
13
13
 
14
14
  help_text = (bootstrap_options.help_text || scoped_help_text(attribute))
15
15
 
16
- tag.span(help_text, class: "form-text text-muted") if help_text.present?
16
+ tag.div(help_text, class: "form-text text-muted") if help_text.present?
17
17
  end
18
18
 
19
19
  def object_class
@@ -8,12 +8,12 @@ module RailsBootstrapForm
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  def self.included(base_class)
11
- def label(attribute, bootstrap_options)
11
+ def draw_label(attribute, bootstrap_options)
12
12
  unless bootstrap_options.skip_label
13
13
  label_class = label_classes(attribute, bootstrap_options)
14
14
  label_text = label_text(attribute, bootstrap_options)
15
15
 
16
- super(attribute, label_text, class: label_class)
16
+ label(attribute, label_text, class: label_class)
17
17
  end
18
18
  end
19
19
 
@@ -29,7 +29,7 @@ module RailsBootstrapForm
29
29
  bootstrap_options.label_text || object&.class.try(:human_attribute_name, attribute)
30
30
  end
31
31
 
32
- private :label, :label_classes, :label_text
32
+ private :draw_label, :label_classes, :label_text
33
33
  end
34
34
  end
35
35
  end
@@ -0,0 +1,62 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ module RailsBootstrapForm
6
+ module Components
7
+ module RadioButton
8
+ extend ActiveSupport::Concern
9
+
10
+ def self.included(base_class)
11
+ def radio_button_label(attribute, value, options, bootstrap_options)
12
+ unless bootstrap_options.skip_label
13
+ label_options = {
14
+ value: value,
15
+ class: radio_button_label_class(attribute, bootstrap_options, options)
16
+ }
17
+ label_options[:for] = options[:id] if options[:id].present?
18
+
19
+ label_name = if options[:multiple]
20
+ radio_button_value(attribute, checked_value)
21
+ else
22
+ attribute
23
+ end
24
+
25
+ label_text = label_text(attribute, bootstrap_options)
26
+
27
+ label(label_name, label_text, label_options)
28
+ end
29
+ end
30
+
31
+ def radio_button_value(attribute, value)
32
+ # label's `for` attribute needs to match checkbox tag's id,
33
+ # IE sanitized value, IE
34
+ # https://github.com/rails/rails/blob/5-0-stable/actionview/lib/action_view/helpers/tags/base.rb#L123-L125
35
+ "#{attribute}_#{value.to_s.gsub(/\s/, "_").gsub(/[^-[[:word:]]]/, "").mb_chars.downcase}"
36
+ end
37
+
38
+ def radio_button_classes(attribute, options)
39
+ classes = Array(options[:class]) << "form-check-input"
40
+ classes << "is-invalid" if is_invalid?(attribute)
41
+ classes.flatten.compact
42
+ end
43
+
44
+ def radio_button_label_class(attribute, bootstrap_options, options)
45
+ classes = Array("form-check-label") << bootstrap_options.additional_label_class
46
+ classes << "required" if is_field_required?(attribute, options) && !bootstrap_options.inline?
47
+ classes << "is-invalid" if is_invalid?(attribute)
48
+ classes << bootstrap_options.hide_class if bootstrap_options.hide_label
49
+ classes.flatten.compact
50
+ end
51
+
52
+ def radio_button_wrapper_class(bootstrap_options)
53
+ classes = Array("form-check")
54
+ classes << "form-check-inline" if bootstrap_options.inline?
55
+ classes.flatten.compact
56
+ end
57
+
58
+ private :radio_button_label, :radio_button_classes, :radio_button_label_class, :radio_button_wrapper_class
59
+ end
60
+ end
61
+ end
62
+ end
@@ -10,10 +10,14 @@ module RailsBootstrapForm
10
10
  autoload :Labels
11
11
  autoload :RequiredField
12
12
  autoload :Errors
13
+ autoload :CheckBox
14
+ autoload :RadioButton
13
15
 
14
16
  include HelpText
15
17
  include Labels
16
18
  include RequiredField
17
19
  include Errors
20
+ include CheckBox
21
+ include RadioButton
18
22
  end
19
23
  end
@@ -13,7 +13,7 @@ module RailsBootstrapForm
13
13
  end
14
14
 
15
15
  def field_wrapper(attribute, bootstrap_options, options, &block)
16
- label = label(attribute, bootstrap_options)
16
+ label = draw_label(attribute, bootstrap_options)
17
17
  help_text = help_text(attribute, bootstrap_options)
18
18
 
19
19
  if bootstrap_options.floating
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ module RailsBootstrapForm
6
+ module Inputs
7
+ module Base
8
+ extend ActiveSupport::Concern
9
+
10
+ def self.included(base_class)
11
+ def collection_input_checked?(checked, obj, input_value)
12
+ checked == input_value || Array(checked).try(:include?, input_value) ||
13
+ checked == obj || Array(checked).try(:include?, obj)
14
+ end
15
+
16
+ def control_specific_class(field_tag_name)
17
+ "rails-bootstrap-forms-#{field_tag_name.to_s.tr("_", "-")}"
18
+ end
19
+
20
+ private :collection_input_checked?, :control_specific_class
21
+ end
22
+ end
23
+ end
24
+ end
@@ -5,6 +5,12 @@
5
5
  module RailsBootstrapForm
6
6
  module Inputs
7
7
 
8
+ extend ActiveSupport::Autoload
9
+
10
+ autoload :Base
11
+
12
+ include Base
13
+
8
14
  FIELD_HELPERS = %i[
9
15
  text_field
10
16
  url_field
@@ -120,5 +126,97 @@ module RailsBootstrapForm
120
126
 
121
127
  text_field(attribute, static_options)
122
128
  end
129
+
130
+ def check_box(attribute, options = {}, checked_value = "1", unchecked_value = "0", &block)
131
+ bootstrap_options = bootstrap_form_options.scoped(options.delete(:bootstrap_form))
132
+
133
+ options[:class] = check_box_classes(attribute, options)
134
+
135
+ check_box_field = super(attribute, options, checked_value, unchecked_value)
136
+ check_box_help_text = help_text(attribute, bootstrap_options)
137
+
138
+ check_box_label = check_box_label(attribute, checked_value, options, bootstrap_options, &block)
139
+
140
+ check_box_html = tag.div(class: check_box_wrapper_class(bootstrap_options)) do
141
+ concat(check_box_field)
142
+ concat(check_box_label)
143
+ concat(check_box_help_text) unless bootstrap_options.inline?
144
+ concat(generate_error(attribute)) if is_invalid?(attribute) && !bootstrap_options.inline?
145
+ end
146
+
147
+ check_box_html
148
+ end
149
+
150
+ def radio_button(attribute, value, options = {})
151
+ bootstrap_options = bootstrap_form_options.scoped(options.delete(:bootstrap_form))
152
+
153
+ options[:class] = radio_button_classes(attribute, options)
154
+
155
+ radio_button_field = super(attribute, value, options)
156
+ radio_button_help_text = help_text(attribute, bootstrap_options)
157
+
158
+ radio_button_label = radio_button_label(attribute, value, options, bootstrap_options)
159
+
160
+ radio_button_html = tag.div(class: radio_button_wrapper_class(bootstrap_options)) do
161
+ concat(radio_button_field)
162
+ concat(radio_button_label)
163
+ concat(radio_button_help_text) unless bootstrap_options.inline?
164
+ concat(generate_error(attribute)) if is_invalid?(attribute) && !bootstrap_options.inline?
165
+ end
166
+
167
+ radio_button_html
168
+ end
169
+
170
+ def collection_check_boxes(attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
171
+ options[:multiple] = true
172
+
173
+ inputs = ActiveSupport::SafeBuffer.new
174
+
175
+ collection.each do |object|
176
+ input_value = value_method.respond_to?(:call) ? value_method.call(object) : object.send(value_method)
177
+ input_options = {
178
+ bootstrap_form: {
179
+ label_text: text_method.respond_to?(:call) ? text_method.call(object) : object.send(text_method)
180
+ }
181
+ }.deep_merge!(options)
182
+
183
+ inputs << check_box(attribute, input_options, input_value, nil)
184
+ end
185
+
186
+ if options.delete(:include_hidden) { true }
187
+ inputs.prepend hidden_field(attribute, value: "", multiple: true)
188
+ end
189
+
190
+ field_wrapper_builder(attribute, options, html_options) do
191
+ concat(tag.div(class: control_specific_class(:collection_check_boxes)) do
192
+ concat(inputs)
193
+ end)
194
+ end
195
+ end
196
+
197
+ def collection_radio_buttons(attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
198
+ inputs = ActiveSupport::SafeBuffer.new
199
+
200
+ collection.each do |object|
201
+ input_value = value_method.respond_to?(:call) ? value_method.call(object) : object.send(value_method)
202
+ input_options = {
203
+ bootstrap_form: {
204
+ label_text: text_method.respond_to?(:call) ? text_method.call(object) : object.send(text_method)
205
+ }
206
+ }.deep_merge!(options)
207
+
208
+ if (checked = input_options[:checked])
209
+ input_options[:checked] = collection_input_checked?(checked, object, object.send(value_method))
210
+ end
211
+
212
+ inputs << radio_button(attribute, input_value, input_options)
213
+ end
214
+
215
+ field_wrapper_builder(attribute, options, html_options) do
216
+ concat(tag.div(class: control_specific_class(:collection_radio_buttons)) do
217
+ concat(inputs)
218
+ end)
219
+ end
220
+ end
123
221
  end
124
222
  end
@@ -3,6 +3,6 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  module RailsBootstrapForm
6
- VERSION = "0.4.2".freeze
6
+ VERSION = "0.5.1".freeze
7
7
  REQUIRED_RAILS_VERSION = "~> 7.0".freeze
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_bootstrap_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harshal LADHE (shivam091)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-16 00:00:00.000000000 Z
11
+ date: 2023-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: generator_spec
@@ -111,15 +111,18 @@ files:
111
111
  - lib/rails_bootstrap_form/bootstrap_form_builder.rb
112
112
  - lib/rails_bootstrap_form/bootstrap_form_options.rb
113
113
  - lib/rails_bootstrap_form/components.rb
114
+ - lib/rails_bootstrap_form/components/check_box.rb
114
115
  - lib/rails_bootstrap_form/components/errors.rb
115
116
  - lib/rails_bootstrap_form/components/help_text.rb
116
117
  - lib/rails_bootstrap_form/components/labels.rb
118
+ - lib/rails_bootstrap_form/components/radio_button.rb
117
119
  - lib/rails_bootstrap_form/components/required_field.rb
118
120
  - lib/rails_bootstrap_form/configuration.rb
119
121
  - lib/rails_bootstrap_form/engine.rb
120
122
  - lib/rails_bootstrap_form/field_wrapper_builder.rb
121
123
  - lib/rails_bootstrap_form/input_group_builder.rb
122
124
  - lib/rails_bootstrap_form/inputs.rb
125
+ - lib/rails_bootstrap_form/inputs/base.rb
123
126
  - lib/rails_bootstrap_form/version.rb
124
127
  - sig/rails_bootstrap_form.rbs
125
128
  homepage: https://github.com/shivam091/rails_bootstrap_form