1
- import React , { useEffect , useRef } from ' react' ;
2
- import { useForms } from ' ../context/store' ;
1
+ import React , { useEffect , useRef } from " react" ;
2
+ import { useForms } from " ../context/store" ;
3
3
import {
4
4
StepHelper ,
5
5
FormContainer ,
@@ -16,10 +16,10 @@ import {
16
16
ProblemDetail ,
17
17
StepDependCondition ,
18
18
getConfirmationData ,
19
- } from ' @episerver/forms-sdk' ;
20
- import { RenderElementInStep } from ' ./RenderElementInStep' ;
21
- import { DispatchFunctions } from ' ../context/dispatchFunctions' ;
22
- import { FormStepNavigation } from ' ./FormStepNavigation' ;
19
+ } from " @episerver/forms-sdk" ;
20
+ import { RenderElementInStep } from " ./RenderElementInStep" ;
21
+ import { DispatchFunctions } from " ../context/dispatchFunctions" ;
22
+ import { FormStepNavigation } from " ./FormStepNavigation" ;
23
23
24
24
interface FormBodyProps {
25
25
identityInfo ?: IdentityInfo ;
@@ -39,13 +39,16 @@ export const FormBody = (props: FormBodyProps) => {
39
39
const currentPageUrl = props . currentPageUrl ?? window . location . href ;
40
40
41
41
const formTitleId = `${ form . key } _label` ;
42
- const statusMessage = useRef < string > ( '' ) ;
43
- const statusDisplay = useRef < string > ( ' hide' ) ;
42
+ const statusMessage = useRef < string > ( "" ) ;
43
+ const statusDisplay = useRef < string > ( " hide" ) ;
44
44
45
45
const showForm = useRef < boolean > ( true ) ;
46
46
47
- const formCache = new FormCache ( ) ;
48
- const localFormCache = new FormCache ( window . localStorage ) ;
47
+ const formCache = new FormCache ( undefined , props . identityInfo ?. username ) ;
48
+ const localFormCache = new FormCache (
49
+ window . localStorage ,
50
+ props . identityInfo ?. username
51
+ ) ;
49
52
const currentStepIndex = formContext ?. currentStepIndex ?? 0 ;
50
53
51
54
// @sampension - check for redirect to page after submit to prevent rendering of (default) success message before redirect
@@ -57,24 +60,37 @@ export const FormBody = (props: FormBodyProps) => {
57
60
isProgressiveSubmit = useRef < boolean > ( false ) ,
58
61
isSuccess = useRef < boolean > ( false ) ,
59
62
submissionWarning = useRef < boolean > ( false ) ,
60
- message = useRef < string > ( '' ) ,
63
+ message = useRef < string > ( "" ) ,
61
64
submissionStorageKey = FormConstants . FormSubmissionId + form . key ,
62
- isStepValidToDisplay = stepDependCondition . isStepValidToDisplay ( currentStepIndex , currentPageUrl ) ,
65
+ isStepValidToDisplay = stepDependCondition . isStepValidToDisplay (
66
+ currentStepIndex ,
67
+ currentPageUrl
68
+ ) ,
63
69
isMalFormSteps = stepHelper . isMalFormSteps ( ) ;
64
70
65
71
// @sampension - added check for redirect to page
66
- if ( ( isFormFinalized . current || isProgressiveSubmit . current ) && isSuccess . current && ! shouldRedirectToPage ) {
67
- statusDisplay . current = 'Form__Success__Message' ;
68
- statusMessage . current = form . properties . submitSuccessMessage ?? message . current ;
69
- } else if ( ( submissionWarning . current || ! isSuccess . current ) && ! isNullOrEmpty ( message . current ) ) {
70
- statusDisplay . current = 'Form__Warning__Message' ;
72
+ if (
73
+ ( isFormFinalized . current || isProgressiveSubmit . current ) &&
74
+ isSuccess . current &&
75
+ ! shouldRedirectToPage
76
+ ) {
77
+ statusDisplay . current = "Form__Success__Message" ;
78
+ statusMessage . current =
79
+ form . properties . submitSuccessMessage ?? message . current ;
80
+ } else if (
81
+ ( submissionWarning . current || ! isSuccess . current ) &&
82
+ ! isNullOrEmpty ( message . current )
83
+ ) {
84
+ statusDisplay . current = "Form__Warning__Message" ;
71
85
statusMessage . current = message . current ;
72
86
} else {
73
- statusDisplay . current = ' hide' ;
74
- statusMessage . current = '' ;
87
+ statusDisplay . current = " hide" ;
88
+ statusMessage . current = "" ;
75
89
}
76
90
77
- const validationCssClass = validateFail . current ? 'ValidationFail' : 'ValidationSuccess' ;
91
+ const validationCssClass = validateFail . current
92
+ ? "ValidationFail"
93
+ : "ValidationSuccess" ;
78
94
79
95
const showError = ( error : string ) => {
80
96
submissionWarning . current = ! isNullOrEmpty ( error ) ;
@@ -83,15 +99,22 @@ export const FormBody = (props: FormBodyProps) => {
83
99
84
100
const handleConfirm = ( ) => {
85
101
const form = formContext ?. formContainer ?? ( { } as FormContainer ) ;
86
- const confirmationMessage = form . properties . confirmationMessage ?? '' ;
102
+ const confirmationMessage = form . properties . confirmationMessage ?? "" ;
87
103
let confimStatus = true ;
88
104
89
105
if ( form . properties . showSummarizedData ) {
90
106
const data = formContext ?. formSubmissions ?? [ ] ;
91
- const messageData = getConfirmationData ( data , form , currentStepIndex , inactiveElements ) ;
92
- const showConfirmationMessage = ! ( isNullOrEmpty ( confirmationMessage ) && isNullOrEmpty ( messageData ) ) ;
107
+ const messageData = getConfirmationData (
108
+ data ,
109
+ form ,
110
+ currentStepIndex ,
111
+ inactiveElements
112
+ ) ;
113
+ const showConfirmationMessage = ! (
114
+ isNullOrEmpty ( confirmationMessage ) && isNullOrEmpty ( messageData )
115
+ ) ;
93
116
if ( showConfirmationMessage ) {
94
- confimStatus = confirm ( confirmationMessage + ' \n\n' + messageData ) ;
117
+ confimStatus = confirm ( confirmationMessage + " \n\n" + messageData ) ;
95
118
}
96
119
}
97
120
@@ -101,13 +124,18 @@ export const FormBody = (props: FormBodyProps) => {
101
124
const handleSubmit = ( e : any ) => {
102
125
e . preventDefault ( ) ;
103
126
104
- if ( ! form . properties . allowAnonymousSubmission && isNullOrEmpty ( formContext ?. identityInfo ?. accessToken ) ) {
127
+ if (
128
+ ! form . properties . allowAnonymousSubmission &&
129
+ isNullOrEmpty ( formContext ?. identityInfo ?. accessToken )
130
+ ) {
105
131
return ;
106
132
}
107
133
108
134
//Find submit button, if found then check property 'finalizeForm' of submit button. Otherwise, button Next/Previous was clicked.
109
135
const buttonId = e . nativeEvent . submitter ?. id ;
110
- const submitButton = form . formElements . find ( ( fe ) => fe . key === buttonId ) as SubmitButton ;
136
+ const submitButton = form . formElements . find (
137
+ ( fe ) => fe . key === buttonId
138
+ ) as SubmitButton ;
111
139
if ( ! isNull ( submitButton ) ) {
112
140
//when submitting by SubmitButton, isProgressiveSubmit default is true
113
141
isProgressiveSubmit . current = true ;
@@ -122,15 +150,20 @@ export const FormBody = (props: FormBodyProps) => {
122
150
123
151
//filter submissions by active elements and current step
124
152
const formSubmissions = ( formContext ?. formSubmissions ?? [ ] ) . filter (
125
- ( fs ) => ! isInArray ( fs . elementKey , inactives ) && stepHelper . isInCurrentStep ( fs . elementKey , currentStepIndex )
153
+ ( fs ) =>
154
+ ! isInArray ( fs . elementKey , inactives ) &&
155
+ stepHelper . isInCurrentStep ( fs . elementKey , currentStepIndex )
126
156
) ;
127
157
128
158
//validate all submission data before submit
129
159
const formValidationResults = formSubmitter . doValidate ( formSubmissions ) ;
130
160
dispatchFunctions . updateAllValidation ( formValidationResults ) ;
131
161
132
162
//set focus on the 1st invalid element of current step
133
- const invalid = stepHelper . getFirstInvalidElement ( formValidationResults , currentStepIndex ) ;
163
+ const invalid = stepHelper . getFirstInvalidElement (
164
+ formValidationResults ,
165
+ currentStepIndex
166
+ ) ;
134
167
if ( ! isNullOrEmpty ( invalid ) ) {
135
168
dispatchFunctions . updateFocusOn ( invalid ) ;
136
169
return ;
@@ -148,7 +181,13 @@ export const FormBody = (props: FormBodyProps) => {
148
181
formKey : form . key ,
149
182
locale : form . locale ,
150
183
isFinalized : submitButton ?. properties ?. finalizeForm || isLastStep ,
151
- partialSubmissionKey : localFormCache . get ( submissionStorageKey ) ?? formContext ?. submissionKey ?? '' ,
184
+ partialSubmissionKey :
185
+ localFormCache . get (
186
+ submissionStorageKey ,
187
+ props . identityInfo ?. username
188
+ ) ??
189
+ formContext ?. submissionKey ??
190
+ "" ,
152
191
hostedPageUrl : currentPageUrl ,
153
192
submissionData : formSubmissions ,
154
193
accessToken : formContext ?. identityInfo ?. accessToken ,
@@ -162,32 +201,51 @@ export const FormBody = (props: FormBodyProps) => {
162
201
. then ( ( response : FormSubmitResult ) => {
163
202
//go here, response.success always is true
164
203
isSuccess . current = response . success ;
165
- isFormFinalized . current = ( submitButton ?. properties ?. finalizeForm || isLastStep ) && response . success ;
204
+ isFormFinalized . current =
205
+ ( submitButton ?. properties ?. finalizeForm || isLastStep ) &&
206
+ response . success ;
166
207
dispatchFunctions . updateSubmissionKey ( response . submissionKey ) ;
167
- localFormCache . set ( submissionStorageKey , response . submissionKey ) ;
208
+ localFormCache . set (
209
+ submissionStorageKey ,
210
+ response . submissionKey ,
211
+ props . identityInfo ?. username
212
+ ) ;
168
213
169
214
if ( isProgressiveSubmit . current ) {
170
- message . current = response . messages . map ( ( m ) => m . message ) . join ( '<br>' ) ;
215
+ message . current = response . messages
216
+ . map ( ( m ) => m . message )
217
+ . join ( "<br>" ) ;
171
218
showForm . current = false ;
172
219
}
173
220
174
221
// Custom redirect message
175
- const redirectMessage = response . messages . find ( ( message ) => message . section === 'redirect' ) ;
222
+ const redirectMessage = response . messages . find (
223
+ ( message ) => message . section === "redirect"
224
+ ) ;
176
225
if ( redirectMessage && ! isNullOrEmpty ( redirectMessage . message ) ) {
177
226
window . location . href = redirectMessage . message ;
178
227
return ;
179
228
}
180
229
181
230
if ( isFormFinalized . current ) {
182
- formCache . remove ( FormConstants . FormCurrentStep + form . key ) ;
183
- localFormCache . remove ( submissionStorageKey ) ;
231
+ formCache . remove (
232
+ FormConstants . FormCurrentStep + form . key ,
233
+ props . identityInfo ?. username
234
+ ) ;
235
+ localFormCache . remove (
236
+ submissionStorageKey ,
237
+ props . identityInfo ?. username
238
+ ) ;
184
239
}
185
240
186
241
//redirect after submit
187
242
if ( submitButton ) {
188
- const redirectToPage = submitButton ?. properties ?. redirectToPage ?? form . properties ?. redirectToPage ;
243
+ const redirectToPage =
244
+ submitButton ?. properties ?. redirectToPage ??
245
+ form . properties ?. redirectToPage ;
189
246
if ( ! isNullOrEmpty ( redirectToPage ) ) {
190
- const cmsUrl = process . env . REACT_APP_HEADLESS_FORM_BASE_URL ?? 'http://temp' ;
247
+ const cmsUrl =
248
+ process . env . REACT_APP_HEADLESS_FORM_BASE_URL ?? "http://temp" ;
191
249
const url = new URL ( redirectToPage , cmsUrl ) ;
192
250
window . location . href = url . href ;
193
251
}
@@ -198,7 +256,10 @@ export const FormBody = (props: FormBodyProps) => {
198
256
case 401 :
199
257
//clear access token to ask login again
200
258
dispatchFunctions . updateIdentity ( { } as IdentityInfo ) ;
201
- formCache . remove ( FormConstants . FormAccessToken ) ;
259
+ formCache . remove (
260
+ FormConstants . FormAccessToken ,
261
+ props . identityInfo ?. username
262
+ ) ;
202
263
break ;
203
264
case 400 :
204
265
if ( e . errors ) {
@@ -210,15 +271,21 @@ export const FormBody = (props: FormBodyProps) => {
210
271
? fr
211
272
: {
212
273
...fr ,
213
- result : { valid : false , message : e . errors [ fr . elementKey ] . join ( '<br/>' ) } ,
274
+ result : {
275
+ valid : false ,
276
+ message : e . errors [ fr . elementKey ] . join ( "<br/>" ) ,
277
+ } ,
214
278
}
215
279
) ?? [ ] ;
216
280
217
281
dispatchFunctions . updateAllValidation ( formValidationResults ) ;
218
282
219
283
//set focus on the 1st invalid element of current step
220
284
dispatchFunctions . updateFocusOn (
221
- stepHelper . getFirstInvalidElement ( formValidationResults , currentStepIndex )
285
+ stepHelper . getFirstInvalidElement (
286
+ formValidationResults ,
287
+ currentStepIndex
288
+ )
222
289
) ;
223
290
}
224
291
break ;
@@ -233,29 +300,37 @@ export const FormBody = (props: FormBodyProps) => {
233
300
234
301
useEffect ( ( ) => {
235
302
dispatchFunctions . updateIdentity ( props . identityInfo ) ;
236
- if ( isNullOrEmpty ( props . identityInfo ?. accessToken ) && ! form . properties . allowAnonymousSubmission ) {
303
+ if (
304
+ isNullOrEmpty ( props . identityInfo ?. accessToken ) &&
305
+ ! form . properties . allowAnonymousSubmission
306
+ ) {
237
307
showError ( form . localizations . allowAnonymousSubmissionErrorMessage ) ;
238
308
} else {
239
- showError ( '' ) ;
309
+ showError ( "" ) ;
240
310
}
241
311
} , [ props . identityInfo ?. accessToken ] ) ;
242
312
243
313
//reset when change page
244
314
useEffect ( ( ) => {
245
315
isSuccess . current = false ;
246
316
if ( form . properties . focusOnForm || currentStepIndex > 0 ) {
247
- dispatchFunctions . updateFocusOn ( stepHelper . getFirstInputElement ( currentStepIndex , inactiveElements ) ) ;
317
+ dispatchFunctions . updateFocusOn (
318
+ stepHelper . getFirstInputElement ( currentStepIndex , inactiveElements )
319
+ ) ;
248
320
}
249
321
} , [ currentStepIndex ] ) ;
250
322
251
323
//Run in-case change page by url. The currentStepIndex that get from cache is incorrect.
252
324
useEffect ( ( ) => {
253
325
if ( ! isStepValidToDisplay ) {
254
- dispatchFunctions . updateCurrentStepIndex ( stepHelper . getCurrentStepIndex ( currentPageUrl ) ) ;
326
+ dispatchFunctions . updateCurrentStepIndex (
327
+ stepHelper . getCurrentStepIndex ( currentPageUrl )
328
+ ) ;
255
329
}
256
330
} , [ ] ) ;
257
331
258
- isMalFormSteps && showError ( form . localizations . malformstepconfigruationErrorMessage ) ;
332
+ isMalFormSteps &&
333
+ showError ( form . localizations . malformstepconfigruationErrorMessage ) ;
259
334
260
335
return (
261
336
< form
@@ -276,26 +351,30 @@ export const FormBody = (props: FormBodyProps) => {
276
351
</ h2 >
277
352
) }
278
353
{ form . properties . description && (
279
- < aside className = "body-lg color-txt-primary body--400 Form__Description" > { form . properties . description } </ aside >
354
+ < aside className = "body-lg color-txt-primary body--400 Form__Description" >
355
+ { form . properties . description }
356
+ </ aside >
280
357
) }
281
358
< div
282
359
className = "Form__MainBody"
283
- style = { { display : showForm . current ? ' flow' : ' none' } }
360
+ style = { { display : showForm . current ? " flow" : " none" } }
284
361
>
285
362
{ /* render element */ }
286
363
{ form . steps . map ( ( e , i ) => {
287
364
const stepDisplaying =
288
- currentStepIndex === i && ! isFormFinalized . current && isStepValidToDisplay && ! isMalFormSteps ? '' : 'hide' ;
365
+ currentStepIndex === i &&
366
+ ! isFormFinalized . current &&
367
+ isStepValidToDisplay &&
368
+ ! isMalFormSteps
369
+ ? ""
370
+ : "hide" ;
289
371
return (
290
372
< section
291
373
key = { e . formStep . key }
292
374
id = { e . formStep . key }
293
375
className = { `Form__Element__Step ${ stepDisplaying } ` }
294
376
>
295
- < RenderElementInStep
296
- elements = { e . elements }
297
- stepIndex = { i }
298
- />
377
+ < RenderElementInStep elements = { e . elements } stepIndex = { i } />
299
378
</ section >
300
379
) ;
301
380
} ) }
@@ -311,7 +390,7 @@ export const FormBody = (props: FormBodyProps) => {
311
390
/>
312
391
</ div >
313
392
{ /* area for showing Form's status or validation */ }
314
- < div className = "Form__Status" >
393
+ < div className = "Form__Status alert-bar alert-bar--urgency--high " >
315
394
< div
316
395
role = "status"
317
396
className = { `Form__Status__Message ${ statusDisplay . current } ` }
0 commit comments