Skip to content

Instantly share code, notes, and snippets.

@fractaledmind
Created March 5, 2021 11:24
Show Gist options
  • Save fractaledmind/40ec91af98e15567275fdd57486ecf16 to your computer and use it in GitHub Desktop.
Save fractaledmind/40ec91af98e15567275fdd57486ecf16 to your computer and use it in GitHub Desktop.
Rails CRUD has_many rich_texts
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [ "insertionPoint", "template", "fieldsWrapper" ]
connect() {
this.element[this.identifier] = this
}
add_association(event) {
const content = this.templateTarget.innerHTML.replace(/NEW_RECORD/g, new Date().getTime())
this.insertionPointTarget.insertAdjacentHTML('beforebegin', content)
}
remove_association(event) {
event.preventDefault()
let wrapper = event.target.closest('[data-target="nested-form.fieldsWrapper"]')
// New records are simply removed from the page
if (wrapper.dataset.newRecord == "true") {
wrapper.remove()
// Existing records are hidden and flagged for deletion
} else {
wrapper.querySelector("input[name*='_destroy']").value = 1
wrapper.style.display = 'none'
}
}
}
<%= form_with(model: feature_story) do |form| %>
<fieldset class="form-group">
<legend class="label">Steps</legend>
<%= render "steps_nested_form", form: form %>
</fieldset>
<% end %>
<%= content_tag :li, data: { target: "nested-form.fieldsWrapper", new_record: form.object.new_record? } do %>
<div class="form-group flex">
<%= form.label :step, class: "sr-only" %>
<div class="flex-1 trix-wrapper trix-no-block-formatting">
<%= form.rich_text_area :step, style: "min-height: 1em" %>
</div>
<%= link_to "&times".html_safe, "#", data: { action: "click->nested-form#remove_association" }, class: "ml-4 bg-red-200 text-red-500 rounded-full text-center font-bold h-8 w-8 leading-8 text-2xl inline block hover:text-red-700" %>
</div>
<%= form.hidden_field :request_id %>
<%= form.hidden_field :id %>
<%= form.hidden_field :_destroy %>
<span class="sr-only">&nbsp;</span>
<% end %>
<div data-controller="nested-form">
<template data-target="nested-form.template">
<%= form.fields_for :thinking_aloud_steps, form.object.thinking_aloud_steps.build, child_index: 'NEW_RECORD' do |step| %>
<%= render "step_fields", form: step %>
<% end %>
</template>
<% steps_for_form = if form.object.thinking_aloud_steps.exists?
form.object.thinking_aloud_steps.includes([:rich_text_step])
else
form.object.thinking_aloud_steps.build
end %>
<ol class="list-decimal fancy-list">
<%= form.fields_for :thinking_aloud_steps, steps_for_form do |step| %>
<%= render "step_fields", form: step %>
<% end %>
<li class="hidden" data-target="nested-form.insertionPoint"></li>
</ol>
<button type="button"
class="btn btn-primary btn-small outline space-x-2"
data-action="nested-form#add_association">
<span>Add new step</span>
<%= inline_svg_tag("feather/plus-circle.svg", class: "h-4 w-4") %>
</button>
</div>
def request_params
params.require(:request)
.permit(
:type,
thinking_aloud_steps_attributes: [
:step,
:request_id,
:id,
:_destroy
])
end
# == Schema Information
#
# Table name: requests
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
#
class ThinkingAloud < Request
has_many :thinking_aloud_steps, dependent: :destroy
accepts_nested_attributes_for :thinking_aloud_steps, allow_destroy: true
end
# == Schema Information
#
# Table name: thinking_aloud_steps
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# request_id :bigint not null
#
# Indexes
#
# index_thinking_aloud_steps_on_request_id (request_id)
#
# Foreign Keys
#
# fk_rails_... (request_id => requests.id)
#
class ThinkingAloudStep < ApplicationRecord
belongs_to :thinking_aloud, foreign_key: :request_id
has_rich_text :step
validates :step, presence: true
end
.trix-no-attachments {
.trix-button-group--file-tools { display: none !important; }
}
.trix-no-block-formatting {
.trix-button-group--block-tools { display: none !important; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment