// Repeated rows (links, timeline entries, services ...) can be added, removed and moved. // Their fields use "#" as index placeholder in data-name, the real names are set on submit. document.addEventListener('click', (event) => { const button = event.target.closest('[data-repeat-add], [data-repeat-remove], [data-repeat-up], [data-repeat-down]'); if (!button) return; if (button.hasAttribute('data-repeat-add')) { const repeat = button.closest('[data-repeat]'); const template = repeat.querySelector(':scope > template[data-repeat-template]'); const list = repeat.querySelector(':scope > [data-repeat-list]'); list.append(template.content.cloneNode(true)); list.lastElementChild?.querySelector('input:not([type="hidden"]), textarea, select')?.focus(); return; } const row = button.closest('[data-repeat-row]'); if (button.hasAttribute('data-repeat-remove')) row.remove(); else if (button.hasAttribute('data-repeat-up')) row.previousElementSibling?.before(row); else row.nextElementSibling?.after(row); }); function rowIndexes(field) { const indexes = []; for (let row = field.closest('[data-repeat-row]'); row; row = row.parentElement.closest('[data-repeat-row]')) { const siblings = [...row.parentElement.children].filter((el) => el.matches('[data-repeat-row]')); indexes.unshift(siblings.indexOf(row)); } return indexes; } document.addEventListener('submit', (event) => { const form = event.target; if (form.dataset.confirm && !window.confirm(form.dataset.confirm)) { event.preventDefault(); return; } for (const field of form.querySelectorAll('[data-name]')) { const indexes = rowIndexes(field); let i = 0; field.name = field.dataset.name.replace(/#/g, () => indexes[i++] ?? 0); } }); // New project: fill the URL name from the German title until it is edited by hand const slug = document.querySelector('[data-slug]'); const title = document.querySelector('[data-title]'); if (slug && title && !slug.value) { let touched = false; slug.addEventListener('input', () => (touched = true)); title.addEventListener('input', () => { if (touched) return; slug.value = title.value .toLowerCase() .replace(/ä/g, 'ae') .replace(/ö/g, 'oe') .replace(/ü/g, 'ue') .replace(/ß/g, 'ss') .normalize('NFKD') .replace(/[̀-ͯ]/g, '') .replace(/[^a-z0-9]+/g, '-') .slice(0, 60) .replace(/^-+|-+$/g, ''); }); }