Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable submit button when submitting #50

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/@episerver/forms-react/src/components/FormBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,38 +68,38 @@ export const FormBody = (props: FormBodyProps) => {
isProgressiveSubmit.current = true;
}

isFormFinalized.current = submitButton?.properties?.finalizeForm || formContext?.currentStepIndex === form.steps.length - 1;

//remove submissions of inactive elements and submissions with undefined value
let formSubmissions = (formContext?.formSubmissions ?? [])
//only post value of active elements
.filter(fs => !isInArray(fs.elementKey, formContext?.dependencyInactiveElements ?? []) && !isNull(fs.value));

//validate all submission data before submit
let formValidationResults = formSubmitter.doValidate(formSubmissions);
dispatchFunctions.dispatchUpdateAllValidation(formValidationResults);
dispatchFunctions.updateAllValidation(formValidationResults);

//set focus on the 1st invalid element of current step
let invalid = formValidationResults.filter(fv =>
fv.results.some(r => !r.valid) &&
form.steps[currentStepIndex]?.elements?.some(e => equals(e.key, fv.elementKey))
)[0]?.elementKey;
if(!isNullOrEmpty(invalid)){
dispatchFunctions.dispatchFocusOn(invalid);
dispatchFunctions.updateFocusOn(invalid);
isFormFinalized.current = false;
return;
}

let model: FormSubmitModel = {
formKey: form.key,
locale: form.locale,
isFinalized: isFormFinalized.current,
isFinalized: submitButton?.properties?.finalizeForm || formContext?.currentStepIndex === form.steps.length - 1,
partialSubmissionKey: formContext?.submissionKey ?? "",
hostedPageUrl: window.location.pathname,
submissionData: formSubmissions,
accessToken: formContext?.identityInfo?.accessToken
}

dispatchFunctions.updateIsSubmitting(true);

formSubmitter.doSubmit(model).then((response: FormSubmitResult)=>{
if(response.success){
message.current = response.messages.map(m => m.message).join("<br>");
Expand All @@ -111,12 +111,13 @@ export const FormBody = (props: FormBodyProps) => {
}
validateFail.current = response.validationFail;
isFormFinalized.current = isSuccess.current = response.success;
dispatchFunctions.dispatchUpdateSubmissionKey(response.submissionKey);
dispatchFunctions.updateSubmissionKey(response.submissionKey);
dispatchFunctions.updateIsSubmitting(false);
});
}

useEffect(()=>{
dispatchFunctions.dispatchUpdateIdentity(props.identityInfo);
dispatchFunctions.updateIdentity(props.identityInfo);
if(isNullOrEmpty(props.identityInfo?.accessToken) && !form.properties.allowAnonymousSubmission){
statusDisplay.current = "Form__Warning__Message";
statusMessage.current = "You must be logged in to submit this form. If you are logged in and still cannot post, make sure \"Do not track\" in your browser settings is disabled.";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { SubmitButton, isNullOrEmpty } from "@episerver/forms-sdk";
import React, { useMemo } from "react";
import { useElement } from "../../hooks/useElement";
import ElementWrapper from "./shared/ElementWrapper";

interface SubmitButtonElementBlockProps{
element: SubmitButton
Expand All @@ -10,7 +9,7 @@ interface SubmitButtonElementBlockProps{
export const SubmitButtonElementBlock = (props: SubmitButtonElementBlockProps) => {
const { element } = props;
const { elementContext } = useElement(element);
const { isVisible, extraAttr, validatorClasses } = elementContext;
const { isVisible, extraAttr, validatorClasses, elementRef } = elementContext;
//TODO: Need to get submittable status from API
const buttonDisableState = false;

Expand All @@ -25,6 +24,7 @@ export const SubmitButtonElementBlock = (props: SubmitButtonElementBlockProps) =
? `Form__Element FormExcludeDataRebind FormSubmitButton ${validatorClasses}`
: `Form__Element FormExcludeDataRebind FormSubmitButton FormImageSubmitButton ${validatorClasses}`
}
ref={elementRef}
>
{isNullOrEmpty(element.properties.image) ? element.properties.label : (
<img src={element.properties.image} alt={element.properties.label} />
Expand Down
27 changes: 17 additions & 10 deletions src/@episerver/forms-react/src/context/dispatchFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,43 @@ export class DispatchFunctions {
this._dispatch = dispatch;
}

dispatchUpdateValidation = (elementKey: string, validationResults: ElementValidationResult[]) => {
updateValidation = (elementKey: string, validationResults: ElementValidationResult[]) => {
this._dispatch({
type: ActionType.UpdateValidation,
elementKey: elementKey,
validationResults
});
}

dispatchUpdateAllValidation = (formValidationResults: FormValidationResult[]) => {
updateAllValidation = (formValidationResults: FormValidationResult[]) => {
this._dispatch({
type: ActionType.UpdateAllValidation,
formValidationResults
});
}

dispatchUpdateValue = (elementKey: string, value: any) => {
updateValue = (elementKey: string, value: any) => {
this._dispatch({
type: ActionType.UpdateValue,
elementKey: elementKey,
value
});
}

dispatchUpdateDependencies = (dependencyInactiveElements: string[]) => {
updateDependencies = (dependencyInactiveElements: string[]) => {
this._dispatch({
type: ActionType.UpdateDependencies,
dependencyInactiveElements
});
}

dispatchResetedForm = () => {
resetedForm = () => {
this._dispatch({
type: ActionType.ResetedForm
});
}

dispatchResetForm = (formContainer: FormContainer) => {
resetForm = (formContainer: FormContainer) => {
this._dispatch({
type: ActionType.ResetForm,
formState: {
Expand All @@ -53,31 +53,38 @@ export class DispatchFunctions {
});
}

dispatchFocusOn = (focusOn: string) => {
updateFocusOn = (focusOn: string) => {
this._dispatch({
type: ActionType.UpdateFocusOn,
focusOn
});
}

dispatchUpdateIdentity = (identityInfo?: IdentityInfo) => {
updateIdentity = (identityInfo?: IdentityInfo) => {
this._dispatch({
type: ActionType.UpdateIdentityInfo,
identityInfo
});
}

dispatchUpdateSubmissionKey = (submissionKey?: string) => {
updateSubmissionKey = (submissionKey?: string) => {
this._dispatch({
type: ActionType.UpdateSubmissionKey,
submissionKey
});
}

dispatchUpdateCurrentStepIndex = (currentStepIndex?: number) => {
updateCurrentStepIndex = (currentStepIndex?: number) => {
this._dispatch({
type: ActionType.UpdateCurrentStepIndex,
currentStepIndex
});
}

updateIsSubmitting = (isSubmitting?: boolean) => {
this._dispatch({
type: ActionType.UpdateIsSubmitting,
isSubmitting
});
}
}
9 changes: 8 additions & 1 deletion src/@episerver/forms-react/src/context/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export enum ActionType {
UpdateFocusOn = "UpdateFocusOn",
UpdateIdentityInfo = "UpdateIdentityInfo",
UpdateSubmissionKey = "UpdateSubmissionKey",
UpdateCurrentStepIndex = "UpdateCurrentStepIndex"
UpdateCurrentStepIndex = "UpdateCurrentStepIndex",
UpdateIsSubmitting = "UpdateIsSubmitting"
}

export function formReducer(formState: FormState, action: any) {
Expand Down Expand Up @@ -84,6 +85,12 @@ export function formReducer(formState: FormState, action: any) {
currentStepIndex: action.currentStepIndex
} as FormState
}
case ActionType.UpdateIsSubmitting: {
return {
...formState,
isSubmitting: action.isSubmitting
} as FormState
}
default: {
return formState;
}
Expand Down
21 changes: 14 additions & 7 deletions src/@episerver/forms-react/src/hooks/useElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const useElement = (element: FormElementBase) => {
useEffect(()=>{
if(formContext?.isReset){
//update form state
dispatchFuncs.dispatchResetedForm();
dispatchFuncs.resetedForm();
}
},[formContext?.isReset]);

Expand Down Expand Up @@ -103,18 +103,25 @@ export const useElement = (element: FormElementBase) => {
else {
!isInArray(element.key, inactives) && inactives.push(element.key);
}
dispatchFuncs.dispatchUpdateDependencies(inactives);
dispatchFuncs.updateDependencies(inactives);
},[formContext?.formSubmissions]);

//focus on element if validate fail before submitting
useEffect(()=>{
let focusOn = formContext?.focusOn ?? "";
if(equals(focusOn, element.key)){
elementRef.current && elementRef.current.focus();
dispatchFuncs.dispatchFocusOn("");
dispatchFuncs.updateFocusOn("");
}
},[formContext?.focusOn]);

//disable submit button when form submitting
useEffect(()=>{
if(equals(element.contentType, "SubmitButtonElementBlock")){
elementRef.current.disabled = formContext?.isSubmitting ?? false;
}
},[formContext?.isSubmitting])

const handleChange = (e: any) => {
const { name, value: inputValue, type, checked, files } = e.target;
let submissionValue = inputValue;
Expand All @@ -138,23 +145,23 @@ export const useElement = (element: FormElementBase) => {
if (/file/.test(type)) {
submissionValue = files;
let validationResults = formValidation.validate(files)
dispatchFuncs.dispatchUpdateValidation(element.key, validationResults);
dispatchFuncs.updateValidation(element.key, validationResults);
}

//update form context
dispatchFuncs.dispatchUpdateValue(element.key, submissionValue);
dispatchFuncs.updateValue(element.key, submissionValue);
}

const handleBlur = (e: any) => {
//call validation from form-sdk
let validationResults = formValidation.validate(value);

//update form context
dispatchFuncs.dispatchUpdateValidation(element.key, validationResults);
dispatchFuncs.updateValidation(element.key, validationResults);
}

const handleReset = () => {
dispatchFuncs.dispatchResetForm(formContext?.formContainer ?? {} as FormContainer);
dispatchFuncs.resetForm(formContext?.formContainer ?? {} as FormContainer);
}

return {
Expand Down
1 change: 1 addition & 0 deletions src/@episerver/forms-sdk/src/models/states/FormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export interface FormState {
identityInfo?: IdentityInfo
submissionKey?: string
currentStepIndex: number
isSubmitting?: boolean
}