/* jshint esversion: 6 */ const defaults = { nameToReplace: 'idx', removeSelector: '.remove', minimalId: 'auto' } export function formStamp(element, options = {}) { const { nameToReplace, removeSelector, minimalId } = { ...defaults, ...element.dataset, ...options }; const container = element.parentElement; const template = element.querySelector('template'); const itemSelector = '.' + template.content.firstElementChild.className.replace(/ /g, '.'); const startWithId = minimalId === 'auto' ? container.querySelectorAll(itemSelector).length : parseInt(minimalId); let created = 0; const afterDomManipulation = () => { element.dispatchEvent(new CustomEvent('afterStampDomManipulation')); } const removeRow = (removeItem) => () => { const rowToDelete = removeItem.closest(itemSelector); // Flow renders identity fields directly at the form tag, so we need to look if (rowToDelete.dataset.stampRemoveWithMe) { container.closest('form') .querySelectorAll(rowToDelete.dataset.stampRemoveWithMe) .forEach(child => child.remove()) } if (element.dispatchEvent(new CustomEvent( 'beforeStampRemoval', { cancelable: true, detail: { toBeRemoved: rowToDelete } } ))) { rowToDelete.remove(); afterDomManipulation(); } } element.addEventListener('click', () => { const clone = template.content.cloneNode(true); clone.querySelectorAll('input, select, textarea').forEach(child => { child.name = child.name.replace(nameToReplace, startWithId + created); }); clone.querySelectorAll(removeSelector).forEach(child => { child.onclick = removeRow(child); }); if (element.dispatchEvent(new CustomEvent( 'beforeStampInsert', { detail: { i: startWithId + created, node: clone }, cancelable: true } ))) { element.before(clone); afterDomManipulation(); created++; } }); container.querySelectorAll(removeSelector).forEach(child => { child.onclick = removeRow(child); }); } export default formStamp;