Rails’ Form Builder gives a great interface to easily build extensive forms. But a common issue many Rails developers using Tailwind CSS stumble upon, is styling their text_field
’s, text_area
’s and check_boxes
’. There are multiple solutions:
- copy all Tailwind’s classes around;
- using Tailwind’s
@apply
directive and add a (vanilla) class, eg.input
to the form field; - create custom components (using ViewComponent) for each field type.
Option 2 was my go-to solution for a long time. Reusable, easy to make changes and simple enough to apply. But when I was working on my next SaaS, I started to explore a new option: a custom form builder.
What is a Form Builder?
Rails Form Builder provides a structured way to generate and handle HTML forms, allowing you to create form fields that are automatically associated with model objects and their attributes. I use them a lot!
Creating a basic custom form builder
You can create your own (Action view) Form Builder by subclassing ActionView::Helpers::FormBuilder
.
The most basic version could look like this:
class CustomFormBuilder < ActionView::Helpers::FormBuilder
def text_field(attribute, options = {})
super(attribute, options.merge(class: "px-2 py-1 text-gray-900 bg-gray-50 rounded"))
end
# def password_field(attribute, options = {});end
# def email_field(attribute, options = {});end
# def file_field(attribute, options = {});end
# def url_field(attribute, options = {});end
end
You can see how you can write this for every supported field type and add the needed Tailwind CSS classes. The most common field types are: text_field, password_field, email_field, file_field, and url_field.
You can use your new Form Builder in different ways. For just one form:
<%= form_with model: @user, builder: CustomFormBuilder do |form| %>
<%= form.text_field :name %>
<% end %>
Of, if you want to apply it to all your forms, add the following to your ApplicationController:
default_form_builder CustomFormBuilder
For the above example, this would then render:
<input type="text" name="user[name]" class="px-2 py-1 text-gray-900 rounded bg-gray-50" id="user_name">
Included in Rails Designer
Rails Designer’s UI Components Library has its own FormBuilder included, giving you beautiful form fields without doing all the work.
It has support for all the typical field types like text_field and password_field, but also collection_select and collection_radio_buttons.
It has also a feature called Smart Inputs. If you used gems like simple_form; this is familiar. You can write <%= form.input :name %>
and it will render the correct field helper, including a label and a wrapping div-element, something like this:
<div class="w-full mt-4">
<label class="text-gray-700" for="user_title">Title</label>
<input class="w-full px-2 py-1 text-sm text-gray-900 rounded bg-gray-50" type="text" name="user[title]" id="user_title">
</div>
It is also smart enough to correctly render the correct field type when using <%= form.input :email %>
(email_field) or <%= form.input :password %>
(password_field).
Behind the scenes it checks for two Rails Designer components presence: FormLabelComponent and FieldComponent.
Check out the docs on Form Builder for more details and get access to thé Rails UI Components Library here (it’s a great Christmas present for your team and you! 🎅)