From 0870589dab3fa46f59a1d6b128528c570da74cc7 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:14:38 +0200 Subject: Implement before-submit validation (broken, crashing) --- src/pages/FormPage.tsx | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index c49b9fd..6c7cad2 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -2,7 +2,7 @@ import { jsx, css } from "@emotion/react"; import { Link } from "react-router-dom"; -import React, { SyntheticEvent, useEffect, useState } from "react"; +import React, { SyntheticEvent, useEffect, useState, createRef, RefObject } from "react"; import { useParams } from "react-router"; import HeaderBar from "../components/HeaderBar"; @@ -13,6 +13,7 @@ import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; import { unselectable } from "../commonStyles"; +import { Question } from "../api/question"; interface PathParams { @@ -167,12 +168,36 @@ function FormPage(): JSX.Element { return ; } - const questions = form.questions.map((question, index) => { - return ; + const questionsMap: Map = new Map(); + form.questions.map((question, index) => { + questionsMap.set(question.id, ()} scroll_ref={createRef()} question={question} public_state={new Map()} key={index + Date.now()}/>); }); function handleSubmit(event: SyntheticEvent) { - questions.forEach(prop => { + // Client-side required validation + const invalidFieldIds: string[] = []; + questionsMap.forEach((prop, id) => { + const question: Question = prop.props.question; + if (!question.required) { + return; + } + + prop.ref.current.validateField(); + // In case when field is invalid, add this to invalid fields list. + if (prop.props.public_state.get("valid") === false) { + invalidFieldIds.push(id); + } + }); + + if (invalidFieldIds.length) { + const firstErrored = questionsMap.get(invalidFieldIds[0]); + if (firstErrored !== undefined) { + firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); + } + return; + } + + questionsMap.forEach(prop => { const question = prop.props.question; // TODO: Parse input from each question, and submit @@ -192,6 +217,9 @@ function FormPage(): JSX.Element { closed_header =
This form is now closed. You will not be able to submit your response.
; } + const questions: JSX.Element[] = []; + questionsMap.forEach(val => questions.push(val)); + return (
-- cgit v1.2.3 From 4cf4ae1a0195f0e0923ee48b428b94447e8f64b0 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:27:24 +0200 Subject: Add preventDefault to avoid reloading of page --- src/pages/FormPage.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 6c7cad2..1a9b7cf 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -174,6 +174,7 @@ function FormPage(): JSX.Element { }); function handleSubmit(event: SyntheticEvent) { + event.preventDefault(); // Client-side required validation const invalidFieldIds: string[] = []; questionsMap.forEach((prop, id) => { -- cgit v1.2.3 From 3a2338e44b368defe441b91a9c0e60b6a679f871 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:33:35 +0200 Subject: Remove preventDefault from end --- src/pages/FormPage.tsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 1a9b7cf..06d20d6 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -207,8 +207,6 @@ function FormPage(): JSX.Element { console.log(question.id, prop.props.public_state); } }); - - event.preventDefault(); } const open: boolean = form.features.includes(FormFeatures.Open); -- cgit v1.2.3 From 7db4972038dd1c27a75d50cd539f7d3c79e51bee Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 Jan 2021 15:29:49 +0200 Subject: Implement form submitting --- src/pages/FormPage.tsx | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 06d20d6..dc023a6 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -13,7 +13,8 @@ import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; import { unselectable } from "../commonStyles"; -import { Question } from "../api/question"; +import { Question, QuestionType } from "../api/question"; +import ApiClient from "../api/client"; interface PathParams { @@ -173,7 +174,7 @@ function FormPage(): JSX.Element { questionsMap.set(question.id, ()} scroll_ref={createRef()} question={question} public_state={new Map()} key={index + Date.now()}/>); }); - function handleSubmit(event: SyntheticEvent) { + async function handleSubmit(event: SyntheticEvent) { event.preventDefault(); // Client-side required validation const invalidFieldIds: string[] = []; @@ -198,15 +199,41 @@ function FormPage(): JSX.Element { return; } + const answers = {}; questionsMap.forEach(prop => { const question = prop.props.question; + const options: string | string[] = prop.props.question.data["options"]; // TODO: Parse input from each question, and submit switch (question.type) { + case QuestionType.Section: + answers[question.id] = false; + break; + + case QuestionType.Code: + answers[question.id] = ""; + break; + + case QuestionType.Checkbox: + if (typeof options !== "string") { + const keys: Map = new Map(); + options.forEach((val, index) => { + keys.set(val, `${("000" + index).slice(-4)}. ${val}`); + }); + const pairs = {}; + keys.forEach((val, key) => { + pairs[key] = !!prop.props.public_state.get(val); + }); + answers[question.id] = pairs; + } + break; + default: - console.log(question.id, prop.props.public_state); + answers[question.id] = prop.props.public_state.get("value"); } }); + + await ApiClient.post(`forms/submit/${id}`, {response: answers}); } const open: boolean = form.features.includes(FormFeatures.Open); -- cgit v1.2.3 From db9bc59c8b92141e1783629a345a6f7220417123 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 Jan 2021 15:35:07 +0200 Subject: Un-refactor map to array for questions --- src/pages/FormPage.tsx | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index dc023a6..b4a8903 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -169,16 +169,15 @@ function FormPage(): JSX.Element { return ; } - const questionsMap: Map = new Map(); - form.questions.map((question, index) => { - questionsMap.set(question.id, ()} scroll_ref={createRef()} question={question} public_state={new Map()} key={index + Date.now()}/>); + const questions = form.questions.map((question, index) => { + return ()} scroll_ref={createRef()} question={question} public_state={new Map()} key={index + Date.now()}/>; }); async function handleSubmit(event: SyntheticEvent) { event.preventDefault(); // Client-side required validation - const invalidFieldIds: string[] = []; - questionsMap.forEach((prop, id) => { + const invalidFieldIds: number[] = []; + questions.forEach((prop, i) => { const question: Question = prop.props.question; if (!question.required) { return; @@ -187,12 +186,12 @@ function FormPage(): JSX.Element { prop.ref.current.validateField(); // In case when field is invalid, add this to invalid fields list. if (prop.props.public_state.get("valid") === false) { - invalidFieldIds.push(id); + invalidFieldIds.push(i); } }); if (invalidFieldIds.length) { - const firstErrored = questionsMap.get(invalidFieldIds[0]); + const firstErrored = questions[invalidFieldIds[0]]; if (firstErrored !== undefined) { firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); } @@ -200,7 +199,7 @@ function FormPage(): JSX.Element { } const answers = {}; - questionsMap.forEach(prop => { + questions.forEach(prop => { const question = prop.props.question; const options: string | string[] = prop.props.question.data["options"]; @@ -243,9 +242,6 @@ function FormPage(): JSX.Element { closed_header =
This form is now closed. You will not be able to submit your response.
; } - const questions: JSX.Element[] = []; - questionsMap.forEach(val => questions.push(val)); - return (
-- cgit v1.2.3 From a49bb796c7d4eee1f8184be78f1671bdf1cef61d Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Wed, 20 Jan 2021 13:27:21 +0200 Subject: Add state for displaying thanks for submitting showing --- src/commonStyles.tsx | 63 +++++++++++++++++++++++++++++- src/pages/FormPage.tsx | 103 +++++++++++++++++++------------------------------ 2 files changed, 101 insertions(+), 65 deletions(-) (limited to 'src/pages') diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 0cd68d5..3ff2a2f 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -60,11 +60,72 @@ const invalidStyles = css` } `; +const containerStyles = css` + margin: auto; + width: 50%; + + text-align: center; + font-size: 1.5rem; + white-space: nowrap; + + > div { + display: inline-block; + margin: 2rem auto; + width: 50%; + } + + @media (max-width: 850px) { + width: 100%; + + > div { + display: flex; + justify-content: center; + + margin: 0 auto; + } + } + + .return_button { + text-align: left; + } + + .return_button.closed { + text-align: center; + } +`; + +const separatorStyles = css` + height: 0; + display: none; + + @media (max-width: 850px) { + display: block; + } +`; + +const returnStyles = css` + padding: 0.5rem 2rem; + border-radius: 8px; + + color: white; + text-decoration: none; + + background-color: ${colors.greyple}; + transition: background-color 300ms; + + :hover { + background-color: ${colors.darkerGreyple}; + } +`; + export { selectable, unselectable, hiddenInput, multiSelectInput, textInputs, - invalidStyles + invalidStyles, + containerStyles, + separatorStyles, + returnStyles }; diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index b4a8903..cf6947b 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -2,8 +2,9 @@ import { jsx, css } from "@emotion/react"; import { Link } from "react-router-dom"; -import React, { SyntheticEvent, useEffect, useState, createRef, RefObject } from "react"; +import React, { SyntheticEvent, useEffect, useState, createRef } from "react"; import { useParams } from "react-router"; +import { PropagateLoader } from "react-spinners"; import HeaderBar from "../components/HeaderBar"; import RenderedQuestion from "../components/Question"; @@ -12,7 +13,7 @@ import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; -import { unselectable } from "../commonStyles"; +import { unselectable, containerStyles, separatorStyles, returnStyles } from "../commonStyles"; import { Question, QuestionType } from "../api/question"; import ApiClient from "../api/client"; @@ -26,65 +27,6 @@ interface NavigationProps { } class Navigation extends React.Component { - containerStyles = css` - margin: auto; - width: 50%; - - text-align: center; - font-size: 1.5rem; - white-space: nowrap; - - > div { - display: inline-block; - margin: 2rem auto; - width: 50%; - } - - @media (max-width: 850px) { - width: 100%; - - > div { - display: flex; - justify-content: center; - - margin: 0 auto; - } - } - - .return_button { - text-align: left; - } - - .return_button.closed { - text-align: center; - } - `; - - separatorStyles = css` - height: 0; - display: none; - - @media (max-width: 850px) { - display: block; - } - `; - - returnStyles = css` - padding: 0.5rem 2rem; - border-radius: 8px; - - color: white; - text-decoration: none; - - background-color: ${colors.greyple}; - transition: background-color 300ms; - - :hover { - background-color: ${colors.darkerGreyple}; - } - } - `; - submitStyles = css` text-align: right; @@ -118,11 +60,11 @@ class Navigation extends React.Component { } return ( -
+
- Return Home + Return Home
-
+
{ submit }
); @@ -158,6 +100,8 @@ function FormPage(): JSX.Element { const { id } = useParams(); const [form, setForm] = useState
(); + const [sending, setSending] = useState(); + const [sent, setSent] = useState(); useEffect(() => { getForm(id).then(form => { @@ -165,6 +109,33 @@ function FormPage(): JSX.Element { }); }, []); + if (form && sent) { + const thanksStyle = css`font-family: "Uni Sans", "Hind", "Arial", sans-serif;`; + return ( +
+ +
+

Thanks for your response!

+
+ Return Home +
+
+
+
+ ); + } + + if (sending) { + return ( +
+ +
+ +
+
+ ); + } + if (!form) { return ; } @@ -198,6 +169,8 @@ function FormPage(): JSX.Element { return; } + setSending(true); + const answers = {}; questions.forEach(prop => { const question = prop.props.question; @@ -233,6 +206,8 @@ function FormPage(): JSX.Element { }); await ApiClient.post(`forms/submit/${id}`, {response: answers}); + setSending(false); + setSent(true); } const open: boolean = form.features.includes(FormFeatures.Open); -- cgit v1.2.3 From 449a56d91e7208b057a0a5165fbbc2bfadd33ba6 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Thu, 21 Jan 2021 14:34:53 +0200 Subject: Implement dynamic showing of form submitted text --- src/commonStyles.tsx | 2 +- src/pages/FormPage.tsx | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/pages') diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 3ff2a2f..cbfc40a 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -66,7 +66,6 @@ const containerStyles = css` text-align: center; font-size: 1.5rem; - white-space: nowrap; > div { display: inline-block; @@ -109,6 +108,7 @@ const returnStyles = css` color: white; text-decoration: none; + white-space: nowrap; background-color: ${colors.greyple}; transition: background-color 300ms; diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index cf6947b..72b073f 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -29,6 +29,7 @@ interface NavigationProps { class Navigation extends React.Component { submitStyles = css` text-align: right; + white-space: nowrap; button { padding: 0.5rem 4rem; @@ -110,12 +111,13 @@ function FormPage(): JSX.Element { }, []); if (form && sent) { - const thanksStyle = css`font-family: "Uni Sans", "Hind", "Arial", sans-serif;`; + const thanksStyle = css`font-family: "Uni Sans", "Hind", "Arial", sans-serif; margin-top: 250px;`; + const divStyle = css`width: 80%;`; return (
-
-

Thanks for your response!

+
+

{form.submitted_text ?? "Thanks for your response!"}

Return Home
-- cgit v1.2.3 From 8d3469e69d1030b5d83108c6e967bffbb9e1d9a9 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Thu, 21 Jan 2021 20:13:51 +0200 Subject: Use relative units --- src/commonStyles.tsx | 4 ++-- src/components/ErrorMessage.tsx | 6 +++--- src/pages/FormPage.tsx | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/pages') diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index cbfc40a..2caa77e 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -54,8 +54,8 @@ const textInputs = css` const invalidStyles = css` .invalid-box { -webkit-appearance: none; - -webkit-box-shadow: 0 0 10px ${colors.error}; - box-shadow: 0 0 10px ${colors.error}; + -webkit-box-shadow: 0 0 0.6rem ${colors.error}; + box-shadow: 0 0 0.6rem ${colors.error}; border: none; } `; diff --git a/src/components/ErrorMessage.tsx b/src/components/ErrorMessage.tsx index 55e3759..1cf3cbc 100644 --- a/src/components/ErrorMessage.tsx +++ b/src/components/ErrorMessage.tsx @@ -9,9 +9,9 @@ interface ErrorMessageProps { const styles = css` color: ${colors.error}; - font-size: 18px; - line-height: 15px; - margin: 15px 0 0; + font-size: 1.15rem; + line-height: 1.1rem; + margin: 1rem 0 0; `; export default function ErrorMessage(props: ErrorMessageProps): JSX.Element|null { diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 72b073f..21303ab 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -107,11 +107,12 @@ function FormPage(): JSX.Element { useEffect(() => { getForm(id).then(form => { setForm(form); + setSent(true); }); }, []); if (form && sent) { - const thanksStyle = css`font-family: "Uni Sans", "Hind", "Arial", sans-serif; margin-top: 250px;`; + const thanksStyle = css`font-family: "Uni Sans", "Hind", "Arial", sans-serif; margin-top: 15.5rem;`; const divStyle = css`width: 80%;`; return (
-- cgit v1.2.3 From 646469028115dd7005e2a4427d55adc9f4150aa4 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 23 Jan 2021 15:38:11 +0200 Subject: Remove debugging setSent --- src/pages/FormPage.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 21303ab..36ca86f 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -107,7 +107,6 @@ function FormPage(): JSX.Element { useEffect(() => { getForm(id).then(form => { setForm(form); - setSent(true); }); }, []); -- cgit v1.2.3 From e221e20a82411dabc4d6c21172f0c68badc64364 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Thu, 28 Jan 2021 19:31:25 +0200 Subject: Remove unnecessary separator from sent form return home button --- src/commonStyles.tsx | 10 ---------- src/pages/FormPage.tsx | 12 ++++++++++-- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'src/pages') diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 2caa77e..1136b34 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -93,15 +93,6 @@ const containerStyles = css` } `; -const separatorStyles = css` - height: 0; - display: none; - - @media (max-width: 850px) { - display: block; - } -`; - const returnStyles = css` padding: 0.5rem 2rem; border-radius: 8px; @@ -126,6 +117,5 @@ export { textInputs, invalidStyles, containerStyles, - separatorStyles, returnStyles }; diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 36ca86f..abb008f 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -13,7 +13,7 @@ import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; -import { unselectable, containerStyles, separatorStyles, returnStyles } from "../commonStyles"; +import { unselectable, containerStyles, returnStyles } from "../commonStyles"; import { Question, QuestionType } from "../api/question"; import ApiClient from "../api/client"; @@ -27,6 +27,15 @@ interface NavigationProps { } class Navigation extends React.Component { + separatorStyles = css` + height: 0; + display: none; + + @media (max-width: 850px) { + display: block; + } + `; + submitStyles = css` text-align: right; white-space: nowrap; @@ -121,7 +130,6 @@ function FormPage(): JSX.Element {
Return Home
-
); -- cgit v1.2.3 From 978754f9bc81d0d836ddea6656af4a3dadce5248 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Thu, 28 Jan 2021 19:34:15 +0200 Subject: Move container and return styles back to FormPage --- src/commonStyles.tsx | 53 +------------------------------------------------- src/pages/FormPage.tsx | 52 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 54 deletions(-) (limited to 'src/pages') diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 1136b34..57002a9 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -60,62 +60,11 @@ const invalidStyles = css` } `; -const containerStyles = css` - margin: auto; - width: 50%; - - text-align: center; - font-size: 1.5rem; - - > div { - display: inline-block; - margin: 2rem auto; - width: 50%; - } - - @media (max-width: 850px) { - width: 100%; - - > div { - display: flex; - justify-content: center; - - margin: 0 auto; - } - } - - .return_button { - text-align: left; - } - - .return_button.closed { - text-align: center; - } -`; - -const returnStyles = css` - padding: 0.5rem 2rem; - border-radius: 8px; - - color: white; - text-decoration: none; - white-space: nowrap; - - background-color: ${colors.greyple}; - transition: background-color 300ms; - - :hover { - background-color: ${colors.darkerGreyple}; - } -`; - export { selectable, unselectable, hiddenInput, multiSelectInput, textInputs, - invalidStyles, - containerStyles, - returnStyles + invalidStyles }; diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index abb008f..de80e8a 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -13,10 +13,58 @@ import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; -import { unselectable, containerStyles, returnStyles } from "../commonStyles"; +import { unselectable } from "../commonStyles"; import { Question, QuestionType } from "../api/question"; import ApiClient from "../api/client"; +const containerStyles = css` + margin: auto; + width: 50%; + + text-align: center; + font-size: 1.5rem; + + > div { + display: inline-block; + margin: 2rem auto; + width: 50%; + } + + @media (max-width: 850px) { + width: 100%; + + > div { + display: flex; + justify-content: center; + + margin: 0 auto; + } + } + + .return_button { + text-align: left; + } + + .return_button.closed { + text-align: center; + } +`; + +const returnStyles = css` + padding: 0.5rem 2rem; + border-radius: 8px; + + color: white; + text-decoration: none; + white-space: nowrap; + + background-color: ${colors.greyple}; + transition: background-color 300ms; + + :hover { + background-color: ${colors.darkerGreyple}; + } +`; interface PathParams { id: string @@ -74,7 +122,7 @@ class Navigation extends React.Component {
Return Home
-
+
{ submit }
); -- cgit v1.2.3 From ff1e4bc4d37fb55aeb5b33cbb8b4f640e9fc745e Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:31:29 +0200 Subject: Improve and simplify checkboxes gathering Co-authored-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- src/pages/FormPage.tsx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index de80e8a..b8518c0 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -244,19 +244,18 @@ function FormPage(): JSX.Element { answers[question.id] = ""; break; - case QuestionType.Checkbox: - if (typeof options !== "string") { - const keys: Map = new Map(); - options.forEach((val, index) => { - keys.set(val, `${("000" + index).slice(-4)}. ${val}`); - }); - const pairs = {}; - keys.forEach((val, key) => { - pairs[key] = !!prop.props.public_state.get(val); - }); - answers[question.id] = pairs; - } + case QuestionType.Checkbox: { + const parsed = new Map(); + + prop.props.public_state.forEach((value, key) => { + if (key !== "valid" && key !== "error") { + answers.set(key.slice(6), value); + } + }); + + answers[question.id] = parsed; break; + } default: answers[question.id] = prop.props.public_state.get("value"); -- cgit v1.2.3 From c9d423d99a0eb4be2b4cc808ae11e42fc2cd04de Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:45:33 +0200 Subject: Simplify if check --- src/pages/FormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index b8518c0..0023db4 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -221,7 +221,7 @@ function FormPage(): JSX.Element { if (invalidFieldIds.length) { const firstErrored = questions[invalidFieldIds[0]]; - if (firstErrored !== undefined) { + if (firstErrored) { firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); } return; -- cgit v1.2.3 From c7711d4d14cfb8bd99ab066bf53ed5ef6efe6a9c Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:47:58 +0200 Subject: Add nullability check for ref --- src/pages/FormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 0023db4..e8d1a4b 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -221,7 +221,7 @@ function FormPage(): JSX.Element { if (invalidFieldIds.length) { const firstErrored = questions[invalidFieldIds[0]]; - if (firstErrored) { + if (firstErrored && firstErrored.props.scroll_ref) { firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); } return; -- cgit v1.2.3 From ee94923ffbe84361d1b8d219a8ed2e1d7a08e6a2 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:55:46 +0200 Subject: Improve submit data gathering --- src/pages/FormPage.tsx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index e8d1a4b..ab74be9 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -229,10 +229,9 @@ function FormPage(): JSX.Element { setSending(true); - const answers = {}; + const answers: { [key: string]: unknown } = {}; questions.forEach(prop => { - const question = prop.props.question; - const options: string | string[] = prop.props.question.data["options"]; + const question: Question = prop.props.question; // TODO: Parse input from each question, and submit switch (question.type) { @@ -240,16 +239,12 @@ function FormPage(): JSX.Element { answers[question.id] = false; break; - case QuestionType.Code: - answers[question.id] = ""; - break; - case QuestionType.Checkbox: { - const parsed = new Map(); + const parsed: { [key: string]: unknown } = {}; - prop.props.public_state.forEach((value, key) => { + prop.props.public_state.forEach((value: unknown, key: string) => { if (key !== "valid" && key !== "error") { - answers.set(key.slice(6), value); + parsed[key.slice(6)] = value; } }); @@ -257,6 +252,7 @@ function FormPage(): JSX.Element { break; } + case QuestionType.Code: default: answers[question.id] = prop.props.public_state.get("value"); } -- cgit v1.2.3 From 4cd5c97fa8db2809c796f89062d06eade582ea55 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 18:01:08 +0200 Subject: Rename invalid field IDs variable --- src/pages/FormPage.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/pages') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index ab74be9..8e998c5 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -205,7 +205,7 @@ function FormPage(): JSX.Element { async function handleSubmit(event: SyntheticEvent) { event.preventDefault(); // Client-side required validation - const invalidFieldIds: number[] = []; + const invalidFieldIDs: number[] = []; questions.forEach((prop, i) => { const question: Question = prop.props.question; if (!question.required) { @@ -215,12 +215,12 @@ function FormPage(): JSX.Element { prop.ref.current.validateField(); // In case when field is invalid, add this to invalid fields list. if (prop.props.public_state.get("valid") === false) { - invalidFieldIds.push(i); + invalidFieldIDs.push(i); } }); - if (invalidFieldIds.length) { - const firstErrored = questions[invalidFieldIds[0]]; + if (invalidFieldIDs.length) { + const firstErrored = questions[invalidFieldIDs[0]]; if (firstErrored && firstErrored.props.scroll_ref) { firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); } -- cgit v1.2.3 From 7075e8579e5aa038438be9bbb2ba275d52c20910 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 8 Feb 2021 19:29:37 +0200 Subject: Implement focusing text fields if empty on submit --- src/components/InputTypes/ShortText.tsx | 6 ++++-- src/components/InputTypes/TextArea.tsx | 6 ++++-- src/components/InputTypes/index.tsx | 9 +++++---- src/components/Question.tsx | 6 ++++-- src/pages/FormPage.tsx | 6 +++++- 5 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src/pages') 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) => void, blurHandler: (event: FocusEvent) => void, - valid: boolean + valid: boolean, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + focus_ref: React.RefObject } export default function ShortText(props: ShortTextProps): JSX.Element { return (
- +
); } 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) => void, onBlurHandler: (event: FocusEvent) => void, - valid: boolean + valid: boolean, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + focus_ref: React.RefObject } const styles = css` @@ -21,7 +23,7 @@ const styles = css` export default function TextArea(props: TextAreaProps): JSX.Element { return (
-