Hello!
I have a generic modal that renders the form of the section you want to edit.
When you click on the edit button in one of the sections, I want to trigger a modal that will render the form from rails and then inject that into the modal child element.
When the user hits the save button, I want to save the changes in the backend and then return the partial of the updated section.
The problem is it seems like I have to attach the controller to the body or top-level element.
In my example below I have a controller for edit-modal and venture-stage.
The problem is there are multiple sections and it looks like I will end up with a body tag that has multiple controllers. (<body data-controller="edit-modal about venture-stage location highlights"></body>
)
Somehow, I feel like there is a better way to do this.
Any thoughts? I included my code below to illustrate what I am trying to accomplish.
It doesn’t look like each controller should know about each other.
the only alternative is for the edit-modal controller to reference the content controllers…
but, then that seems messy as well.
HTML
<body data-controller="edit-modal venture-stage">
<div class="content">
<div class="sidebar">
<div data-target="venture-stage.content">
<!-- render venture stage data -->
</div>
<%= link_to edit_venture_stage_path(@project),
remote: true,
data: {
action: 'ajax:success->edit-modal#onShowForm'
} %>
</div>
<div class="main">
<!-- render main content -->
<div class="modal-wrapper" data-reveal>
<div target="edit-modal.content">
<%= form_for venture_stage_path(@project),
remote: true,
data: { action: 'ajax:success->edit-modal#onSaveSucess ajax:success->venture-stage#onUpdate' } do |f| %>
<!-- rendered form fields -->
<% end %>
</div>
</div>
</div>
</div>
</body>
edit_modal_controller.js
import { Controller } from 'stimulus';
export default class extends Controller {
static targets = [
'content',
]
connect() {
this.$modal = $(this.contentTarget.parentNode());
}
disconnect() {
this.$modal.foundation('_destroy');
this.$modal = null;
}
onShowForm(e) {
const [data, status, xhr] = e.detail;
this.contentTarger.innerHTML = xhr.response;
this.show();
}
show() {
this.$modal.foundation('open');
}
hide() {
this.$modal.foundation('close');
}
}
venture_stage_controller.js
import { Controller } from 'stimulus';
export default class extends Controller {
static targets = ['content'];
onUpdate(e) {
const [data, status, xhr] = e.details;
this.contentTarget.innerHTML = xhr.response;
}
}