From bef1356e5bf5db3443f875d4afc163177cca0cff Mon Sep 17 00:00:00 2001 From: M Fahru Date: Thu, 4 Apr 2024 08:24:19 -0700 Subject: [PATCH] [web] Implement new notification style for homepage registration form (#17695) The new notification style is implemented as a separate function (pug mixin), so in order to update all of our forms, we need to explicitly change the function call in the other pug templates. This way, we can update all the other forms with the new notification style gradually. GitOrigin-RevId: 78b755468e3e70f08500bdfb6280fa79853c3ed1 --- .../web/app/views/_mixins/formMessages.pug | 6 ++ .../js/features/form-helpers/hydrate-form.js | 80 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/services/web/app/views/_mixins/formMessages.pug b/services/web/app/views/_mixins/formMessages.pug index 01845a2f59..a9531595cb 100644 --- a/services/web/app/views/_mixins/formMessages.pug +++ b/services/web/app/views/_mixins/formMessages.pug @@ -4,6 +4,12 @@ mixin formMessages() role="alert" ) +mixin formMessagesNewStyle() + div( + data-ol-form-messages-new-style='', + role="alert" + ) + mixin customFormMessage(key, kind) if kind === 'success' div.alert.alert-success( diff --git a/services/web/frontend/js/features/form-helpers/hydrate-form.js b/services/web/frontend/js/features/form-helpers/hydrate-form.js index 54d67dcafb..99c6c8160e 100644 --- a/services/web/frontend/js/features/form-helpers/hydrate-form.js +++ b/services/web/frontend/js/features/form-helpers/hydrate-form.js @@ -80,7 +80,10 @@ function formSubmitHelper(formEl) { // Let the user re-submit the form. formEl.dispatchEvent(new Event('idle')) } finally { + // call old and new notification builder functions + // but only one will be rendered showMessages(formEl, messageBag) + showMessagesNewStyle(formEl, messageBag) } }) } @@ -126,6 +129,8 @@ function hideFormElements(formEl) { } } +// TODO: remove the showMessages function after every form alerts are updated to use the new style +// TODO: rename showMessagesNewStyle to showMessages after the above is done function showMessages(formEl, messageBag) { const messagesEl = formEl.querySelector('[data-ol-form-messages]') if (!messagesEl) return @@ -192,6 +197,81 @@ function showMessages(formEl, messageBag) { }) } +function showMessagesNewStyle(formEl, messageBag) { + const messagesEl = formEl.querySelector('[data-ol-form-messages-new-style]') + if (!messagesEl) return + + // Clear content + messagesEl.textContent = '' + formEl.querySelectorAll('[data-ol-custom-form-message]').forEach(el => { + el.hidden = true + }) + + // Render messages + messageBag.forEach(message => { + const customErrorElements = message.key + ? formEl.querySelectorAll( + `[data-ol-custom-form-message="${message.key}"]` + ) + : [] + if (message.key && customErrorElements.length > 0) { + // Found at least one custom error element for key, show them + customErrorElements.forEach(el => { + el.hidden = false + }) + } else { + // No custom error element for key on page, append a new error message + const messageElContainer = document.createElement('div') + messageElContainer.className = classNames( + 'notification', + 'text-centered', + { + 'notification-type-error': message.type === 'error', + 'notification-type-success': message.type !== 'error', + } + ) + const messageEl = document.createElement('div') + + messageEl.className = 'notification-content' + messageEl.textContent = message.text || `Error: ${message.key}` + messageEl.setAttribute('aria-live', 'assertive') + messageEl.setAttribute( + 'role', + message.type === 'error' ? 'alert' : 'status' + ) + if (message.hints && message.hints.length) { + const listEl = document.createElement('ul') + message.hints.forEach(hint => { + const listItemEl = document.createElement('li') + listItemEl.textContent = hint + listEl.append(listItemEl) + }) + messageEl.append(listEl) + } + + messageElContainer.appendChild(messageEl) + messagesEl.append(messageElContainer) + } + if (message.key) { + // Hide the form elements on specific message types + const hideOnError = formEl.attributes['data-ol-hide-on-error'] + if ( + hideOnError && + hideOnError.value && + hideOnError.value.match(message.key) + ) { + hideFormElements(formEl) + } + // Hide any elements with specific `data-ol-hide-on-error-message` message + document + .querySelectorAll(`[data-ol-hide-on-error-message="${message.key}"]`) + .forEach(el => { + el.hidden = true + }) + } + }) +} + export function inflightHelper(el) { const disabledInflight = el.querySelectorAll('[data-ol-disabled-inflight]') const showWhenNotInflight = el.querySelectorAll('[data-ol-inflight="idle"]')