Skip to content

pinzonjulian/actionview_attribute_builders

Repository files navigation

Actionview::AttributeBuilders

🧪 ☣️ This gem is an experiment. Please do not use it for anything other than to explore the new concepts it brings into Rails.

New!

Visit the AttributeBuilders playground https://attributebuilders.julianpinzon.com to see all of this in action!

🧑🏽‍💻 Installation

Install the gem in your Rails application. Use:

$ bundle add actionview_attribute_builders

Or add it directly in your Gemfile

gem 'actionview_attribute_builders', '~> 0.1.0'

And then execute:

$ bundle

🧑🏽‍🎨 Usage

1. Create a custom form builder

# app/form_builders/example_form_builder.rb
 
class ExampleFormBuilder < ActionView::Helpers::FormBuilder
end

2. Add a text_field method, overriding the one inherited from its parent (Rails' default)

# app/form_builders/example_form_builder.rb
 
class ExampleFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(method, options = {})
    # ...
  end
end

3. Use the appropriate <helper>_attribute_builder method for the type of field you're creating

In this case text_field_attribute_builder

# app/form_builders/example_form_builder.rb
 
class ExampleFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(method, options = {})
    # 1. Retreive an instance of the `AttributeBuilders::TextField` class via the helper method
    attribute_builder = text_field_attribute_builder(method, options)
    # 2. Use the `html_attributes` method to retrieve the computed attributes. Commonly, `id`, `name`, `value` etc.
    html_attributes = attribute_builder.html_attributes
    # => { id: "user_name", name: "user[name]", value: "Julian" }
  end
end

4. Render the HTML form element

# app/form_builders/example_form_builder.rb
 
class ExampleFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(method, options = {})
    # ...
    # 3. Use the attributes to create the markup.
    
    # 3.1 For example, use a web component
    @template.content_tag("example-text-field", nil,  html_attributes.merge!(options))

    # 3.1 Or a ViewComponent
    @template.render(ExampleFieldComponent.new(html_attributes, options))
  end
end

5. Use the new form builder in a template

<%= form_with model: @user, builder: ExampleFormBuilder do |form| %>
  <%= form.text_field :name, required: true, label: "Name" %>
<% end %>

6. Check the output in your browser's inspector to verify the new markup

Note how, just like in a plain Rails application, the field includes the conventional name, type and id attributes based on the model used.

<form action="/users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="3EgNNhL-HUI-2gxV_-9T_cEaT8p6b4CWtVbQMCeHlaKlfgd_p9sFuuLVKaDkUt3gEQKhc_d7YdR-TFzp-LiAuA" autocomplete="off">
  <example-text-field required="" type="text" name="user[name]" id="user_name"></example-text-field>
</form>

6. Do this for *every form helper

number_field, password_field, checkbox etc.

* every helper that's currently supported. Not all of them are done

🏞️ Concrete examples

Playground

Visit the Attribute Builders playground https://attributebuilders.julianpinzon.com for an interactive preview of this gem in action.

Implementation guides

👀 Images inside!

Visit the examples folder and follow the guides on how to use this with real components using Shoelace and Material Design Web Components.

🔧 API

This library exposes helpers that use the exact same mechanics to create form input element attributes that Rails uses internally to create input elements that are compliant with ActiveModel and ActiveRecordconventions.

Check out the lib/actionview_attribute_builders/attribute_builders_helper for a list of all currently supported builders.

☢️ Status

This library is not finished. There are several things missing. For example:

  1. Not all attribute builders have been extracted from Rails. There are currently 4 missing input fields and some extra missing helpers (like buttons and input submit fields)
  2. Some helpers are far more complex than others and probably can't be used yet in a real scenario. For example, <select> tags (and similar elements) are harder because they are composed of not one but multiple html elements (<select> and <option>). This problem is yet to be solved.
  3. The way the gem is loaded is a bit hacky and has a lot of garbage comments.

⚙️ Current AttributeBuilders compatibility with ActionView Tags

Attributer Builder Available?
check_box
collection_check_boxes ◻️
collection_radio_buttons ◻️
collection_select
color_field
date_field
date_select ◻️
datetime_field
datetime_select ◻️
email_field
file_field
grouped_collection_select
hidden_field
label
month_field
number_field
password_field
radio_button
range_field
search_field
select
tel_field
text_area
text_field
time_field
time_select ◻️
time_zone_select
url_field
week_field
weekday_select
submit
button

💎 What problem is this solving?

The short version is that Rails has a lot of conventions for form fields to work seamlessly with ActiveModel and ActiveRecord. However, these are not exposed to developers; they are deeply nested and coupled to the rendering of the actual markup. This makes creating new FormBuilders notoriously hard or even impossible in some cases. This forces developers to abandon Rails' conventions which is not desirable.

This gem's objective is to separate those responsibilities so developers can leverage Rails' conventions to build custom form elements and keep enjoying the advantages of convention over configuraiton.

I have written extensively about this problem. If you're interested, please read the following:

  1. https://dev.julianpinzon.com/series/exploring-rails-forms
  2. ViewComponent/view_component#420 (comment)

Contributing

The best way to contribute to this gem in its current state is:

  1. to experiment with it and build custom FormBuilder classes.
  2. start a discussion or issue on this repo

License

The gem is available as open source under the terms of the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages