Skip to content

Commit

Permalink
required input check fired on repeater generation
Browse files Browse the repository at this point in the history
  • Loading branch information
qiyundai committed May 9, 2024
1 parent 86bcba0 commit a769ed3
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 107 deletions.
7 changes: 4 additions & 3 deletions blocks/event-info-component/event-info-component.js
Original file line number Diff line number Diff line change
@@ -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`);

Expand Down Expand Up @@ -38,6 +38,7 @@ async function decorateField(row, type = 'text') {
row.innerHTML = '';
wrapper.append(input, attrTextEl);
row.append(wrapper);
addRepeater(row, 'add extra title');
}

function buildDatePicker(column) {
Expand Down Expand Up @@ -78,8 +79,8 @@ function buildTimePicker(column) {
select.append(option);
timeSlots.forEach((t) => {
const text = t.textContent.trim();
const option = createTag('option', { value: handlize(text) }, text);
select.append(option);
const opt = createTag('option', { value: handlize(text) }, text);
select.append(opt);
});
timePickerWrapper.append(select);
}
Expand Down
19 changes: 9 additions & 10 deletions blocks/event-materials-component/event-materials-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ async function decorateSWCTextField(row, extraOptions) {
if (!cols.length) return;
const [placeholderCol, maxLengthCol] = cols;
const text = placeholderCol.textContent.trim();

let maxCharNum, attrTextEl;

let maxCharNum; let
attrTextEl;
if (maxLengthCol) {
attrTextEl = createTag('div', { class: 'attr-text' }, maxLengthCol.textContent.trim());
maxCharNum = maxLengthCol.querySelector('strong')?.textContent.trim();
}

const isRequired = attrTextEl?.textContent.trim().endsWith('*');

const input = createTag('sp-textfield', {
...extraOptions, class: 'text-input', placeholder: text
});
const input = createTag('sp-textfield', { ...extraOptions, class: 'text-input', placeholder: text });

if (isRequired) input.required = true;

Expand All @@ -44,7 +43,7 @@ function decorateFileDropzone(row) {
row.classList.add('file-dropzones');
const cols = row.querySelectorAll(':scope > div');
const dropzones = [];

cols.forEach((c, i) => {
c.classList.add('file-dropzone');
const text = c.textContent.trim();
Expand All @@ -53,17 +52,17 @@ function decorateFileDropzone(row) {
const fileInput = createTag('input', { id: inputId, type: 'file', class: 'material-file-input' });
const inputWrapper = createTag('div', { class: 'material-file-input-wrapper' });
const inputLabel = createTag('label', { class: 'material-file-input-label' });

const previewWrapper = createTag('div', { class: 'preview-wrapper hidden' });
const previewImg = createTag('div', { class: 'preview-img-placeholder' });
const previewDeleteButton = getIcon('delete');

previewWrapper.append(previewImg, previewDeleteButton);

inputWrapper.append(previewWrapper, inputLabel);
inputLabel.append(fileInput, getIcon('upload-cloud'), text);
dropzones.push(inputWrapper);
})
});

row.innerHTML = '';
dropzones.forEach((dz) => {
Expand Down
19 changes: 5 additions & 14 deletions blocks/form-handler/controllers/event-info-component-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { getMappedInputsOutput, initRepeater, initRemove } from './share-control
const { createTag } = await import(`${getLibs()}/utils/utils.js`);

function formatDate(date) {
let month = '' + (date.getMonth() + 1),
day = '' + date.getDate(),
year = date.getFullYear();
let month = `${date.getMonth() + 1}`;
let day = `${date.getDate()}`;
const year = date.getFullYear();

if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
if (month.length < 2) month = `0${month}`;
if (day.length < 2) day = `0${day}`;

return [month, day, year].join('-');
}
Expand Down Expand Up @@ -171,13 +169,6 @@ function selectDate(component, state, date) {
}

function updateInput(component, state) {
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
};

const dateInput = component.querySelector('#event-info-date-picker');

dateInput.dataset.startDate = formatDate(state.selectedStartDate);
Expand Down
45 changes: 27 additions & 18 deletions blocks/form-handler/controllers/share-controller.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { yieldToMain } from '../../../utils/utils.js';
import { initRequiredFieldsValidation } from '../form-handler.js';

async function uploadImage(file) {
const formData = new FormData();
formData.append('file', file);
Expand Down Expand Up @@ -26,15 +29,15 @@ function uploadBinaryFile(file) {
// xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onload = function () {
if (xhr.status === 200) {
console.log('Success:', xhr.responseText);
} else {
console.error('Error Status:', xhr.status);
}
if (xhr.status === 200) {
console.log('Success:', xhr.responseText);
} else {
console.error('Error Status:', xhr.status);
}
};

xhr.onerror = function () {
console.error('Network error');
console.error('Network error');
};

xhr.send(file);
Expand Down Expand Up @@ -140,6 +143,12 @@ export default function makeFileInputDropZone(inputWrapper) {
});
}

function setRemoveEventListener(removeElement) {
removeElement.addEventListener('click', (event) => {
event.currentTarget.parentElement.remove();
});
}

export function initRepeater(component) {
const repeaters = component.querySelectorAll('.repeater-element');
repeaters.forEach((element) => {
Expand All @@ -148,24 +157,24 @@ export 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);

const deleteIcon = clonedNode.querySelector('.repeater-delete-button');

if (deleteIcon) {
deleteIcon.classList.remove('hidden');
setRemoveEventListener(deleteIcon);
}

prevNode.after(clonedNode);
yieldToMain().then(() => {
initRequiredFieldsValidation();
});
});
});
}

function setRemoveEventListener(removeElement) {
removeElement.addEventListener('click', (event) => {
event.currentTarget.parentElement.remove();
});
}

export function initRemove(component) {
const removeIcons = component.querySelectorAll('.delete-button');
const removeIcons = component.querySelectorAll('.repeater-delete-button');
removeIcons.forEach((removeIcon) => setRemoveEventListener(removeIcon));
}
29 changes: 12 additions & 17 deletions blocks/form-handler/form-handler.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
.form-handler .side-menu ul li a {
padding-left: 12px;
padding-right: 12px;
color: var(--color-black);
width: 100%;
}

.form-handler .side-menu ul li:not(:has(ul)) {
Expand All @@ -42,11 +44,6 @@
padding-bottom: 8px;
}

.form-handler .side-menu ul li a {
color: var(--color-black);
width: 100%;
}

.form-handler .side-menu ul li:not(:has(ul)):has(a):hover,
.form-handler .side-menu ul li:not(:has(ul)):has(a).active {
background-color: var(--color-red);
Expand Down Expand Up @@ -74,6 +71,10 @@
max-width: var(--grid-container-width);
}

.form-handler .main-frame .section .content {
max-width: none;
}

.form-handler .main-frame .section:first-of-type .content {
margin: 0 24px;
max-width: none;
Expand All @@ -93,10 +94,6 @@
box-shadow: 0 3px 6px 0 rgb(0 0 0 / 16%);
}

.form-handler .main-frame .section .content {
max-width: none;
}

.form-handler .fragment.hidden {
display: none;
}
Expand Down Expand Up @@ -264,10 +261,10 @@
height: var(--spectrum-spacing-700, 48px);
flex-shrink: 0;
border-radius: 10px;
border: 1px dashed var(--Divider, #6E6E6E);
border: 1px dashed var(--color-gray-500);
display: flex;
align-items: center;
padding: 0px 32px;
padding: 0 32px;
margin-bottom: 24px;
}

Expand All @@ -278,12 +275,10 @@

.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";
color: var(--color-gray-500);
font-family: var(--body-font-family);
font-size: 20px;
font-style: normal;
font-weight: 700;
line-height: 24px; /* 125% */
margin: 0px;
}
margin: 0;
}
69 changes: 35 additions & 34 deletions blocks/form-handler/form-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function decorateForm() {

if (!formDivs.length) {
formElement.remove();
return;
return null;
}

formDivs.forEach((formDiv) => {
Expand Down Expand Up @@ -94,7 +94,7 @@ function decorateForm() {
const fragId = `form-step-${fragPathSegments[fragPathSegments.length - 1]}`;
frag.id = fragId;
formState.steps[fragId] = {};
})
});
}
});

Expand Down Expand Up @@ -196,34 +196,54 @@ function updateSideNav() {
}

function validateRequiredFields(fields) {
return fields.length === 0 || Array.from(fields).every((f) => f.value)
return fields.length === 0 || Array.from(fields).every((f) => f.value);
}

function updateCtaStatus() {
const frags = formElement.querySelectorAll('.fragment');
const currentFrag = frags[formState.currentStep];
const stepValid = validateRequiredFields(formState.steps[currentFrag.id].requiredFields);
const ctas = formElement.querySelectorAll('.form-handler-panel-wrapper a');

ctas.forEach((cta) => {
if (cta.classList.contains('back-btn')) {
cta.classList.toggle('disabled', !stepValid || formState.currentStep === 0);
} else {
cta.classList.toggle('disabled', !stepValid);
}
})
});
}

export function initRequiredFieldsValidation() {
const frags = formElement.querySelectorAll('.fragment');
const currentFrag = frags[formState.currentStep];
formState.steps[currentFrag.id].requiredFields = querySelectorAllDeep('input[required], select[required], textarea[required]', currentFrag);
updateCtaStatus()
function querySelectorAllDeep(selector, root = document) {
const elements = [];

function recursiveQuery(r) {
elements.push(...r.querySelectorAll(selector));

r.querySelectorAll('*').forEach((el) => {
if (el.shadowRoot) {
recursiveQuery(el.shadowRoot);
}
});
}

recursiveQuery(root);

return elements;
}

formState.steps[currentFrag.id].requiredFields.forEach((field) => {
field.removeEventListener('change', updateCtaStatus)
field.addEventListener('change', updateCtaStatus, { bubbles: true });
})
export function initRequiredFieldsValidation() {
setTimeout(() => {
const frags = formElement.querySelectorAll('.fragment');
const currentFrag = frags[formState.currentStep];
formState.steps[currentFrag.id].requiredFields = querySelectorAllDeep('input[required], select[required], textarea[required]', currentFrag);
formState.steps[currentFrag.id].requiredFields.forEach((field) => {
field.removeEventListener('change', updateCtaStatus);
field.addEventListener('change', updateCtaStatus, { bubbles: true });
});

updateCtaStatus();
}, 100);
}

function navigateForm(stepIndex = formState.currentStep + 1) {
Expand All @@ -241,7 +261,6 @@ function navigateForm(stepIndex = formState.currentStep + 1) {
frags[prevStep].classList.add('hidden');
frags[formState.currentStep].classList.remove('hidden');


if (formState.currentStep === frags.length - 1) {
nextBtn.textContent = nextBtn.dataset.finalStateText;
} else {
Expand Down Expand Up @@ -356,24 +375,6 @@ async function getInputMap(el) {
return json.data;
}

function querySelectorAllDeep(selector, root = document) {
const elements = [];

function recursiveQuery(root) {
elements.push(...root.querySelectorAll(selector));

root.querySelectorAll('*').forEach(el => {
if (el.shadowRoot) {
recursiveQuery(el.shadowRoot);
}
});
}

recursiveQuery(root);

return elements;
}

function prepopulateForm(inputMap) {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
Expand All @@ -400,7 +401,7 @@ function prepopulateForm(inputMap) {
if (validateRequiredFields(requiredFields)) {
formState.farthestStep = i + 1;
}
})
});

updateSideNav(formElement);
}
Expand Down
Loading

0 comments on commit a769ed3

Please sign in to comment.