diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 47faed85..702a2a23 100644 --- a/blocks/form-handler/controllers/event-info-component-controller.js +++ b/blocks/form-handler/controllers/event-info-component-controller.js @@ -1,6 +1,6 @@ /* eslint-disable no-use-before-define */ import { getLibs } from '../../../scripts/utils.js'; -import { getMappedInputsOutput } from './share-controller.js'; +import { getMappedInputsOutput, initRepeater, initRemove } from './share-controller.js'; const { createTag } = await import(`${getLibs()}/utils/utils.js`); @@ -284,6 +284,8 @@ function initCalendar(component) { export default function init(component) { initCalendar(component); + initRepeater(component); + initRemove(component); } export function onResume(component, eventObj, inputMap) { diff --git a/blocks/form-handler/controllers/share-controller.js b/blocks/form-handler/controllers/share-controller.js index 7469afc5..8f647a3e 100644 --- a/blocks/form-handler/controllers/share-controller.js +++ b/blocks/form-handler/controllers/share-controller.js @@ -139,3 +139,33 @@ export default function makeFileInputDropZone(inputWrapper) { handleImageFiles(inputWrapper, files); }); } + +export function initRepeater(component) { + const repeaters = component.querySelectorAll('.repeater-element'); + repeaters.forEach((element) => { + const vanillaNode = element.previousElementSibling.cloneNode(true); + element.addEventListener('click', (event) => { + const clonedNode = vanillaNode.cloneNode(true); + const prevNode = event.currentTarget.previousElementSibling; + clonedNode.setAttribute('repeatIdx', parseInt(prevNode.getAttribute('repeatIdx'), 10) + 1); + + // Reset delete icon state and add listener. + const deleteIcon = clonedNode.querySelector('.delete-button'); + deleteIcon.classList.remove('hidden'); + setRemoveEventListener(deleteIcon); + + prevNode.after(clonedNode); + }); + }); +} + +function setRemoveEventListener(removeElement) { + removeElement.addEventListener('click', (event) => { + event.currentTarget.parentElement.remove(); + }); +} + +export function initRemove(component) { + const removeIcons = component.querySelectorAll('.delete-button'); + removeIcons.forEach((removeIcon) => setRemoveEventListener(removeIcon)); +} diff --git a/blocks/form-handler/form-handler.css b/blocks/form-handler/form-handler.css index 11b3637b..c1485acb 100644 --- a/blocks/form-handler/form-handler.css +++ b/blocks/form-handler/form-handler.css @@ -254,3 +254,36 @@ background-color: var(--color-white); color: var(--color-red); } + +.form-handler .hidden { + display: none; +} + +.form-handler .repeater-element { + max-width: 100%; + height: var(--spectrum-spacing-700, 48px); + flex-shrink: 0; + border-radius: 10px; + border: 1px dashed var(--Divider, #6E6E6E); + display: flex; + align-items: center; + padding: 0px 32px; + margin-bottom: 24px; +} + +.form-handler .icon-add-circle { + height: 24px; + width: 24px; +} + +.form-handler .repeater-element-title { + width: 100%; + color: var(--web-gray-scale-color-gray-500909090, var(--web-grey-scale-color-gray-500909090, #909090)); + /* Heading/Heading S */ + font-family: "Adobe Clean"; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: 24px; /* 125% */ + margin: 0px; +} \ No newline at end of file diff --git a/utils/utils.js b/utils/utils.js index 87da1d55..44212ae4 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -71,3 +71,18 @@ export function buildNoAccessScreen(el) { el.append(h1, area); area.append(getIcon('browser-access-forbidden-lg'), noAccessDescription); } + +export function addRepeater(element, title) { + element.lastChild.setAttribute('repeatIdx', 0); + + const tag = createTag('div'); + tag.classList.add('repeater-element'); + + const heading = createTag('h3', { class: 'repeater-element-title' }, title); + tag.append(heading); + + const plusIcon = getIcon('add-circle'); + tag.append(plusIcon); + + element.append(tag); +}