diff --git a/src/internal-typings/global.d.ts b/src/internal-typings/global.d.ts index 48b067d2c..ff2db76e7 100644 --- a/src/internal-typings/global.d.ts +++ b/src/internal-typings/global.d.ts @@ -20,6 +20,7 @@ declare namespace Hbspt { target?: string; cssClass?: string; formInstanceId?: string; + onFormReady?: (form: HTMLFormElement) => void; } } diff --git a/src/models/constructor-items/sub-blocks.ts b/src/models/constructor-items/sub-blocks.ts index f90ceb079..5dbd5798e 100644 --- a/src/models/constructor-items/sub-blocks.ts +++ b/src/models/constructor-items/sub-blocks.ts @@ -1,6 +1,10 @@ import {ClassNameProps, QuoteType} from '../../models'; import {ThemeSupporting} from '../../utils'; -import {HubspotEventData, HubspotEventHandlers} from '../../utils/hubspot'; +import { + HubspotEventData, + HubspotEventHandlers, + HubspotFormDefaultValues, +} from '../../utils/hubspot'; import {AnalyticsEventsBase} from '../common'; import {ContentBlockProps} from './blocks'; @@ -103,6 +107,7 @@ export interface HubspotFormProps extends HubspotEventHandlers, AnalyticsEventsB onLoad?: (arg: HubspotEventData) => void; hubspotEvents?: string[]; createDOMElement?: boolean; + defaultValues?: HubspotFormDefaultValues; } //cards diff --git a/src/sub-blocks/HubspotForm/HubspotFormContainer.tsx b/src/sub-blocks/HubspotForm/HubspotFormContainer.tsx index 9c4c7321f..084e46730 100644 --- a/src/sub-blocks/HubspotForm/HubspotFormContainer.tsx +++ b/src/sub-blocks/HubspotForm/HubspotFormContainer.tsx @@ -4,6 +4,7 @@ import {useMount} from '../../hooks'; import {HubspotFormProps} from '../../models'; import loadHubspotScript from './loadHubspotScript'; +import {setHubspotDefaultValues} from './setHubspotDefaultValues'; type HubspotFormContainerPropsKeys = | 'className' @@ -12,7 +13,8 @@ type HubspotFormContainerPropsKeys = | 'portalId' | 'region' | 'formClassName' - | 'createDOMElement'; + | 'createDOMElement' + | 'defaultValues'; type HubspotFormContainerProps = Pick; @@ -27,6 +29,7 @@ const HubspotFormContainer = React.forwardRef(null); @@ -56,6 +59,9 @@ const HubspotFormContainer = React.forwardRef setHubspotDefaultValues(form, defaultValues) + : undefined, }); } } diff --git a/src/sub-blocks/HubspotForm/index.tsx b/src/sub-blocks/HubspotForm/index.tsx index 47bd2a2da..54a94e431 100644 --- a/src/sub-blocks/HubspotForm/index.tsx +++ b/src/sub-blocks/HubspotForm/index.tsx @@ -30,6 +30,7 @@ const HubspotForm = React.forwardRef((props, r onLoad, createDOMElement, onSubmitError, + defaultValues, } = props; const themeValue = useTheme(); @@ -72,6 +73,7 @@ const HubspotForm = React.forwardRef((props, r portalId={portalId} formInstanceId={formInstanceId} region={region} + defaultValues={defaultValues} ref={ref} /> ); diff --git a/src/sub-blocks/HubspotForm/setHubspotDefaultValues.ts b/src/sub-blocks/HubspotForm/setHubspotDefaultValues.ts new file mode 100644 index 000000000..d2dca9246 --- /dev/null +++ b/src/sub-blocks/HubspotForm/setHubspotDefaultValues.ts @@ -0,0 +1,62 @@ +import {HubspotFormDefaultValues} from '../../utils/hubspot'; + +/* eslint-disable no-not-accumulator-reassign/no-not-accumulator-reassign */ +/* eslint-disable no-param-reassign */ + +type HubspotInputValue = HubspotFormDefaultValues[string]; + +const setInputValue = (inputs: HTMLInputElement[], value: HubspotInputValue) => { + const input = inputs[0]; + const type = input.type; + + switch (type) { + case 'checkbox': + input.checked = Boolean(value); + return; + case 'radio': + inputs.forEach((radio) => { + if (radio.value === String(value)) { + input.checked = true; + } + }); + return; + default: + input.value = String(value); + } +}; + +const setSelectValue = (select: HTMLSelectElement, value: HubspotInputValue) => { + const options = Array.from(select.querySelectorAll('option')); + + options.forEach((option) => { + if (option.value === String(value)) { + option.selected = true; + } + }); +}; + +const setValue = (elements: Element[], value: HubspotInputValue) => { + const element = elements[0]; + + switch (element.tagName.toLowerCase()) { + case 'input': + setInputValue(elements as HTMLInputElement[], value); + return; + case 'textarea': + (element as HTMLTextAreaElement).value = String(value); + return; + case 'select': + setSelectValue(element as HTMLSelectElement, value); + return; + } +}; + +export const setHubspotDefaultValues = ( + form: HTMLFormElement, + defaultValues: HubspotFormDefaultValues, +) => { + Object.entries(defaultValues).forEach(([name, value]) => { + const inputs = Array.from(form.querySelectorAll(`[name="${name}"]`)); + setValue(inputs, value); + }); +}; diff --git a/src/utils/hubspot.ts b/src/utils/hubspot.ts index 523da562b..1bac2a7b6 100644 --- a/src/utils/hubspot.ts +++ b/src/utils/hubspot.ts @@ -13,6 +13,8 @@ export interface HubspotEventData { data?: unknown; } +export type HubspotFormDefaultValues = Record; + export function isHubspotEventData(maybeData: unknown): maybeData is HubspotEventData { return ( typeof maybeData === 'object' &&