Rails nested form (new gem with Stimulus)

hungle00 - Jun 18 '23 - - Dev Community

Nested forms are forms that handle nested models and attributes in one form; e.g. a project with its tasks or an invoice with its line items.

Before Rails 6, Cocoon is a good choice for creating dynamic nested forms. But Cocoon needs jQuery to work well, it's a very old library on modern-day frontend frameworks.
When Stimulus is came out, Rails devs is suggested to use Stimulus as Javascript library in their projects. So, I created a gem for handling dynamic nested forms with Stimulus JS.

GitHub logo hungle00 / rondo_form

Same as Cocoon, but using StimulusJS https://rubygems.org/gems/rondo_form

RondoForm

Handle dynamic nested forms, same as Cocoon, but using StimulusJS

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add rondo_form

Or inside the Gemfile add the following

$ gem 'rondo_form', '~> 0.2.6'

Run the installation task:

$ rails g rondo_form:install

Usage

For example, you have Project model, which has has_many relationship with Task model:

rails g scaffold Project name:string description:string
rails g model Task description:string done:boolean project:belongs_to

You need to add accepts_nested_attributes_for to Project model:

class Project < ApplicationRecord
  has_many :tasks, dependent: :destroy
  accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true
end

Sample with SimpleForm

The RondoForm gem adds two helper functions: link_to_add_association and link_to_remove_association. The example below illustrates the way to use it.

In your projects/_form partial:

<%= simple_form_for(@project) do |f| %>
  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :description %>
  </div
Enter fullscreen mode Exit fullscreen mode

Rondo Form is easy to use, it has the same tag helpers name as cocoon: link_to_add_association, link_to_remove_association.
This gem does not need JS dependencies to work with, when you run under command, it will generate nested_rondo_controller.js in your app/javascript/controllers/ folder:



rails g rondo_form:install 


Enter fullscreen mode Exit fullscreen mode

And auto import this controller into index.js.


 js
import NestedRondoController from "./nested_rondo_controller"
application.register("nested-rondo", NestedRondoController)


Enter fullscreen mode Exit fullscreen mode

You must add data-controller="nested-rondo" to an element, that wraps fields_for and link_to_add_association helper.
For example, we have Project model, which has has_many relationship with Task model.
In your projects/_form partial:


 erb
<%= simple_form_for(@project) do |f| %>
  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :description %>
  </div>
  <h3>Tasks</h3>
  <div data-controller="nested-rondo">
    <%= f.simple_fields_for :tasks do |task| %>
      <%= render "task_fields", f: task %>
    <% end %>
    <div class="links">
      <%= link_to_add_association "Add Task", f, :tasks %>
    </div>
  </div>
  <%= f.button :submit %>
<% end %>


Enter fullscreen mode Exit fullscreen mode

In your _task_fields partial:


 erb
<div class="nested-fields">
  <%= f.input :description %>
  <%= f.input :done, as: :boolean %>
  <%= link_to_remove_association "Remove Task", f %>
</div>


Enter fullscreen mode Exit fullscreen mode

This sample I built with SimpleForm gem, but the idea is the same with Rails standard form.

. . . . . . . . .
Terabox Video Player