feat(forms): add isolated Form A iframe adapter
This commit is contained in:
18 files changed
+1345
-170
No files matched your search
@@ -6,6 +6,8 @@ The CSS translates the existing AIA form treatment: Rubik typography, blue label
|
||||
|
||||
The selectors target Jotform Classic Forms identifiers such as `#form`, `.form-all`, `.form-line`, `.form-label`, `.form-sub-label`, `.form-required`, `.form-textbox`, `.form-dropdown`, `.form-textarea`, `.form-error-message`, and `.form-submit-button`. Jotform's final generated DOM must be checked in the account before relying on pixel-level parity. The stylesheet does not hide required indicators, error messages, honeypots, or focus outlines, and it does not request fonts or other external assets.
|
||||
|
||||
The current Builder theme reconciliation adds narrowly scoped `!important` declarations to the outer surface, labels, inputs, and submit-button treatments that Jotform's generated theme otherwise overrides. Error, required-indicator, and focus rules remain visible and are deliberately not reset. The account owner must still confirm the final generated DOM and rendered form after any Jotform theme or field change.
|
||||
|
||||
## Installation and comparison
|
||||
|
||||
1. Create or open the approved blank Form A in AIA's HIPAA-enabled Jotform account.
|
||||
@@ -17,6 +19,29 @@ The selectors target Jotform Classic Forms identifiers such as `#form`, `.form-a
|
||||
|
||||
The current Astro meeting preview remains `off` by default and can only be shown in a non-indexing mock build. It does not load Jotform and is not a live submission test.
|
||||
|
||||
## Isolated Form A iframe adapter
|
||||
|
||||
The Astro adapter exists only for a separately approved, non-indexing isolated test. It can render Form A at the two contact routes and five explicitly allowlisted landing routes when **all** of the following are set at build time:
|
||||
|
||||
```sh
|
||||
PUBLIC_AIA_FORMS_MODE=isolated-test
|
||||
PUBLIC_AIA_FORMS_ENVIRONMENT=isolated-test
|
||||
PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED=true
|
||||
PUBLIC_ALLOW_INDEXING=false
|
||||
```
|
||||
|
||||
It uses fixed allowlisted hosted URLs only: the contact routes use `formContext=contact` with their fixed English or Spanish language value, and the five landing routes use `formContext=landing&language=en`. `formContext` is the exact case-sensitive Jotform Unique Name supplied by the owner; it is presentation-only and does not accept visitor query values. A missing gate, any other environment role, an indexing-enabled build, a route outside that seven-route allowlist, or `live` mode renders the normal fail-closed Astro fallback instead.
|
||||
|
||||
The adapter has a localized iframe title, a fixed-height responsive frame, a `no-referrer` policy, a minimal sandbox, and a direct hosted-form fallback. It loads no Jotform helper script, reads no iframe DOM, and treats no frame load as a submission or conversion. The disabled Form A must undergo owner-authorized synthetic EN/ES testing before the isolated adapter or its fixed height can be accepted for a live workflow.
|
||||
|
||||
### Landing-route extension — 2026-10-25 / 2026-10-26
|
||||
|
||||
The owner has extended this same **isolated-test-only** adapter to `/lp/aba-therapy`, `/lp/aba-insurance`, `/lp/aba-ahcccs`, `/lp/aba-private-pay`, and `/lp/early-intervention`. Those five English landing routes use the fixed URL parameter pair `formContext=landing&language=en`; the contact routes continue to use `formContext=contact` with their fixed page locale. This supersedes their earlier Form B mapping. Form B remains for the other service-consultation journeys.
|
||||
|
||||
The campaign adapter uses the existing campaign form surface rather than creating a second card. Its native Jotform Submit label is not overridden by Astro. The current sandbox is deliberately limited to `allow-forms allow-scripts allow-same-origin`, which is the minimum anticipated set for Jotform validation and in-frame confirmation. It intentionally does not grant popups, modals, top navigation, downloads, or a feature-policy `allow` list. Owner-authorized synthetic acceptance must confirm the real form's validation, confirmation, and any required in-frame navigation before this sandbox can be accepted for production.
|
||||
|
||||
The versioned P9-03 contract and implementation plan must record this owner decision and reconcile the superseded campaign mapping without erasing the prior decision history. Keep any documentation PR review aligned with those versioned records.
|
||||
|
||||
## Form context and button labels
|
||||
|
||||
The current Form A design uses a hidden `formContext` value with fixed, approved values such as `contact` and `landing`. Jotform does not provide a native conditional rule that changes one Submit button's accessible label safely in every context. If owner-approved context-specific labels are required, use multiple native Jotform Submit buttons and Jotform's conditional visibility rules:
|
||||
@@ -28,7 +53,7 @@ The current Form A design uses a hidden `formContext` value with fixed, approved
|
||||
- Make the no-context and invalid-context states fail closed: no ambiguous extra button and no unintended submission path.
|
||||
- Verify keyboard order, focus visibility, screen-reader names, English/Spanish labels, and mobile layout for every variant.
|
||||
|
||||
The four campaign pages remain mapped to Form B in the production architecture. Their current Form A mock override is temporary meeting-preview behavior only. Do not add an external Astro button that attempts to submit a cross-origin iframe.
|
||||
The owner-approved Form A landing extension applies only to `/lp/aba-therapy`, `/lp/aba-insurance`, `/lp/aba-ahcccs`, `/lp/aba-private-pay`, and `/lp/early-intervention`, using its fixed `landing` context under the isolated-test gate. Form B remains the planned form for the other service-consultation journeys. No Form A landing placement is approved for live production activation. Do not add an external Astro button that attempts to submit a cross-origin iframe.
|
||||
|
||||
## Verification checklist
|
||||
|
||||
|
||||
@@ -1,192 +1,252 @@
|
||||
/*
|
||||
* AIA Form A — Jotform Classic Forms custom CSS
|
||||
*
|
||||
* Paste into Jotform Form Designer > Styles > Inject Custom CSS after
|
||||
* creating the approved Form A. These selectors are scoped to Jotform's
|
||||
* Classic Forms structure and do not replace Jotform validation or controls.
|
||||
* Validate the final generated form DOM before activation; no account access
|
||||
* or pixel-perfect Jotform comparison was performed for this artifact.
|
||||
*/
|
||||
/* ==========================================================
|
||||
AIA FORM A — JOTFORM CUSTOM CSS
|
||||
Form ID: 262946078314059
|
||||
Maximum form width: 640px
|
||||
========================================================== */
|
||||
|
||||
/* The Astro page supplies the surrounding heading, copy, privacy link and
|
||||
card. Keep the iframe's own surface quiet so it does not create a second
|
||||
card inside the page's existing form container. */
|
||||
#form,
|
||||
#form .form-all {
|
||||
background: #fff;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
/* Document and language selector */
|
||||
|
||||
html.supernova,
|
||||
html.supernova body,
|
||||
body.supernova {
|
||||
background: #fff !important;
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
/* Avoid horizontal overflow, including on the thank-you page */
|
||||
body {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* Confirmation page styling */
|
||||
body.thankyou,
|
||||
body.thankyou #stage {
|
||||
background: #fff !important;
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
.jfLangDd.jfLangDd--match-form {
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
|
||||
/* Form container */
|
||||
|
||||
form[id="262946078314059"] {
|
||||
width: 100% !important;
|
||||
max-width: 640px !important;
|
||||
margin: 8px auto !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-all {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
background: #fff !important;
|
||||
border: 0 !important;
|
||||
box-shadow: none !important;
|
||||
color: #254080;
|
||||
font-family: Rubik, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.form-all .form-section {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Field layout */
|
||||
|
||||
.form-all .form-line {
|
||||
margin: 0 !important;
|
||||
padding: 0 0 21px !important;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.form-all .form-input-wide {
|
||||
margin-top: 0 !important;
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
/* Labels and sublabels */
|
||||
|
||||
.form-all .form-label,
|
||||
.form-all .form-label-left,
|
||||
.form-all .form-label-right,
|
||||
.form-all .form-label-top {
|
||||
color: #254080 !important;
|
||||
font-size: .875rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.35 !important;
|
||||
margin: 0 0 6px !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.form-all .form-sub-label {
|
||||
color: #254080;
|
||||
font-size: .75rem;
|
||||
line-height: 1.3 !important;
|
||||
margin: 4px 0 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.form-all .form-sub-label-container {
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.form-all .form-required {
|
||||
color: #a21c28 !important;
|
||||
margin-left: .2rem;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Inputs */
|
||||
|
||||
.form-all input.form-textbox,
|
||||
.form-all select.form-dropdown,
|
||||
.form-all textarea.form-textarea {
|
||||
background: #fcf9f5 !important;
|
||||
background-image: none !important;
|
||||
border: 1px solid #edeef3 !important;
|
||||
border-radius: 4px !important;
|
||||
box-shadow: none !important;
|
||||
box-sizing: border-box;
|
||||
color: #254080 !important;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
line-height: 1.4;
|
||||
min-height: 2.75rem;
|
||||
padding: .55rem .7rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#form .form-all {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* Preserve two-column name fields */
|
||||
|
||||
.form-all .form-sub-label-container input.form-textbox {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
#form .form-line {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0 0 1rem;
|
||||
/* Full-width phone and email fields */
|
||||
|
||||
.form-all
|
||||
.form-line:is(
|
||||
[data-type="control_phone"],
|
||||
[data-type="control_email"]
|
||||
)
|
||||
:is(.form-input, .form-input-wide, input.form-textbox) {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
#form .form-label,
|
||||
#form .form-label-left,
|
||||
#form .form-label-right,
|
||||
#form .form-label-top {
|
||||
color: #254080;
|
||||
font-size: .9rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
margin: 0 0 .4rem;
|
||||
padding: 0;
|
||||
}
|
||||
/* Message field */
|
||||
|
||||
#form .form-sub-label {
|
||||
color: #254080;
|
||||
font-size: .78rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
#form .form-required {
|
||||
color: #a21c28;
|
||||
margin-left: .2rem;
|
||||
}
|
||||
|
||||
#form input.form-textbox,
|
||||
#form input.form-textbox.form-phone,
|
||||
#form input.form-textbox.form-email,
|
||||
#form select.form-dropdown,
|
||||
#form textarea.form-textarea {
|
||||
background: #fcf9f5;
|
||||
border: 1px solid #edeef3;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
color: #254080;
|
||||
font: inherit;
|
||||
line-height: 1.5;
|
||||
min-height: 2.9rem;
|
||||
padding: .7rem .8rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#form textarea.form-textarea {
|
||||
min-height: 7rem;
|
||||
.form-all textarea.form-textarea {
|
||||
width: 100% !important;
|
||||
min-height: 5.5rem !important;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
#form input.form-textbox:focus-visible,
|
||||
#form select.form-dropdown:focus-visible,
|
||||
#form textarea.form-textarea:focus-visible,
|
||||
#form input[type='radio']:focus-visible + label,
|
||||
#form input[type='checkbox']:focus-visible + label,
|
||||
#form .form-submit-button:focus-visible {
|
||||
outline: 3px solid #115bbd;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
/* Radio buttons and checkboxes */
|
||||
|
||||
#form .form-line.form-line-error input.form-textbox,
|
||||
#form .form-line.form-line-error select.form-dropdown,
|
||||
#form .form-line.form-line-error textarea.form-textarea {
|
||||
border-color: #a21c28;
|
||||
outline: 2px solid #a21c28;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
#form .form-error-message,
|
||||
#form .form-line-error .form-error-message {
|
||||
color: #a21c28;
|
||||
font-size: .85rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
margin: .45rem 0 0;
|
||||
}
|
||||
|
||||
#form .form-radio-item,
|
||||
#form .form-checkbox-item {
|
||||
.form-all .form-radio-item,
|
||||
.form-all .form-checkbox-item {
|
||||
color: #254080;
|
||||
line-height: 1.5;
|
||||
margin: 0 1rem .5rem 0;
|
||||
line-height: 1.4;
|
||||
margin: 0 .75rem .2rem 0 !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#form .form-radio,
|
||||
#form .form-checkbox {
|
||||
.form-all .form-radio,
|
||||
.form-all .form-checkbox {
|
||||
accent-color: #254080;
|
||||
}
|
||||
|
||||
#form .form-buttons-wrapper {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
margin: .25rem 0 0;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
/* Submit button and wrapper */
|
||||
|
||||
.form-all .jf-form-buttons,
|
||||
.form-all .form-buttons-wrapper {
|
||||
box-sizing: border-box;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
#form .form-submit-button,
|
||||
#form button[type='submit'] {
|
||||
background: #ffbd59;
|
||||
border: 2px solid #ffbd59;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
color: #254080;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
.form-all .form-submit-button,
|
||||
.form-all button[type="submit"] {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-height: 3rem;
|
||||
padding: .65rem 1.2rem;
|
||||
transition: .3s linear all;
|
||||
width: 100%;
|
||||
background: #ffbd59 !important;
|
||||
background-image: none !important;
|
||||
border: 2px solid #ffbd59 !important;
|
||||
border-radius: 4px !important;
|
||||
box-shadow: none !important;
|
||||
color: #254080 !important;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
text-shadow: none !important;
|
||||
transition: background .3s linear, border-color .3s linear;
|
||||
}
|
||||
|
||||
#form .form-submit-button:hover,
|
||||
#form .form-submit-button:focus-visible,
|
||||
#form button[type='submit']:hover,
|
||||
#form button[type='submit']:focus-visible {
|
||||
background: transparent;
|
||||
border-color: #ff914d;
|
||||
color: #254080;
|
||||
.form-all .form-submit-button:hover,
|
||||
.form-all button[type="submit"]:hover {
|
||||
background: transparent !important;
|
||||
border-color: #ff914d !important;
|
||||
color: #254080 !important;
|
||||
}
|
||||
|
||||
#form .form-submit-button:disabled,
|
||||
#form button[type='submit']:disabled {
|
||||
.form-all .form-submit-button:disabled,
|
||||
.form-all button[type="submit"]:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: .65;
|
||||
}
|
||||
|
||||
/* Jotform error and required content must remain visible. Do not hide these
|
||||
classes in a campaign-specific override. */
|
||||
#form .form-validation-error,
|
||||
#form .form-required,
|
||||
#form .form-error-message {
|
||||
/* Keyboard focus */
|
||||
|
||||
.form-all input.form-textbox:focus-visible,
|
||||
.form-all select.form-dropdown:focus-visible,
|
||||
.form-all textarea.form-textarea:focus-visible,
|
||||
.form-all input[type="radio"]:focus-visible,
|
||||
.form-all input[type="checkbox"]:focus-visible,
|
||||
.form-all .form-submit-button:focus-visible {
|
||||
outline: 3px solid #115bbd !important;
|
||||
outline-offset: -3px;
|
||||
}
|
||||
|
||||
/* Validation */
|
||||
|
||||
.form-all .form-line-error input.form-textbox,
|
||||
.form-all .form-line-error select.form-dropdown,
|
||||
.form-all .form-line-error textarea.form-textarea,
|
||||
.form-all input.form-validation-error {
|
||||
border-color: #a21c28 !important;
|
||||
}
|
||||
|
||||
.form-all .form-error-message,
|
||||
.form-all .form-line-error .form-error-message {
|
||||
color: #a21c28 !important;
|
||||
font-size: .8rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
margin: .3rem 0 0 !important;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
#form .form-line,
|
||||
#form .form-label,
|
||||
#form .form-label-left,
|
||||
#form .form-label-right,
|
||||
#form .form-label-top {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#form .form-all {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#form .form-submit-button,
|
||||
#form button[type='submit'] {
|
||||
min-height: 3rem;
|
||||
}
|
||||
}
|
||||
/* Accessibility: reduced motion */
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
#form .form-submit-button,
|
||||
#form button[type='submit'] {
|
||||
.form-all .form-submit-button,
|
||||
.form-all button[type="submit"] {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user