Skip to content

Commit

Permalink
Add multi step submission
Browse files Browse the repository at this point in the history
Fixes: AFORM-3800
  • Loading branch information
epi-qang2 committed Dec 18, 2023
1 parent a2fcf77 commit 693c540
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
23 changes: 18 additions & 5 deletions src/@episerver/forms-react/src/components/FormBody.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useRef } from "react";
import { useForms, useFormsDispatch } from "../context/store";
import { FormContainer, FormSubmitter, IdentityInfo, SubmitButtonType, equals, isInArray, isNull, isNullOrEmpty, FormSubmitModel, FormSubmitResult, SubmitButton, ElementValidationResult, FormValidationResult } from "@episerver/forms-sdk";
import { useForms } from "../context/store";
import { FormContainer, FormSubmitter, IdentityInfo, equals, isInArray, isNull, isNullOrEmpty, FormSubmitModel, FormSubmitResult, SubmitButton, FormValidationResult, FormCache, FormConstants } from "@episerver/forms-sdk";
import { RenderElementInStep } from "./RenderElementInStep";
import { DispatchFunctions } from "../context/dispatchFunctions";
import { FormStepNavigation } from "./FormStepNavigation";
Expand All @@ -21,6 +21,9 @@ export const FormBody = (props: FormBodyProps) => {
const statusMessage = useRef<string>("");
const statusDisplay = useRef<string>("hide");

const formCache = new FormCache();
const localFormCache = new FormCache(window.localStorage);

//TODO: these variables should be get from api or sdk
const validateFail = useRef<boolean>(false),
isFormFinalized = useRef<boolean>(false),
Expand Down Expand Up @@ -70,7 +73,7 @@ export const FormBody = (props: FormBodyProps) => {
}

//Find submit button, if found then check property 'finalizeForm' of submit button. Otherwise, button Next/Previous was clicked.
let buttonId = e.nativeEvent.submitter.id;
let buttonId = e.nativeEvent.submitter?.id;
let submitButton = form.formElements.find(fe => fe.key === buttonId) as SubmitButton;
if (!isNull(submitButton)) {
//when submitting by SubmitButton, isProgressiveSubmit default is true
Expand All @@ -96,10 +99,11 @@ export const FormBody = (props: FormBodyProps) => {
formKey: form.key,
locale: form.locale,
isFinalized: submitButton?.properties?.finalizeForm || isLastStep,
partialSubmissionKey: formContext?.submissionKey ?? "",
partialSubmissionKey: localFormCache.get(FormConstants.FormSubmissionId + form.key) ?? "",
hostedPageUrl: window.location.pathname,
submissionData: formSubmissions,
accessToken: formContext?.identityInfo?.accessToken
accessToken: formContext?.identityInfo?.accessToken,
currentStepIndex: currentStepIndex
}

dispatchFunctions.updateIsSubmitting(true);
Expand Down Expand Up @@ -131,11 +135,19 @@ export const FormBody = (props: FormBodyProps) => {
//set focus on the 1st invalid element of current step
dispatchFunctions.updateFocusOn(getFirstInvalidElement(formValidationResults));
}

validateFail.current = response.validationFail;
isSuccess.current = response.success;
isFormFinalized.current = isLastStep && response.success;
dispatchFunctions.updateSubmissionKey(response.submissionKey);
dispatchFunctions.updateIsSubmitting(false);

localFormCache.set(FormConstants.FormSubmissionId + form.key, response.submissionKey)

if (isFormFinalized.current) {
formCache.remove(FormConstants.FormCurrentStep + form.key)
localFormCache.remove(FormConstants.FormSubmissionId + form.key)
}
});
}

Expand Down Expand Up @@ -202,6 +214,7 @@ export const FormBody = (props: FormBodyProps) => {
<FormStepNavigation
isFormFinalized={isFormFinalized.current}
history = {props.history}
handleSubmit = {handleSubmit}
/>
</div>
</form>
Expand Down
12 changes: 7 additions & 5 deletions src/@episerver/forms-react/src/components/FormStepNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import { useHistory } from "react-router-dom";
interface FormStepNavigationProps {
isFormFinalized: boolean
history?: any
handleSubmit: (e: any) => void
}

export const FormStepNavigation = (props: FormStepNavigationProps) => {
const formContext = useForms();
const formCache = new FormCache();
const form = formContext?.formContainer ?? {} as FormContainer;
const depend = new StepDependCondition(form, formContext?.dependencyInactiveElements ?? []);
const { isFormFinalized, history } = props;
const { isFormFinalized, history, handleSubmit } = props;
const dispatchFuncs = new DispatchFunctions();
const stepLocalizations = useRef<Record<string, string>>(form.steps?.filter(s => !isNull(s.formStep.localizations))[0]?.formStep.localizations);
const stepLocalizations = useRef<Record<string, string>>(form.steps?.filter(s => !isNull(s.formStep.localizations))[0]?.formStep.localizations).current;

const submittable = true
const stepCount = form.steps.length;
Expand All @@ -36,6 +37,7 @@ export const FormStepNavigation = (props: FormStepNavigationProps) => {

const handleNextStep = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault()
handleSubmit(event)
goToStep(depend.findNextStep(currentStepIndex) ?? 0)
}

Expand Down Expand Up @@ -63,13 +65,13 @@ export const FormStepNavigation = (props: FormStepNavigationProps) => {
disabled={prevButtonDisableState}
onClick={(event) => handlePrevStep(event)}
>
{stepLocalizations.current["previousButtonLabel"]}
{stepLocalizations["previousButtonLabel"]}
</button>

<div className="Form__NavigationBar__ProgressBar">
<div className="Form__NavigationBar__ProgressBar--Progress" style={{ width: progressWidth }}></div>
<div className="Form__NavigationBar__ProgressBar--Text">
<span className="Form__NavigationBar__ProgressBar__ProgressLabel">{stepLocalizations.current["pageButtonLabel"]}</span>
<span className="Form__NavigationBar__ProgressBar__ProgressLabel">{stepLocalizations["pageButtonLabel"]}</span>
<span className="Form__NavigationBar__ProgressBar__CurrentStep">{currentDisplayStepIndex}</span>/
<span className="Form__NavigationBar__ProgressBar__StepsCount">{stepCount}</span>
</div>
Expand All @@ -83,7 +85,7 @@ export const FormStepNavigation = (props: FormStepNavigationProps) => {
disabled={nextButtonDisableState}
onClick={handleNextStep}
>
{stepLocalizations.current["nextButtonLabel"]}
{stepLocalizations["nextButtonLabel"]}
</button>
</nav>
}
Expand Down
5 changes: 5 additions & 0 deletions src/@episerver/forms-sdk/src/form-submit/formSubmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export interface FormSubmitModel {
* The access token to identify login user
*/
accessToken?: string;
/**
* The current index of submitted step
*/
currentStepIndex: number;
}

export interface FormSubmitResult {
Expand Down Expand Up @@ -99,6 +103,7 @@ export class FormSubmitter {
formData.append("IsFinalized", model.isFinalized.toString());
formData.append("PartialSubmissionKey", model.partialSubmissionKey);
formData.append("HostedPageUrl", model.hostedPageUrl);
formData.append("CurrentStep", model.currentStepIndex.toString());

//append form submission to FormData object
model.submissionData.forEach(data => {
Expand Down
3 changes: 2 additions & 1 deletion src/@episerver/forms-sdk/src/models/enums/FormConstants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum FormConstants {
FormAccessToken = "form_access_token",
FormFieldPrefix = "__field_",
FormCurrentStep = "form_current_step_"
FormCurrentStep = "form_current_step_",
FormSubmissionId = "form_submission_id_"
}

0 comments on commit 693c540

Please sign in to comment.