fix: hide required asterisk on optional Marketo fields - #3969
marcklingen wants to merge 2 commits into
Conversation
The Talk to us form CSS forced every .mktoAsterix to display, so optional fields such as Phone looked required. Hide the native asterisk unless Marketo marks the field with .mktoRequiredField, and suppress the ThemeStyleOverride ::after so required labels do not get two marks. Co-authored-by: Marc Klingen <marcklingen@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The page CSS required .mktoForm, which is not always on the loaded <form>, so Marketo's later display:contents rule still showed every asterisk. Target form[id^=mktoForm_] and hide optional marks from .mktoRequiredField after render so IsRequired wins. Co-authored-by: Marc Klingen <marcklingen@users.noreply.github.com>
|
@claude review |
There was a problem hiding this comment.
Claude Code Review
No review was started: this request came from a bot account. Manual reviews can only be requested by someone with write access to this repository. Ask a maintainer to comment @claude review, or have your automation post the comment from a user account with write access.
Tip: disable this comment in your organization's Code Review settings.
| const renderedForm = document.getElementById(MARKETO_FORM_ELEMENT_ID); | ||
| if (renderedForm) { | ||
| applyRequiredAsterisks(renderedForm); |
There was a problem hiding this comment.
The existing sales-completion test mocks the form with replaceChildren() but no querySelectorAll(). When its mocked loadForm calls this callback, applyRequiredAsterisks throws before the success handler is registered. As a result, the documented analytics validation command fails. Update the test fixture to support the new DOM access and check required and optional asterisks.
Prompt To Fix With AI
This is a comment left during a code review.
Path: components/MarketoContactForm.tsx
Line: 87-89
Comment:
**Marketo analytics test breaks**
The existing sales-completion test mocks the form with `replaceChildren()` but no `querySelectorAll()`. When its mocked `loadForm` calls this callback, `applyRequiredAsterisks` throws before the success handler is registered. As a result, the documented analytics validation command fails. Update the test fixture to support the new DOM access and check required and optional asterisks.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Beyond the inline finding already reported, I also checked whether a field that becomes required after the initial Marketo render (e.g. State becoming required when Country=US, via Marketo's dependency rules) would be left with a stale asterisk — it can, since applyRequiredAsterisks only runs once in the loadForm callback, but this is cosmetic only: Marketo's own validation logic (not the asterisk's CSS/inline display) is what actually enforces the required field, so it does not affect form correctness.
Extended reasoning...
The change touches components/MarketoContactForm.tsx (adds a one-time post-render pass that force-sets inline display on Marketo's .mktoAsterix elements based on .mktoRequiredField ancestry) and style.css (stops force-showing every asterisk, defaults to hidden, and suppresses a duplicate ThemeStyleOverride asterisk). It touches no auth, injection, or data-exposure surface — purely form-field display logic. A confirmed finding (the new querySelectorAll call breaks the documented analytics test's Marketo DOM mock) is already being posted as an inline comment, so this body only adds a separately examined and ruled-out cosmetic edge case rather than repeating it.
| const renderedForm = document.getElementById(MARKETO_FORM_ELEMENT_ID); | ||
| if (renderedForm) { | ||
| applyRequiredAsterisks(renderedForm); |
There was a problem hiding this comment.
🔴 Running the project's documented validation test now fails instead of passing, because the new DOM call needs more than the test's existing mock provides. applyRequiredAsterisks(renderedForm) at MarketoContactForm.tsx:89 calls renderedForm.querySelectorAll('.mktoAsterix') (line 36), but scripts/test-use-case-analytics.mjs mocks document.getElementById to return only { replaceChildren() {} }, with no querySelectorAll. That throws a TypeError inside the Forms2 load callback, failing the 'sales completion is emitted only after Marketo success and is deduplicated' test that node --test scripts/test-use-case-analytics.mjs runs as validation. Fix: make applyRequiredAsterisks tolerate/feature-detect elements without querySelectorAll, or update the test's getElementById stub to expose it, so the existing regression test keeps passing.
Why this was flagged
scripts/test-use-case-analytics.mjs sets globalThis.document = { getElementById: () => ({ replaceChildren() {} }) } for the 'sales completion is emitted only after Marketo success and is deduplicated' test, which is the documented validation command per scripts/analytics/README.md:80. On the base branch the Forms2 load callback only called setIsFormLoaded/form.onSuccess, so the stub was sufficient. After this diff, MarketoContactForm.tsx:87-90 re-fetches the element via document.getElementById and passes it to applyRequiredAsterisks, which calls .querySelectorAll('.mktoAsterix') at line 36 — a method the stub lacks. The call throws synchronously inside the test body, which node:test reports as a failure where the test previously passed. Nothing in the new code checks that the element supports querySelectorAll before using it.
Verification: The diff adds a new synchronous call inside the Forms2 load callback that the documented validation test cannot satisfy, turning a passing test into a failing one. In scripts/test-use-case-analytics.mjs:472, the DOM stub is { getElementById: () => ({ replaceChildren() {} }) }, with no querySelectorAll. MarketoContactForm.tsx:87-90 calls applyRequiredAsterisks(renderedForm), which at line 36 calls renderedForm.querySelectorAll(".mktoAsterix"), throwing a TypeError.
Problem
On
/talk-to-us(Get a demo / Talk to us), every Marketo field showed a red required asterisk — including Mobile Phone, which the form descriptor marks as optional (IsRequiredis absent; Email/Company/etc. haveIsRequired: true).Root cause
Marketo Forms2 always emits a
.mktoAsterixin every label. Its default stylesheet hides it unless the field wrap has.mktoRequiredField(set from the descriptor’sIsRequired: true).Two overrides undid that:
.lf-marketo-form .mktoAsterix { display: inline !important }, so every field looked required..lf-marketo-form .mktoAsterix { display: contents !important }after page CSS. A first fix that required a.mktoFormancestor still lost, because that class is not on the loaded<form>.Fix
.mktoAsterixunless the field is in.mktoRequiredField.form[id^="mktoForm_"]so the rule is more specific than ThemeStyleOverride and does not depend on.mktoForm.::afterso required labels do not get two asterisks.IsRequired→.mktoRequiredFieldmapping with an inlinedisplayso later-injected Marketo CSS cannot unhide optional marks.Verification
On local
/talk-to-usafter the form loaded:mktoRequiredFieldabsent, computeddisplay: none, no red asterisk.display: inline.The PR should not merge until the documented Marketo analytics test runs successfully again.
Summary
The PR updates the Talk to Us form to hide optional-field asterisks while retaining required-field indicators.
Reviews (1) · Last reviewed commit: "fix: beat Marketo ThemeStyleOverride on ..."