Skip to content

Instantly share code, notes, and snippets.

@kaspth
Last active June 14, 2023 14:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaspth/32cd8bc14793c41fe29f01d7ff9050bc to your computer and use it in GitHub Desktop.
Save kaspth/32cd8bc14793c41fe29f01d7ff9050bc to your computer and use it in GitHub Desktop.
A pitch to have the ability to go between several form builders in a form, focused on Bullet Train's themed field partials.
# Provide a BulletTrain::Theme::FormBuilder, with extensions to
# go between Rails standard form helpers and BulletTrain's themed versions seamlessly.
# With standard Rails:
# form_with model: Post.new do |form|
# form.themed.text_field # Use BulletTrain theming on just one field
#
# form.themed.fields do # Need a nested section of fields but themed?
# end
# end
# themed_form_with model: Post.new do |form|
# # Use BulletTrain theming on every field, but:
# form.unthemed.text_field # Allow opting out on a field-by-field basis.
# form.original.text_field # An alternative call name in case we're using multiple different form builders.
# end
class BulletTrain::Theme::FormBuilder < ActionView::Helpers::FormBuilder
# themed_form_with model: Post.new do |form|
# form.text_field :text_field_value, autofocus: true
# end
#
# versus:
#
# form_with model: Post.new do |form|
# render "shared/fields/text_field", form: form, method: :text_field_value, options: { autofocus: true }
# end
def text_field(method, other_options: nil, **options)
@template.render "shared/fields/text_field", form: self, other_options: other_options, options: options
end
# Then define the other fields…
def date_field(...)
end
# Provide an out to the old form builder. E.g.:
# form.unthemed.text_field
alias_method :unthemed, :original
end
module BulletTrain::Theme::FormExtensions
ActionView::Helpers::FormBuilder.extend self
def register_form_builder(accessor_name, klass)
define_method(accessor_name) { klass.new(@object_name, @object, @template, @options) }
end
register_form_builder :original, self
register_form_builder :themed, BulletTrain::Theme::FormBuilder
register_from_builder :shoelaced, Shoelace::FormBuilder # Potential builder that'll output `sl-input` etc.
end
# Could also have apps set default_form_builder to BulletTrain::Theme::FormBuilder via an option,
# then form_with would automatically use the theme aware methods.
def themed_form_with(**options, &block)
form_with(**options, builder: BulletTrain::Theme::FormBuilder, &block)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment