I have a repeated pattern throughout my app that looks like this:
<div class="form-group floating-label <%= f.object.errors[:to].any?? "has-error has-feedback" : "" %>">
<% if f.object.errors[:to].any? %>
<%= f.label f.object.errors[:to].join(", ") %>
<% end %>
<%= f.email_field :to, class: "form-control" %>
<%= f.label :to %>
</div>
The only thing that changes is the attribute. Instead of the :to
attribute, it might be something else. But everything else will remain the same.
I extracted it out into a helper method:
_form.html.erb
<%= field_view "To", f.email_field(:to, class: "form-control") %>
form_helper.rb
def field_view(label, *args, &block)
# label = label.t internalization
options = args.extract_options!
field = args.first
formatter = args.second
data = capture(&block) if block_given?
options[:class] = "form-group floating-label #{options[:class]}".strip
element = formatter ? send(formatter, field) : field
make_content label, element, options
end
def make_content(label, element, options)
content_tag :div, options do
element + content_tag(:label, label)
end
end
I do not want my form_helper to know anything about the field. Because sometimes it will be f.text_field :to
, text_field_tag :to
, f.select
, etc. Too much change happening to make the form_helper aware of it.
What approach would you suggest in order to incorporate that error checking functionality which is shown in the first example?
1 Answer 1
I would try this (naming needs improvement):
*_helper.rb:
def field_wrapper(errors, &block)
css_classes = %w(form-group floating-label)
css_classes << 'has-error has-feedback' if errors.any?
content_tag :div, class: css_classes, &block
end
def error_label(form, errors)
form.label errors.join(', ') if errors.any?
end
*.html.erb:
<%= field_wrapper f.object.errors[:to] do %>
<%= error_label f, f.object.errors[:to] %>
<%= f.email_field :to, class: "form-control" %>
<%= f.label :to %>
<% end %>