Skip to content

Instantly share code, notes, and snippets.

@skyporter
Last active June 5, 2020 08:00
Show Gist options
  • Save skyporter/a7d4bf19e17ae74ceef1dd08d2a11474 to your computer and use it in GitHub Desktop.
Save skyporter/a7d4bf19e17ae74ceef1dd08d2a11474 to your computer and use it in GitHub Desktop.
// This example controller works with specially annotated HTML like:
//
// <div data-controller="nested-form">
// <template data-target="nested-form.template">
// <%= form.fields_for :tasks, Task.new, child_index: 'NEW_RECORD' do |ff| %>
// <%= render "task_fields", form: ff %>
// <% end %>
// </template>
// <%= form.fields_for :tasks do |ff| %>
// <%= render "task_fields", form: ff %>
// <% end %>
// <%= link_to "Add Task", "#", "data-target": "nested-form.link", "data-action": "click->nested-form#add_association" %>
// </div>
//
// # _task_fields.html.erb
// <div class="nested-fields" data-new-record="<%= form.object.new_record? %>">
// <%= form.text_field :name %>
// <%= link_to "Remove", "#", "data-action": "click->nested-form#remove_association" %>
// <%= form.hidden_field :_destroy %>
// </div>
import {Controller} from "stimulus"
export default class extends Controller {
static targets = ["link", "template"]
addAssociation(e) {
e.preventDefault();
let content = this.templateTarget.innerHTML.replace(/NEW_RECORD/g, new Date().getTime());
this.linkTarget.insertAdjacentHTML('beforebegin', content);
}
removeAssociation(e) {
e.preventDefault();
let wrapper = e.target.closest(".nested-fields");
if (wrapper.dataset.newRecord === "true") {
wrapper.remove(); // New records are simply removed from the page
} else {
// Existing records are hidden and flagged for deletion
wrapper.querySelector("input[name*='_destroy']").value = 1;
wrapper.style.display = 'none';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment