nomilo/assets/scripts/add-form-row.js

92 lines
2.8 KiB
JavaScript

function templateString(text, args) {
for (const argName in args) {
text = text.replace(`{${argName}}`, args[argName]);
}
return text;
}
function templateNode(node, id) {
// Template attributes
const templatedAttrNodes = node.querySelectorAll('[data-new-item-template-attr]');
for (const node of templatedAttrNodes) {
const attributes = node.dataset.newItemTemplateAttr.split(/\s/);
for (const attribute of attributes) {
const templatedString = node.getAttribute(`data-template-${attribute}`);
node.setAttribute(attribute, templateString(templatedString, {i: id}));
}
}
// Template content
const templatedNodes = node.querySelectorAll('[data-new-item-template-content]');
for (const node of templatedNodes) {
const templatedString = node.dataset.newItemTemplateContent;
node.innerHTML = templateString(templatedString, {i: id + 1})
}
}
function addFormRow(templateName) {
const allRows = document.querySelectorAll(`[data-new-item-template="${templateName}"]`);
const templateElement = allRows[0];
const nextId = allRows.length;
const newItem = templateElement.cloneNode(true);
newItem.querySelectorAll('[data-new-item-skip]')
.forEach(node => node.remove());
// Reset form fields
newItem.querySelectorAll('input')
.forEach(input => { input.value = '' });
newItem.querySelectorAll('textarea')
.forEach(input => { input.value = '' });
templateNode(newItem, nextId);
const deleteButton = newItem.querySelector('button[data-delete-item]');
if (deleteButton) {
setupDeleteButton(deleteButton)
}
allRows[allRows.length - 1].insertAdjacentElement('afterend', newItem);
}
function setupForm() {
const addRowButtons = document.querySelectorAll('button[data-new-item]');
for (const button of addRowButtons) {
button.addEventListener('click', () => addFormRow(button.dataset.newItem))
}
const delRowButtons = document.querySelectorAll('button[data-delete-item]');
for (const button of delRowButtons) {
setupDeleteButton(button);
}
}
function setupDeleteButton(button) {
let row = button.parentElement;
while (!row.dataset.newItemTemplate) {
row = row.parentElement;
}
const templateName = row.dataset.newItemTemplate;
button.addEventListener('click', () => {
let allRows = document.querySelectorAll(`[data-new-item-template="${templateName}"]`);
if (allRows.length == 1) {
addFormRow(templateName);
}
row.remove();
document.querySelectorAll(`[data-new-item-template="${templateName}"]`)
.forEach(templateNode);
});
}
document.addEventListener('DOMContentLoaded', setupForm);