Skip to content

Commit

Permalink
Merge pull request #5 from shivam091/0.2.3
Browse files Browse the repository at this point in the history
0.2.3
  • Loading branch information
shivam091 committed May 15, 2023
2 parents ce87ada + 1da0c03 commit 38fd5b6
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
11 changes: 10 additions & 1 deletion app/assets/stylesheets/rails_bootstrap_form.css
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@

label.is-invalid, .invalid-feedback {
color: var(--bs-danger);
}
label.required::after {
color: var(--bs-danger);
content: "*";
padding-left: .25rem;
top: -2px;
font-weight: bolder;
}
2 changes: 2 additions & 0 deletions lib/rails_bootstrap_form/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ module Components

autoload :HelpText
autoload :Labels
autoload :RequiredField

include HelpText
include Labels
include RequiredField
end
end
1 change: 1 addition & 0 deletions lib/rails_bootstrap_form/components/labels.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def label(attribute, bootstrap_options)
def label_classes(attribute, bootstrap_options)
classes = [bootstrap_options.label_class, bootstrap_options.additional_label_class]
classes << bootstrap_options.hide_class if bootstrap_options.hide_label
classes << "required" if is_attribute_required?(attribute)
classes.flatten.compact
end

Expand Down
64 changes: 64 additions & 0 deletions lib/rails_bootstrap_form/components/required_field.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# -*- encoding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-

module RailsBootstrapForm
module Components
module RequiredField
extend ActiveSupport::Concern

def self.included(base_class)
def is_field_required?(attribute, options)
return false unless attribute

if options.key?(:required)
options[:required]
else
is_attribute_required?(attribute)
end
end

def required_field_options(options, attribute)
required = is_field_required?(attribute, options)

{}.tap do |option|
option[:aria] = {required: true} if required
option[:required] = required
end
end

def is_attribute_required?(attribute)
return false unless attribute

target = object.instance_of?(Class) ? object : object.class
return false unless target.respond_to?(:validators_on)

has_presence_validator?(target_validators(target, attribute)) ||
is_required_association?(target, attribute)
end

def target_validators(target, attribute)
target.validators_on(attribute).map(&:class)
end

def has_presence_validator?(target_validators)
target_validators.include?(ActiveModel::Validations::PresenceValidator) ||
(defined?(ActiveRecord::Validations::PresenceValidator) &&
target_validators.include?(ActiveRecord::Validations::PresenceValidator))
end

def is_required_association?(target, attribute)
target.reflections.find do |name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == attribute.to_s

has_presence_validator?(target_validators(target, name))
end
end

private :is_field_required?, :required_field_options, :target_validators,
:has_presence_validator?, :is_required_association?
end
end
end
end

0 comments on commit 38fd5b6

Please sign in to comment.