Module: DynamicFormHelper
- Defined in:
- app/helpers/dynamic_form_helper.rb
Overview
Extraction from https://github.com/joelmoss/dynamic_form/blob/master/lib/action_view/helpers/dynamic_form.rb
And modified for bootstrap styles
Instance Method Summary collapse
Instance Method Details
#error_messages_for(*params) ⇒ Object
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 |
# File 'app/helpers/dynamic_form_helper.rb', line 5 def (*params) = params..symbolize_keys [:header_message] = false objects = Array.wrap(.delete(:object) || params).map do |object| unless object.is_a?(ActiveRecord::Associations::CollectionProxy) object = instance_variable_get(:"@#{object}") unless object.respond_to?(:to_model) object = convert_to_model(object) [:object_name] ||= object.class.model_name.human.downcase if object.class.respond_to?(:model_name) end object end objects = objects.flatten.compact count = objects.inject(0) { |sum, object| sum + object.errors.count } return if count.zero? [:object_name] ||= params.first I18n. locale: [:locale], scope: %i[errors template] do |locale| = if .include?(:header_message) [:header_message] else locale.t :header, count: count, model: [:object_name].to_s.tr('_', ' ') end = .include?(:message) ? [:message] : locale.t(:body) = objects.flat_map { |object| object.errors. }.uniq # Use CalloutComponent for consistent styling with flash messages. # # `data-error-summary` is the hook the global turbo:submit-end handler # (client/js/crm/setup/turbo_config.js) uses to scroll the page back to # this summary after a 422 form submission, so a user who clicked Save # at the bottom of a long form actually sees that validation failed. # # The inline `scroll-margin-top` clears the fixed CRM navbar so the # alert lands fully visible — the browser honours scroll-margin-top # during scrollIntoView(). render Railsboot::CalloutComponent.new( variant: 'danger', style: 'scroll-margin-top: 6rem', data: { 'error-summary': true } ) do content_tag(:div, class: 'd-flex gap-3') do content_tag(:div, class: 'flex-shrink-0') do fa_icon('octagon-exclamation', family: 'fa-sharp fa-solid', class: 'text-danger') end + content_tag(:div, class: 'flex-grow-1') do contents = [] contents << content_tag(:h4, ) if .present? contents << content_tag(:p, raw()) if .present? contents << content_tag(:ul, .map { |msg| content_tag(:li, raw(msg)) }.join.html_safe, style: 'margin-top:0.5em') contents.join.html_safe end + content_tag(:div, class: 'flex-shrink-0') do tag.(type: 'button', class: 'btn-close', onclick: "this.closest('.callout').style.display='none'", 'aria-label': 'Close') end end end end end |