Skip to content

Instantly share code, notes, and snippets.

@slecorvaisier
Last active March 30, 2018 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slecorvaisier/99336ed2b49652d5e192e856dcf0295e to your computer and use it in GitHub Desktop.
Save slecorvaisier/99336ed2b49652d5e192e856dcf0295e to your computer and use it in GitHub Desktop.
komponent rendering issue
.RENDERED_TWICE
= @f.field_wrapper @field_name, class: "form-group" do
= @f.text_field @field_name
# frozen_string_literal: true
class CustomFormBuilder < ActionView::Helpers::FormBuilder
FIELDS = %w[textarea input select].freeze
delegate :capture, :safe_join, :raw, :content_tag, to: :@template
def field_wrapper(attribute, options = {}, &block)
content = capture(&block)
classes = options.delete(:class) { "" }.split
errors = options.delete(:errors) { [] }
errors = @object.errors[attribute] if @object.present? && errors.empty?
content = append_errors(content, errors) if errors.any?
content_tag :div, class: classes.join(" "), **options do
content
end
end
private
def append_errors(content, errors)
elements = Nokogiri::HTML::DocumentFragment.parse(content)
elements
.children
.select { |element| FIELDS.include? element.node_name }
.select { |element| %w[checkbox radio hidden].exclude? element[:type] }
.each { |element| element[:class] = "is-invalid #{element[:class]}".strip }
safe_join([elements.to_html.html_safe, *html_errors(errors)]) # rubocop:disable Rails/OutputSafety
end
def html_errors(errors)
errors.map { |error| content_tag(:div, error, class: "invalid-feedback") }
end
end
= form_for(@model, options) do |f|
// this component will be rendered twice, in a nested fashion
= component "list_error", f: f, field_name: "foo"
// this one will behave as expected
= component "list_success", f: f, field_name: "bar"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment