Skip to content

fix: hide required asterisk on optional Marketo fields - #3969

Open
marcklingen wants to merge 2 commits into
mainfrom
cursor/fix-marketo-optional-asterisk-0081
Open

marcklingen wants to merge 2 commits into
mainfrom
cursor/fix-marketo-optional-asterisk-0081

Conversation

@marcklingen

@marcklingen marcklingen commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

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 (IsRequired is absent; Email/Company/etc. have IsRequired: true).

Root cause

Marketo Forms2 always emits a .mktoAsterix in every label. Its default stylesheet hides it unless the field wrap has .mktoRequiredField (set from the descriptor’s IsRequired: true).

Two overrides undid that:

  1. Our page CSS used .lf-marketo-form .mktoAsterix { display: inline !important }, so every field looked required.
  2. The Marketo form ThemeStyleOverride injects .lf-marketo-form .mktoAsterix { display: contents !important } after page CSS. A first fix that required a .mktoForm ancestor still lost, because that class is not on the loaded <form>.

Fix

  • Hide .mktoAsterix unless the field is in .mktoRequiredField.
  • Select form[id^="mktoForm_"] so the rule is more specific than ThemeStyleOverride and does not depend on .mktoForm.
  • Suppress the ThemeStyleOverride ::after so required labels do not get two asterisks.
  • After Forms2 renders, apply the same IsRequired → .mktoRequiredField mapping with an inline display so later-injected Marketo CSS cannot unhide optional marks.
  • No hardcoded “Phone is optional”. Form IDs, field names, and submit behavior are unchanged.

Verification

On local /talk-to-us after the form loaded:

  • Phone: mktoRequiredField absent, computed display: none, no red asterisk.
  • First name, Last name, Work email, Company Name, and other required fields: single red asterisk, display: inline.
  • Empty submit: Phone stays valid; required fields are marked invalid. Marketo did not treat Phone as required.

Talk to us form after the fix: Mobile Phone has no required asterisk, other fields still do

Open in Web Open in Cursor 

RetriggerConfidence Score: 4/5

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.

  • It adds form-scoped CSS and a render-time inline-style adjustment.
  • The new DOM access breaks the existing Marketo sales-completion test fixture.

Reviews (1) · Last reviewed commit: "fix: beat Marketo ThemeStyleOverride on ..."

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>
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
langfuse-docs Ready Ready Preview Oct 5, 2026 8:24pm UTC

Request Review

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>
@marcklingen
marcklingen marked this pull request as ready for review October 6, 2026 08:10
@marcklingen
marcklingen enabled auto-merge October 6, 2026 08:10
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

@claude review

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +87 to +89
const renderedForm = document.getElementById(MARKETO_FORM_ELEMENT_ID);
if (renderedForm) {
applyRequiredAsterisks(renderedForm);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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.

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.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +87 to +89
const renderedForm = document.getElementById(MARKETO_FORM_ELEMENT_ID);
if (renderedForm) {
applyRequiredAsterisks(renderedForm);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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.

This branch was successfully deployed

1 active deployment
Preview — 017c2bd8 Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants