aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar ks129 <[email protected]>2021-02-08 19:29:37 +0200
committerGravatar ks129 <[email protected]>2021-02-08 19:29:37 +0200
commit7075e8579e5aa038438be9bbb2ba275d52c20910 (patch)
tree87140512e8d6d4cdebb88b40e76f741c7dae38db
parentRename invalid field IDs variable (diff)
Implement focusing text fields if empty on submit
-rw-r--r--src/components/InputTypes/ShortText.tsx6
-rw-r--r--src/components/InputTypes/TextArea.tsx6
-rw-r--r--src/components/InputTypes/index.tsx9
-rw-r--r--src/components/Question.tsx6
-rw-r--r--src/pages/FormPage.tsx6
5 files changed, 22 insertions, 11 deletions
diff --git a/src/components/InputTypes/ShortText.tsx b/src/components/InputTypes/ShortText.tsx
index 5509a45..12f066e 100644
--- a/src/components/InputTypes/ShortText.tsx
+++ b/src/components/InputTypes/ShortText.tsx
@@ -6,13 +6,15 @@ import { textInputs, invalidStyles } from "../../commonStyles";
interface ShortTextProps {
handler: (event: ChangeEvent<HTMLInputElement>) => void,
blurHandler: (event: FocusEvent<HTMLInputElement>) => void,
- valid: boolean
+ valid: boolean,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ focus_ref: React.RefObject<any>
}
export default function ShortText(props: ShortTextProps): JSX.Element {
return (
<div css={invalidStyles}>
- <input type="text" css={textInputs} placeholder="Enter Text..." onChange={props.handler} onBlur={props.blurHandler} className={!props.valid ? "invalid-box" : ""}/>
+ <input type="text" css={textInputs} placeholder="Enter Text..." onChange={props.handler} onBlur={props.blurHandler} className={!props.valid ? "invalid-box" : ""} ref={props.focus_ref}/>
</div>
);
}
diff --git a/src/components/InputTypes/TextArea.tsx b/src/components/InputTypes/TextArea.tsx
index 10dbf10..35afe67 100644
--- a/src/components/InputTypes/TextArea.tsx
+++ b/src/components/InputTypes/TextArea.tsx
@@ -6,7 +6,9 @@ import { invalidStyles, textInputs } from "../../commonStyles";
interface TextAreaProps {
handler: (event: ChangeEvent<HTMLTextAreaElement>) => void,
onBlurHandler: (event: FocusEvent<HTMLTextAreaElement>) => void,
- valid: boolean
+ valid: boolean,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ focus_ref: React.RefObject<any>
}
const styles = css`
@@ -21,7 +23,7 @@ const styles = css`
export default function TextArea(props: TextAreaProps): JSX.Element {
return (
<div css={invalidStyles}>
- <textarea css={[textInputs, styles]} placeholder="Enter Text..." onChange={props.handler} onBlur={props.onBlurHandler} className={!props.valid ? "invalid-box" : ""}/>
+ <textarea css={[textInputs, styles]} placeholder="Enter Text..." onChange={props.handler} onBlur={props.onBlurHandler} className={!props.valid ? "invalid-box" : ""} ref={props.focus_ref}/>
</div>
);
}
diff --git a/src/components/InputTypes/index.tsx b/src/components/InputTypes/index.tsx
index 2b348e0..cbfbd8c 100644
--- a/src/components/InputTypes/index.tsx
+++ b/src/components/InputTypes/index.tsx
@@ -18,7 +18,8 @@ const require_options: Array<QuestionType> = [
QuestionType.Range
];
-export default function create_input({ question, public_state }: QuestionProp, handler: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void, blurHandler: () => void): JSX.Element | JSX.Element[] {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default function create_input({ question, public_state }: QuestionProp, handler: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void, blurHandler: () => void, focus_ref: React.RefObject<any>): JSX.Element | JSX.Element[] {
let result: JSX.Element | JSX.Element[];
// eslint-disable-next-line
@@ -38,7 +39,7 @@ export default function create_input({ question, public_state }: QuestionProp, h
/* eslint-disable react/react-in-jsx-scope */
switch (question.type) {
case QuestionType.TextArea:
- result = <TextArea handler={handler} valid={valid} onBlurHandler={blurHandler}/>;
+ result = <TextArea handler={handler} valid={valid} onBlurHandler={blurHandler} focus_ref={focus_ref}/>;
break;
case QuestionType.Checkbox:
@@ -54,7 +55,7 @@ export default function create_input({ question, public_state }: QuestionProp, h
break;
case QuestionType.ShortText:
- result = <ShortText handler={handler} blurHandler={blurHandler} valid={valid}/>;
+ result = <ShortText handler={handler} blurHandler={blurHandler} valid={valid} focus_ref={focus_ref}/>;
break;
case QuestionType.Range:
@@ -67,7 +68,7 @@ export default function create_input({ question, public_state }: QuestionProp, h
break;
default:
- result = <TextArea handler={handler} valid={valid} onBlurHandler={blurHandler}/>;
+ result = <TextArea handler={handler} valid={valid} onBlurHandler={blurHandler} focus_ref={focus_ref}/>;
}
/* eslint-enable react/react-in-jsx-scope */
diff --git a/src/components/Question.tsx b/src/components/Question.tsx
index 567da2c..e619a45 100644
--- a/src/components/Question.tsx
+++ b/src/components/Question.tsx
@@ -18,7 +18,9 @@ const skip_normal_state: Array<QuestionType> = [
export type QuestionProp = {
question: Question,
public_state: Map<string, string | boolean | null>,
- scroll_ref: React.RefObject<HTMLDivElement>
+ scroll_ref: React.RefObject<HTMLDivElement>,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ focus_ref: React.RefObject<any>
}
class RenderedQuestion extends React.Component<QuestionProp> {
@@ -256,7 +258,7 @@ class RenderedQuestion extends React.Component<QuestionProp> {
<h2 css={[selectable, requiredStarStyles]}>
{question.name}<span className={question.required ? "required" : ""}>*</span>
</h2>
- { create_input(this.props, this.handler, this.blurHandler) }
+ { create_input(this.props, this.handler, this.blurHandler, this.props.focus_ref) }
<ErrorMessage show={!valid} message={error} />
<hr css={css`color: gray; margin: 3rem 0;`}/>
</div>;
diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx
index 8e998c5..50f48ba 100644
--- a/src/pages/FormPage.tsx
+++ b/src/pages/FormPage.tsx
@@ -199,7 +199,8 @@ function FormPage(): JSX.Element {
}
const questions = form.questions.map((question, index) => {
- return <RenderedQuestion ref={createRef<RenderedQuestion>()} scroll_ref={createRef<HTMLDivElement>()} question={question} public_state={new Map()} key={index + Date.now()}/>;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ return <RenderedQuestion ref={createRef<RenderedQuestion>()} focus_ref={createRef<any>()} scroll_ref={createRef<HTMLDivElement>()} question={question} public_state={new Map()} key={index + Date.now()}/>;
});
async function handleSubmit(event: SyntheticEvent) {
@@ -223,6 +224,9 @@ function FormPage(): JSX.Element {
const firstErrored = questions[invalidFieldIDs[0]];
if (firstErrored && firstErrored.props.scroll_ref) {
firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" });
+ if (firstErrored.props.focus_ref && firstErrored.props.focus_ref.current) {
+ firstErrored.props.focus_ref.current.focus({ preventScroll: true });
+ }
}
return;
}