From 07ef7a9d614a75b0b3920dccfa811f5b361c2e5e Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Fri, 3 May 2024 18:00:48 +0530 Subject: [PATCH 1/8] Adding repeatable element using a plus icon. --- .../event-info-component.css | 4 +++ .../event-info-component.js | 33 ++++++++++++++++--- .../event-info-component-controller.js | 28 ++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/blocks/event-info-component/event-info-component.css b/blocks/event-info-component/event-info-component.css index 5673512c..894a8d39 100644 --- a/blocks/event-info-component/event-info-component.css +++ b/blocks/event-info-component/event-info-component.css @@ -250,3 +250,7 @@ background-color: var(--color-info-accent-light); z-index: -1; } + +.hidden { + display: none; +} diff --git a/blocks/event-info-component/event-info-component.js b/blocks/event-info-component/event-info-component.js index 46355b1f..686b19e4 100644 --- a/blocks/event-info-component/event-info-component.js +++ b/blocks/event-info-component/event-info-component.js @@ -34,9 +34,18 @@ async function decorateField(row, type = 'text') { if (maxCharNum) input.setAttribute('maxlength', maxCharNum); - const wrapper = createTag('div', { class: 'info-field-wrapper' }); + const component = createTag('div'); row.innerHTML = ''; - wrapper.append(input, attrTextEl); + component.append(input, attrTextEl); + + // TODO Remove after validation. + const deleteButton = createTag('div', { class: 'delete-button' }); + deleteButton.append(getIcon('delete')); + deleteButton.classList.add('hidden'); + + const wrapper = createTag('div', { class: 'info-field-wrapper' }); + wrapper.append(component); + wrapper.append(deleteButton); row.append(wrapper); } @@ -97,14 +106,30 @@ function decorateDateTimeFields(row) { }); } +function addRepeater(element) { + element.lastChild.setAttribute('repeatIdx', 0); + + const tag = createTag('div'); + tag.classList.add('trial-repeater'); + const plusIcon = getIcon('add-circle'); + tag.append(plusIcon); + element.append(tag); +} + export default function init(el) { el.classList.add('form-component'); generateToolTip(el); const rows = el.querySelectorAll(':scope > div'); rows.forEach(async (r, i) => { - if (i === 1) await decorateField(r, 'text'); - if (i === 2) await decorateField(r, 'textarea'); + if (i === 1) { + await decorateField(r, 'text'); + addRepeater(r); + } + if (i === 2) { + await decorateField(r, 'textarea'); + addRepeater(r); + } if (i === 3) decorateDateTimeFields(r); }); } diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 93f90d17..641f74f8 100644 --- a/blocks/form-handler/controllers/event-info-component-controller.js +++ b/blocks/form-handler/controllers/event-info-component-controller.js @@ -279,6 +279,34 @@ function initCalendar(component) { export default function init(component) { initCalendar(component); + initRepeater(component); + initRemove(component); +} + +function initRepeater(component) { + const tRepeaters = component.querySelectorAll('.trial-repeater'); + tRepeaters.forEach((tRepeater) => tRepeater.addEventListener('click', (event) => { + const prevNode = event.currentTarget.previousElementSibling; + const nodeClone = prevNode.cloneNode(true); + // eslint + nodeClone.setAttribute('repeatIdx', parseInt(prevNode.getAttribute('repeatIdx'), 10) + 1); + const deleteIcon = nodeClone.querySelector('.delete-button'); + deleteIcon.classList.remove('hidden'); + setRemoveEventListener(deleteIcon); + prevNode.after(nodeClone); + })); +} + +function setRemoveEventListener(removeElement) { + removeElement.addEventListener('click', (event) => { + console.log('remove called'); + event.currentTarget.parentElement.remove(); + }); +} + +function initRemove(component) { + const removeIcons = component.querySelectorAll('.delete-button'); + removeIcons.forEach((removeIcon) => setRemoveEventListener(removeIcon)); } export function onResume(component, eventObj, inputMap) { From aa2402e111fbab5b8e86328eb56558b736c02355 Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Fri, 3 May 2024 20:34:27 +0530 Subject: [PATCH 2/8] Fixing cloning of components --- .../event-info-component-controller.js | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 641f74f8..5d6baf61 100644 --- a/blocks/form-handler/controllers/event-info-component-controller.js +++ b/blocks/form-handler/controllers/event-info-component-controller.js @@ -284,22 +284,23 @@ export default function init(component) { } function initRepeater(component) { - const tRepeaters = component.querySelectorAll('.trial-repeater'); - tRepeaters.forEach((tRepeater) => tRepeater.addEventListener('click', (event) => { - const prevNode = event.currentTarget.previousElementSibling; - const nodeClone = prevNode.cloneNode(true); - // eslint - nodeClone.setAttribute('repeatIdx', parseInt(prevNode.getAttribute('repeatIdx'), 10) + 1); - const deleteIcon = nodeClone.querySelector('.delete-button'); - deleteIcon.classList.remove('hidden'); - setRemoveEventListener(deleteIcon); - prevNode.after(nodeClone); - })); + const repeaters = component.querySelectorAll('.trial-repeater'); + repeaters.forEach((tRepeater) => { + const vanillaNode = tRepeater.previousElementSibling.cloneNode(true); + tRepeater.addEventListener('click', (event) => { + const clonedNode = vanillaNode.cloneNode(true); + const prevNode = event.currentTarget.previousElementSibling; + clonedNode.setAttribute('repeatIdx', parseInt(prevNode.getAttribute('repeatIdx'), 10) + 1); + const deleteIcon = clonedNode.querySelector('.delete-button'); + deleteIcon.classList.remove('hidden'); + setRemoveEventListener(deleteIcon); + prevNode.after(clonedNode); + }); + }); } function setRemoveEventListener(removeElement) { removeElement.addEventListener('click', (event) => { - console.log('remove called'); event.currentTarget.parentElement.remove(); }); } From 3f16fa404a63a6369f52e23d68f68bc93f7eb440 Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Tue, 7 May 2024 19:23:03 +0530 Subject: [PATCH 3/8] UI fixes for repeater element. --- .../event-info-component.css | 29 +++++++++++++++++++ .../event-info-component.js | 13 ++++++--- .../event-info-component-controller.js | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/blocks/event-info-component/event-info-component.css b/blocks/event-info-component/event-info-component.css index 894a8d39..f8e8292d 100644 --- a/blocks/event-info-component/event-info-component.css +++ b/blocks/event-info-component/event-info-component.css @@ -254,3 +254,32 @@ .hidden { display: none; } + +.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; +} + +.icon-add-circle { + height: 24px; + width: 24px; +} + +.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/blocks/event-info-component/event-info-component.js b/blocks/event-info-component/event-info-component.js index 686b19e4..bd22dc4c 100644 --- a/blocks/event-info-component/event-info-component.js +++ b/blocks/event-info-component/event-info-component.js @@ -106,13 +106,18 @@ function decorateDateTimeFields(row) { }); } -function addRepeater(element) { +function addRepeater(element, title) { element.lastChild.setAttribute('repeatIdx', 0); const tag = createTag('div'); - tag.classList.add('trial-repeater'); + 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); } @@ -124,11 +129,11 @@ export default function init(el) { rows.forEach(async (r, i) => { if (i === 1) { await decorateField(r, 'text'); - addRepeater(r); + addRepeater(r, 'Add event title'); } if (i === 2) { await decorateField(r, 'textarea'); - addRepeater(r); + addRepeater(r, 'Add event description'); } if (i === 3) decorateDateTimeFields(r); }); diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 5d6baf61..875a58dd 100644 --- a/blocks/form-handler/controllers/event-info-component-controller.js +++ b/blocks/form-handler/controllers/event-info-component-controller.js @@ -284,7 +284,7 @@ export default function init(component) { } function initRepeater(component) { - const repeaters = component.querySelectorAll('.trial-repeater'); + const repeaters = component.querySelectorAll('.repeater-element'); repeaters.forEach((tRepeater) => { const vanillaNode = tRepeater.previousElementSibling.cloneNode(true); tRepeater.addEventListener('click', (event) => { From 8caf4b3cd130342404c6108fcadfa5de694a54d3 Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Tue, 7 May 2024 22:30:39 +0530 Subject: [PATCH 4/8] Minor enhancements --- blocks/event-info-component/event-info-component.js | 2 ++ .../controllers/event-info-component-controller.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/blocks/event-info-component/event-info-component.js b/blocks/event-info-component/event-info-component.js index bd22dc4c..cc9a80e5 100644 --- a/blocks/event-info-component/event-info-component.js +++ b/blocks/event-info-component/event-info-component.js @@ -129,10 +129,12 @@ export default function init(el) { rows.forEach(async (r, i) => { if (i === 1) { await decorateField(r, 'text'); + // Remove after view. addRepeater(r, 'Add event title'); } if (i === 2) { await decorateField(r, 'textarea'); + // Remove after view. addRepeater(r, 'Add event description'); } if (i === 3) decorateDateTimeFields(r); diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 875a58dd..8938dcb9 100644 --- a/blocks/form-handler/controllers/event-info-component-controller.js +++ b/blocks/form-handler/controllers/event-info-component-controller.js @@ -291,9 +291,12 @@ function initRepeater(component) { 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); }); }); From 3c1d0a52e2e0db8692fa10a6167e5d87a5789c6d Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Wed, 8 May 2024 12:41:23 +0530 Subject: [PATCH 5/8] Review comments incorporated --- .../event-info-component.js | 27 +--------------- .../event-info-component-controller.js | 32 +------------------ .../controllers/share-controller.js | 30 +++++++++++++++++ utils/utils.js | 15 +++++++++ 4 files changed, 47 insertions(+), 57 deletions(-) diff --git a/blocks/event-info-component/event-info-component.js b/blocks/event-info-component/event-info-component.js index cc9a80e5..00b9df73 100644 --- a/blocks/event-info-component/event-info-component.js +++ b/blocks/event-info-component/event-info-component.js @@ -1,5 +1,5 @@ import { getLibs } from '../../scripts/utils.js'; -import { getIcon, handlize, generateToolTip } from '../../utils/utils.js'; +import { getIcon, handlize, generateToolTip, addRepeater } from '../../utils/utils.js'; const { createTag } = await import(`${getLibs()}/utils/utils.js`); @@ -38,14 +38,8 @@ async function decorateField(row, type = 'text') { row.innerHTML = ''; component.append(input, attrTextEl); - // TODO Remove after validation. - const deleteButton = createTag('div', { class: 'delete-button' }); - deleteButton.append(getIcon('delete')); - deleteButton.classList.add('hidden'); - const wrapper = createTag('div', { class: 'info-field-wrapper' }); wrapper.append(component); - wrapper.append(deleteButton); row.append(wrapper); } @@ -106,21 +100,6 @@ function decorateDateTimeFields(row) { }); } -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); -} - export default function init(el) { el.classList.add('form-component'); generateToolTip(el); @@ -129,13 +108,9 @@ export default function init(el) { rows.forEach(async (r, i) => { if (i === 1) { await decorateField(r, 'text'); - // Remove after view. - addRepeater(r, 'Add event title'); } if (i === 2) { await decorateField(r, 'textarea'); - // Remove after view. - addRepeater(r, 'Add event description'); } if (i === 3) decorateDateTimeFields(r); }); diff --git a/blocks/form-handler/controllers/event-info-component-controller.js b/blocks/form-handler/controllers/event-info-component-controller.js index 8938dcb9..f98fd7c0 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`); @@ -283,36 +283,6 @@ export default function init(component) { initRemove(component); } -function initRepeater(component) { - const repeaters = component.querySelectorAll('.repeater-element'); - repeaters.forEach((tRepeater) => { - const vanillaNode = tRepeater.previousElementSibling.cloneNode(true); - tRepeater.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(); - }); -} - -function initRemove(component) { - const removeIcons = component.querySelectorAll('.delete-button'); - removeIcons.forEach((removeIcon) => setRemoveEventListener(removeIcon)); -} - export function onResume(component, eventObj, inputMap) { inputMap.forEach((input) => { const element = component.querySelector(input.selector); 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/utils/utils.js b/utils/utils.js index b4b2cd4e..ef41377e 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -61,3 +61,18 @@ export function getIcon(tag) { return img; } + +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); +} \ No newline at end of file From 333b8aeed5b672ab7d45d7e996ec9b20261f2ab9 Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Thu, 9 May 2024 10:19:00 +0530 Subject: [PATCH 6/8] Review comments --- .../event-info-component.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/blocks/event-info-component/event-info-component.js b/blocks/event-info-component/event-info-component.js index 00b9df73..46355b1f 100644 --- a/blocks/event-info-component/event-info-component.js +++ b/blocks/event-info-component/event-info-component.js @@ -1,5 +1,5 @@ import { getLibs } from '../../scripts/utils.js'; -import { getIcon, handlize, generateToolTip, addRepeater } from '../../utils/utils.js'; +import { getIcon, handlize, generateToolTip } from '../../utils/utils.js'; const { createTag } = await import(`${getLibs()}/utils/utils.js`); @@ -34,12 +34,9 @@ async function decorateField(row, type = 'text') { if (maxCharNum) input.setAttribute('maxlength', maxCharNum); - const component = createTag('div'); - row.innerHTML = ''; - component.append(input, attrTextEl); - const wrapper = createTag('div', { class: 'info-field-wrapper' }); - wrapper.append(component); + row.innerHTML = ''; + wrapper.append(input, attrTextEl); row.append(wrapper); } @@ -106,12 +103,8 @@ export default function init(el) { const rows = el.querySelectorAll(':scope > div'); rows.forEach(async (r, i) => { - if (i === 1) { - await decorateField(r, 'text'); - } - if (i === 2) { - await decorateField(r, 'textarea'); - } + if (i === 1) await decorateField(r, 'text'); + if (i === 2) await decorateField(r, 'textarea'); if (i === 3) decorateDateTimeFields(r); }); } From fd0812ec5791f5c6a300313791843a2f662c0f03 Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Thu, 9 May 2024 21:34:03 +0530 Subject: [PATCH 7/8] Review comments --- .../event-info-component.css | 33 ------------------- blocks/form-handler/form-handler.css | 33 +++++++++++++++++++ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/blocks/event-info-component/event-info-component.css b/blocks/event-info-component/event-info-component.css index f8e8292d..7af766f9 100644 --- a/blocks/event-info-component/event-info-component.css +++ b/blocks/event-info-component/event-info-component.css @@ -249,37 +249,4 @@ right: 0 ; background-color: var(--color-info-accent-light); z-index: -1; -} - -.hidden { - display: none; -} - -.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; -} - -.icon-add-circle { - height: 24px; - width: 24px; -} - -.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/blocks/form-handler/form-handler.css b/blocks/form-handler/form-handler.css index 36f2bdd4..b2772782 100644 --- a/blocks/form-handler/form-handler.css +++ b/blocks/form-handler/form-handler.css @@ -196,3 +196,36 @@ min-height: 21px; padding: 7px 18px 8px; } + +.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 From 10fca4fc0d23d5c6a745d675c472bf811891519b Mon Sep 17 00:00:00 2001 From: Gautam Bajaj Date: Thu, 9 May 2024 21:36:42 +0530 Subject: [PATCH 8/8] minor fix --- blocks/event-info-component/event-info-component.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/event-info-component/event-info-component.css b/blocks/event-info-component/event-info-component.css index 7af766f9..5673512c 100644 --- a/blocks/event-info-component/event-info-component.css +++ b/blocks/event-info-component/event-info-component.css @@ -249,4 +249,4 @@ right: 0 ; background-color: var(--color-info-accent-light); z-index: -1; -} \ No newline at end of file +}