@oneblink/apps-react
    Preparing search index...

    Variable OneBlinkFormControlledConst

    OneBlinkFormControlled: NamedExoticComponent<
        OneBlinkReadOnlyFormProps & {
            abnLookupAuthenticationGuid?: string;
            attachmentRetentionInDays?: number;
            buttons?: {
                cancel?: ButtonConfiguration;
                cancelPromptNo?: ButtonConfiguration;
                cancelPromptYes?: ButtonConfiguration;
                saveDraft?: ButtonConfiguration;
                submit?: ButtonConfiguration;
            };
            captchaSiteKey?: string;
            captchaType?: CaptchaType;
            disabled?: boolean;
            getCurrentSubmissionDuration?: () => number;
            handleNavigateAway?: () => unknown;
            isInfoPage?: "YES" | "NO" | "CALCULATED";
            isPendingQueueEnabled: boolean;
            isPreview?: boolean;
            navigableValidationErrorsNotificationSettings?: {
                navigationTopOffset?: number;
                scrollableContainerId?: string;
            };
            onBeforeUnload?: (
                props: {
                    definition: Form;
                    lastElementUpdated: FormElement | undefined;
                    submission: { [name: string]: unknown };
                    submissionDuration: number | undefined;
                },
            ) => void;
            onCancel: () => unknown;
            onSaveDraft?: (newDraftSubmission: NewDraftSubmission) => unknown;
            onSubmit: (newFormSubmission: NewFormSubmission) => unknown;
            onUploadAttachment?: (
                options: UploadAttachmentConfiguration,
                abortSignal?: AbortSignal,
            ) => Promise<FormSubmissionAttachment>;
            scrollToTopOfPage?: boolean;
            shouldUseNavigableValidationErrorsNotification?: boolean;
            validationIcon?: { accessibleLabel?: string; icon: string };
        } & OneBlinkFormControlledProps,
    > = ...

    Similar to OneBlinkForm, however requires props to control the definition and submission values.

    import React from 'react'
    import ReactDOM from 'react-dom'
    import { FormTypes } from '@oneblink/types'
    import {
    OneBlinkAppsError,
    draftService,
    submissionService,
    IsOfflineContextProvider,
    OneBlinkFormControlled,
    useIsMounted,
    useFormSubmissionState,
    } from '@oneblink/apps-react'
    import '@oneblink/apps-react/dist/styles.css'

    const captchaSiteKey = 'ENTER_YOUR_SITE_KEY_HERE'
    const googleMapsApiKey = 'ENTER_YOUR_MAPS_API_KEY_HERE'
    const formsAppId = 1
    const form: FormTypes.Form = {
    id: 1,
    name: 'Name of Form',
    description: '',
    organisationId: 'abc123',
    formsAppEnvironmentId: 1,
    formsAppIds: [],
    elements: [],
    isAuthenticated: false,
    isMultiPage: false,
    isInfoPage: false,
    publishStartDate: null,
    publishEndDate: null,
    postSubmissionAction: 'FORMS_LIBRARY',
    submissionEvents: [],
    tags: [],
    }
    const initialSubmission: Record<string, unknown> = {
    data: 1,
    }

    function FormContainer() {
    const isMounted = useIsMounted()

    const [{ definition, submission }, setFormSubmission] =
    useFormSubmissionState(form, initialSubmission)

    const [{ isSavingDraft, saveDraftError }, setSaveDraftState] =
    React.useState({
    isSavingDraft: false,
    saveDraftError: null,
    })

    const [
    { isSubmitting, submitError, formSubmissionResult },
    setSubmitState,
    ] = React.useState({
    formSubmissionResult: null,
    isSubmitting: false,
    submitError: null,
    })

    const handleSubmit = React.useCallback(
    async (newFormSubmission: FormTypes.NewFormSubmission) => {
    const formSubmission: FormSubmission = Object.assign(
    {},
    newFormSubmission,
    {
    formsAppId,
    jobId: null,
    externalId: null,
    draftId: null,
    preFillFormDataId: null,
    },
    )

    setSubmitState({
    formSubmissionResult: null,
    submitError: null,
    isSubmitting: true,
    })

    try {
    const newFormSubmissionResult = await submissionService.submit({
    formSubmission,
    })
    if (
    newFormSubmissionResult.isOffline &&
    !newFormSubmissionResult.isInPendingQueue
    ) {
    throw new OneBlinkAppsError(
    'You cannot submit this form while offline, please try again when connectivity is restored.',
    {
    isOffline: true,
    },
    )
    }

    if (isMounted.current) {
    setSubmitState({
    formSubmissionResult: newFormSubmissionResult,
    isSubmitting: false,
    submitError: null,
    })
    }
    } catch (error) {
    if (isMounted.current) {
    setSubmitState({
    formSubmissionResult: null,
    isSubmitting: false,
    submitError: error,
    })
    }
    }
    },
    [isMounted],
    )

    const handleSaveDraft = React.useCallback(
    async (newDraftSubmission: FormTypes.NewDraftSubmission) => {
    const draftSubmission: FormTypes.DraftSubmission = {
    ...newDraftSubmission,
    formsAppId,
    }
    setSaveDraftState({
    saveDraftError: null,
    isSavingDraft: true,
    })

    try {
    await draftService.addDraft(
    {
    title: form.name,
    formId: form.id,
    externalId: null,
    jobId: null,
    },
    draftSubmission,
    )

    if (isMounted.current) {
    setSaveDraftState({
    saveDraftError: null,
    isSavingDraft: false,
    })
    }
    } catch (error) {
    if (isMounted.current) {
    setSaveDraftState({
    saveDraftError: error,
    isSavingDraft: false,
    })
    }
    }
    },
    [isMounted],
    )

    const handleCancel = React.useCallback(() => {
    // handle cancel here...
    }, [])

    if (isSubmitting) {
    // Render submitting animation/loading
    }

    if (submitError) {
    // Render error while submitting
    }

    if (isSavingDraft) {
    // Render saving draft animation/loading
    }

    if (saveDraftError) {
    // Render error while saving draft
    }

    if (formSubmissionResult) {
    // Render submission success
    }

    return (
    <OneBlinkFormControlled
    captchaSiteKey={captchaSiteKey}
    googleMapsApiKey={googleMapsApiKey}
    formsAppId={formsAppId}
    definition={definition}
    submission={submission}
    setFormSubmission={setFormSubmission}
    onCancel={handleCancel}
    onSubmit={handleSubmit}
    onSaveDraft={handleSaveDraft}
    />
    )
    }

    function App() {
    return (
    <IsOfflineContextProvider>
    <FormContainer />
    </IsOfflineContextProvider>
    )
    }

    const root = document.getElementById('root')
    if (root) {
    ReactDOM.render(<App />, root)
    }

    The OneBlinkAutoSaveForm component does not offer props to allow for a controlled form (i.e. having access to submission and definition values). To implement a controlled version of the <OneBlinkAutoSaveForm /> component, use the example component below.

    import * as React from 'react'
    import {
    OneBlinkAutoSaveForm,
    OneBlinkFormControlled,
    useFormSubmissionAutoSaveState,
    } from '@oneblink/apps-react'

    function OneBlinkAutoSaveFormControlled({
    form,
    initialSubmission,
    autoSaveKey,
    onCancel,
    onSubmit,
    onSaveDraft,
    ...props
    }: React.ComponentProps<typeof OneBlinkAutoSaveForm>) {
    const {
    definition,
    submission,
    isLoadingAutoSaveSubmission,
    isAutoSaveSubmissionAvailable,
    startNewSubmission,
    continueAutoSaveSubmission,
    handleSubmit,
    handleCancel,
    handleSaveDraft,
    setFormSubmission,
    } = useFormSubmissionAutoSaveState({
    form,
    initialSubmission,
    autoSaveKey,
    onCancel,
    onSubmit,
    onSaveDraft,
    })

    // This is just an example of how you could intercept
    // the change event when a user enters/selects a value
    // on the form.
    const customSetFormSubmission = React.useCallback(
    (formSubmission) => {
    setFormSubmission((currentFormSubmission) => {
    const newFormSubmission =
    typeof formSubmission === 'function'
    ? formSubmission(currentFormSubmission)
    : formSubmission

    // This is where you can access the updated
    // submission data or form definition.
    // You could even change the form definition
    // programmatically based on user inputs.
    console.log(
    'A change has occurred to the submission',
    newFormSubmission.submission,
    )
    newFormSubmission.definition.isInfoPage =
    !newFormSubmission.submission.doesTheUserNeedToSubmit

    return newFormSubmission
    })
    },
    [setFormSubmission],
    )

    if (isLoadingAutoSaveSubmission) {
    return <p>Checking for auto save data...</p>
    }

    if (isAutoSaveSubmissionAvailable) {
    return (
    <>
    <p>Do you want to use the auto save data?</p>
    <button onClick={startNewSubmission}>No, start again</button>
    <button onClick={continueAutoSaveSubmission}>
    Yes, continue
    </button>
    </>
    )
    }

    return (
    <OneBlinkFormControlled
    {...props}
    submission={submission}
    definition={definition}
    onCancel={handleCancel}
    onSubmit={handleSubmit}
    onSaveDraft={handleSaveDraft}
    setFormSubmission={customSetFormSubmission}
    />
    )
    }

    export default React.memo(OneBlinkAutoSaveFormControlled)