function templateString(text, args) { for (const argName in args) { text = text.replace(`{${argName}}`, args[argName]); } return text; } function addFormRow(templateName) { const allRows = document.querySelectorAll(`[data-new-item-template="${templateName}"]`); const templateElement = allRows[0]; const nextId = allRows.length + 1; 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 = '' }); // Template attributes const templatedAttrNodes = newItem.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: nextId})); } } // Template content const templatedNodes = newItem.querySelectorAll('[data-new-item-template-content]'); for (const node of templatedNodes) { const templatedString = node.dataset.newItemTemplateContent; node.innerHTML = templateString(templatedString, {i: nextId}) } allRows[allRows.length - 1].insertAdjacentElement('afterend', newItem); } function setUpAddFormRow() { const buttons = document.querySelectorAll('button[data-new-item]'); for (const button of buttons) { button.addEventListener('click', () => addFormRow(button.dataset.newItem)) } } document.addEventListener('DOMContentLoaded', setUpAddFormRow);