Matthew Weeks
Matthew Weeks

Reputation: 1028

Rails field_error_proc override messing with html structure

In a rails application I am overriding field_error_proc to allow the displaying of inline errors like so:

enter image description here

and the code to do so looks like the following

ActionView::Base.field_error_proc = proc { |html_tag, instance|
  html = %(<div class="field_with_errors">#{html_tag}</div>).html_safe

  form_fields = %w[textarea input select]

  elements = Nokogiri::HTML::DocumentFragment.parse(html_tag).css 'label, ' + form_fields.join(', ')

  elements.each do |e|
    next unless form_fields.include?(e.node_name)
    errors = [instance.error_message].flatten.uniq.collect { |error| "#{instance.method_name.humanize} #{error}" }
    html = %(<div class="field_with_errors">#{html_tag}</div><small class="form-text error-text">&nbsp;#{errors.join(', ')}</small>).html_safe
  end

  html
}

This works fine for normal inputs, as they are wrapped normally.

The problem comes when the input is wrapped around something, which I would like the field_with_errors div to wrap around like a select2 dropdown or a custom input group like so:

<div class="split-daterange-picker form-control daterange-picker" id="">
  <input class="start-date" placeholder="Requested Dates" type="text" name="housing_lead[start_date]"> 
  <span class="separator"></span>
  <input class="end-date" placeholder="Requested Dates" type="text" name="housing_lead[end_date]"> 
</div>

I am using 2 inputs that essentially act as a single form field like so: enter image description here

But the problem is when the inputs are wrapped in the field_with_errors div it looks like the following:

enter image description here

What I'd essentially like to do is wrap the split-daterange-picker in the field_with_errors div so I can style appropriately and append the error messages after that. How can I do this

Upvotes: 1

Views: 1112

Answers (1)

eremite
eremite

Reputation: 1916

I know of no way to do that with ActionView::Base.field_error_proc. But you could probably get something working with a custom form builder, as discussed in this answer.

class PrettyFormBuilder < ActionView::Helpers::FormBuilder  
  def split_daterange_picker(start_field, end_field, options = {})
    options[:wrapper_class] ||= []
    if @object.errors[start_field].present? || @object.errors[end_field].present?
      options[:wrapper_class] << 'field_with_errors'
    end
    datepickers = text_field(start_field) + text_field(end_field)
    @template.content_tag(:div, datepickers, class: options[:wrapper_class])
  end
end

Upvotes: 1

Related Questions