diff --git a/src/@episerver/forms-react/src/components/FormBody.tsx b/src/@episerver/forms-react/src/components/FormBody.tsx index ed6333f..f1079ef 100644 --- a/src/@episerver/forms-react/src/components/FormBody.tsx +++ b/src/@episerver/forms-react/src/components/FormBody.tsx @@ -100,9 +100,14 @@ export const FormBody = (props: FormBodyProps) => { let isLastStep = currentStepIndex === form.steps.length - 1; + //get inactives element + let inactives = (formContext?.elementDependencies ?? []) + .filter(dependency => !dependency.isSatisfied) + .map(dependency => dependency.elementKey); + //filter submissions by active elements and current step let formSubmissions = (formContext?.formSubmissions ?? []) - .filter(fs => !isInArray(fs.elementKey, formContext?.dependencyInactiveElements ?? []) && stepHelper.isInCurrentStep(fs.elementKey, currentStepIndex)); + .filter(fs => !isInArray(fs.elementKey, inactives) && stepHelper.isInCurrentStep(fs.elementKey, currentStepIndex)); //validate all submission data before submit let formValidationResults = formSubmitter.doValidate(formSubmissions); diff --git a/src/@episerver/forms-react/src/components/FormContainerBlock.tsx b/src/@episerver/forms-react/src/components/FormContainerBlock.tsx index 842db59..d4b9870 100644 --- a/src/@episerver/forms-react/src/components/FormContainerBlock.tsx +++ b/src/@episerver/forms-react/src/components/FormContainerBlock.tsx @@ -34,7 +34,6 @@ export function FormContainerBlock(props: FormContainerProps){ const stepBuilder = new StepBuilder(props.form); const form = stepBuilder.buildForm(); const state = initFormState(form, props.currentPageUrl, props.history); - {/* finally return the form */} return ( diff --git a/src/@episerver/forms-react/src/context/dispatchFunctions.ts b/src/@episerver/forms-react/src/context/dispatchFunctions.ts index fd6d14a..6a43b43 100644 --- a/src/@episerver/forms-react/src/context/dispatchFunctions.ts +++ b/src/@episerver/forms-react/src/context/dispatchFunctions.ts @@ -16,6 +16,14 @@ export class DispatchFunctions { }); } + UpdateElementDependencies = (elementKey: string, condition: boolean) => { + this._dispatch({ + type: ActionType.UpdateElementDependencies, + elementKey: elementKey, + condition + }); + } + updateAllValidation = (formValidationResults: FormValidationResult[]) => { this._dispatch({ type: ActionType.UpdateAllValidation, diff --git a/src/@episerver/forms-react/src/context/model/dependencyModel.ts b/src/@episerver/forms-react/src/context/model/dependencyModel.ts new file mode 100644 index 0000000..d7188d4 --- /dev/null +++ b/src/@episerver/forms-react/src/context/model/dependencyModel.ts @@ -0,0 +1,8 @@ +export class DependencyElementData { + elementId: string + condition: boolean + constructor(elementId: string, condition: boolean) { + this.elementId = elementId + this.condition = condition + } +} \ No newline at end of file diff --git a/src/@episerver/forms-react/src/context/reducer.ts b/src/@episerver/forms-react/src/context/reducer.ts index cb30f5b..37416e9 100644 --- a/src/@episerver/forms-react/src/context/reducer.ts +++ b/src/@episerver/forms-react/src/context/reducer.ts @@ -1,7 +1,9 @@ import { equals, FormState, FormSubmission, - FormValidationResult } from "@episerver/forms-sdk"; + FormValidationResult, + ElementDependencies } from "@episerver/forms-sdk"; + export enum ActionType { UpdateValue = "UpdateValue", @@ -14,7 +16,8 @@ export enum ActionType { UpdateIdentityInfo = "UpdateIdentityInfo", UpdateSubmissionKey = "UpdateSubmissionKey", UpdateCurrentStepIndex = "UpdateCurrentStepIndex", - UpdateIsSubmitting = "UpdateIsSubmitting" + UpdateIsSubmitting = "UpdateIsSubmitting", + UpdateElementDependencies = "UpdateElementDependencies" } export function formReducer(formState: FormState, action: any) { @@ -28,6 +31,15 @@ export function formReducer(formState: FormState, action: any) { } as FormSubmission : fs) } as FormState; } + case ActionType.UpdateElementDependencies: { + return { + ...formState, + elementDependencies: formState.elementDependencies.map(fs => equals(fs.elementKey, action.elementKey) ? { + elementKey: action.elementKey, + isSatisfied: action.condition + } as ElementDependencies : fs) + } as FormState; + } case ActionType.UpdateValidation: { return { ...formState, diff --git a/src/@episerver/forms-react/src/hooks/useElement.ts b/src/@episerver/forms-react/src/hooks/useElement.ts index cd8dbc7..fadfb42 100644 --- a/src/@episerver/forms-react/src/hooks/useElement.ts +++ b/src/@episerver/forms-react/src/hooks/useElement.ts @@ -103,22 +103,9 @@ export const useElement = (element: FormElementBase) => { isVisible.current = equals(conditionProps.satisfiedAction, SatisfiedActionType.Hide); } - //update form state - let inactives = formContext?.dependencyInactiveElements ?? []; - let needUpdate = false; - if(isVisible.current){ - if(inactives.includes(element.key)){ - inactives = inactives.filter(ek => !equals(ek, element.key)); - needUpdate = true; - } - } - else { - if(!isInArray(element.key, inactives)){ - inactives.push(element.key); - needUpdate = true; - } - } - needUpdate && dispatchFuncs.updateDependencies(inactives); + // Update element dependencies state + dispatchFuncs.UpdateElementDependencies(element.key,checkConditions); + },[formContext?.formSubmissions]); //focus on element if validate fail before submitting diff --git a/src/@episerver/forms-sdk/src/helpers/initFormState.ts b/src/@episerver/forms-sdk/src/helpers/initFormState.ts index c705f3e..1d9ea6e 100644 --- a/src/@episerver/forms-sdk/src/helpers/initFormState.ts +++ b/src/@episerver/forms-sdk/src/helpers/initFormState.ts @@ -1,7 +1,7 @@ import { FormCache } from "../form-cache"; import { StepHelper } from "./stepHelper"; import { FormStorage } from "../form-storage"; -import { FormConstants, FormContainer, FormState, FormSubmission, FormValidationResult, StepDependencies } from "../models"; +import { ElementDependencies, FormConstants, FormContainer, FormState, FormSubmission, FormValidationResult, StepDependencies } from "../models"; import { getDefaultValue } from "./elementHelper"; import { equals, isNullOrEmpty } from "./utils"; @@ -19,14 +19,18 @@ export function initFormState(formContainer: FormContainer, currentPageUrl?: str let formSubmissions = [] as FormSubmission[]; let formValidationResults = [] as FormValidationResult[]; let stepDependencies = [] as StepDependencies[]; + let elementDependencies = [] as ElementDependencies[] formContainer.steps?.forEach(s => { s.elements.forEach(e => { - //init form submission - formSubmissions = formSubmissions.concat({ elementKey: e.key, value: getDefaultValue(e) } as FormSubmission); - - //init form validation - formValidationResults = formValidationResults.concat({ elementKey: e.key, result: {valid: true, message: ""} }); + if (e.key != s.formStep.key) { + //init form validation + formValidationResults = formValidationResults.concat({ elementKey: e.key, result: {valid: true, message: ""} }); + //init form submission + formSubmissions = formSubmissions.concat({ elementKey: e.key, value: getDefaultValue(e) } as FormSubmission); + //init form elements dependencies + elementDependencies = elementDependencies.concat({ elementKey: e.key, isSatisfied: true }); + } }); stepDependencies = stepDependencies.concat({ elementKey: s.formStep.key, isSatisfied: false }); }); @@ -53,6 +57,7 @@ export function initFormState(formContainer: FormContainer, currentPageUrl?: str formValidationResults, stepDependencies, formContainer, - history + history, + elementDependencies } as FormState; } \ No newline at end of file diff --git a/src/@episerver/forms-sdk/src/models/states/ElementDependencies.ts b/src/@episerver/forms-sdk/src/models/states/ElementDependencies.ts new file mode 100644 index 0000000..4ec28f4 --- /dev/null +++ b/src/@episerver/forms-sdk/src/models/states/ElementDependencies.ts @@ -0,0 +1,4 @@ +export interface ElementDependencies{ + elementKey: string + isSatisfied: boolean +} \ No newline at end of file diff --git a/src/@episerver/forms-sdk/src/models/states/FormState.ts b/src/@episerver/forms-sdk/src/models/states/FormState.ts index 610ed5e..72a7b7e 100644 --- a/src/@episerver/forms-sdk/src/models/states/FormState.ts +++ b/src/@episerver/forms-sdk/src/models/states/FormState.ts @@ -1,5 +1,6 @@ import { FormContainer } from "../FormContainer" import { IdentityInfo } from "../IdentityInfo" +import { ElementDependencies } from "./ElementDependencies" import { FormSubmission } from "./FormSubmission" import { FormValidationResult } from "./FormValidation" import { StepDependencies } from "./StepDependencies" @@ -12,6 +13,7 @@ export interface FormState { formSubmissions: FormSubmission[] formValidationResults: FormValidationResult[] stepDependencies: StepDependencies[] + elementDependencies: ElementDependencies[]; formContainer: FormContainer dependencyInactiveElements: string[] focusOn: string, diff --git a/src/@episerver/forms-sdk/src/models/states/index.ts b/src/@episerver/forms-sdk/src/models/states/index.ts index 325f493..2024315 100644 --- a/src/@episerver/forms-sdk/src/models/states/index.ts +++ b/src/@episerver/forms-sdk/src/models/states/index.ts @@ -1,4 +1,5 @@ export * from "./FormState"; export * from "./FormSubmission"; export * from "./FormValidation"; -export * from "./StepDependencies"; \ No newline at end of file +export * from "./StepDependencies"; +export * from "./ElementDependencies"; \ No newline at end of file