brandnewbox / app-form-builder

Reference implementation of BNB's Rails FormBuilder
50 stars 2 forks source link
formbuilder forms rails ruby ruby-on-rails

BNB AppFormBuilder

The canonical implementation of BNB's custom form builder.

In the past we've often reached for gems like SimpleForm to implement custom form builders. Form builder gems are amazing feats of engineering, but they were adding complexity to our apps and another layer of config to learn and manage. We found this in-app form builder approach to be more approachable for our team.

By using an in-app form builder we get a few advantages

We wrote up a blog post about this form builder here https://brandnewbox.com/notes/2021/03/form-builders-in-ruby/.

Install

This is a copy and paste library. There's no gem to install, just copy these files into your Rails app and customize from there. We have a template file that you can use to get started.

bin/rails app:template LOCATION=https://raw.githubusercontent.com/brandnewbox/app-form-builder/main/template.rb

Alternatively, you can manually add the files to your Rails app and follow the steps below.

Docs

The main entrypoint into the AppFormBuilder (drawing inspiration from SimpleForm) is the input method.

= f.input :method,
    as: # symbol, optional, will default to the type of the attribute. calls #{as}_input in the form builder
    label: # string | false, optional, controls the label text or hides the label
    hint: # string, optional, adds hint text below the input
    collection: # array, triggers the select_input method
    text_method: # symbol, optional, the method to pull the text from the collection
    value_method: # symbol, optional, the method to pull the value from the collection
    input_html: # hash, optional, additional html options for the input. Most inputs accept this and try to intelligently merge existing options with customizations

Examples

# Renders a string field if `name` is a string column
= f.input :name
# Renders a text area with no label
= f.input :name, as: :text, label: false
# Example of more full featured forms from our code
= f.input :full_name, label: t("full_name").titleize
= f.input :preferred_name, label: t("preferred_name").titleize , hint: t("preferred_name_hint")

= f.fields_for :profile do |f|
  = f.input :work_location, label: t("location"),as: :grouped_select, collection: Profile::WORK_LOCATIONS, group_method: :last, include_blank: t("select_state").titleize, input_html: {style: "color: #808080;"}
  = f.input :tag, label: t("position").titleize, input_html: {placeholder: t("enter_position")}, hint: t("enter_position_long")
  %h4.pb-2=t("optional_info").titleize
  = f.input :organization, label: t("organization").titleize
  = f.input :biography, label: t("biography").titleize, input_html: {placeholder: t("biography_hint")}
  = f.input :language_list, label: t("your_lang").titleize, collection: User::LANGUAGES, input_html: { multiple: true, data:{ controller: "tag", placeholder: t("select_language").titleize } }