diff --git a/package.json b/package.json index 4be4dba..aed6639 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "draft-js": "^0.11.7", "draftjs-to-html": "^0.9.1", "firebase": "^9.6.7", - "framer-motion": "^4.0.0", "hammerjs": "^2.0.8", "json-schema": "^0.4.0", "lodash": "^4.17.21", diff --git a/src/components/commonForm/CommonForm.tsx b/src/components/commonForm/CommonForm.tsx index 3b696a6..ee23ed3 100644 --- a/src/components/commonForm/CommonForm.tsx +++ b/src/components/commonForm/CommonForm.tsx @@ -60,6 +60,29 @@ const CommonForm: React.FC = props => { }, [props.schema, props.commonDefinitionsSchema]); const uiSchema: JSONSchema7 = useMemo(() => JSON.parse(props.uiSchema), [props.uiSchema]); + const validateEssayWordCount = (formData: any, errors: any) => { + if (formData.essays.length !== 0) { + const schema = JSON.parse(props.schema); + const { essays } = formData; + // eslint-disable-next-line guard-for-in + for (const topic in essays) { + let s = essays[topic] !== undefined ? essays[topic] : ""; + + // Credit: https://stackoverflow.com/questions/18679576/counting-words-in-string + s = s.replace(/(^\s*)|(\s*$)/gi, ""); // exclude start and end white-space + s = s.replace(/[ ]{2,}/gi, " "); // 2 or more space to 1 + s = s.replace(/\n /, "\n"); // exclude newline with a start spacing + const curWordCount = s.split(" ").filter((str: string) => str !== "").length; + + const topicWordCount = schema.properties.essays?.properties[topic].wordCount || 100; + if (curWordCount > topicWordCount) { + errors.essays[topic].addError(`Essay cannot be over ${topicWordCount} words`); + } + } + } + return errors; + }; + return (
= props => { noHtml5Validate showErrorList={false} transformErrors={transformErrors} + validate={validateEssayWordCount} > {props.children}
diff --git a/src/components/commonForm/widgets/EssayWidget.tsx b/src/components/commonForm/widgets/EssayWidget.tsx index 8ba85dd..ff02852 100644 --- a/src/components/commonForm/widgets/EssayWidget.tsx +++ b/src/components/commonForm/widgets/EssayWidget.tsx @@ -21,9 +21,6 @@ const getWordCount = (value?: string) => { return curWordCount; }; -// TODO: Make this a dynamic value -const WORD_COUNT_LIMIT = 100; - const EssayWidget: React.FC = props => { const _onChange = ({ target: { value } }: React.ChangeEvent) => props.onChange(value === "" ? props.options.emptyValue : value); @@ -33,6 +30,7 @@ const EssayWidget: React.FC = props => { props.onFocus(props.id, value); const wordCount = getWordCount(props.value); + const wordCountLimit = (props.schema as any).wordCount || 100; return ( = props => { onBlur={_onBlur} onFocus={_onFocus} /> - WORD_COUNT_LIMIT ? "red" : "gray"} marginTop="5px"> - {wordCount} / {WORD_COUNT_LIMIT} words + wordCountLimit ? "red" : "gray"} marginTop="5px"> + {wordCount} / {wordCountLimit} words ); diff --git a/yarn.lock b/yarn.lock index d648cf5..232320a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7072,19 +7072,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -framer-motion@^4.0.0: - version "4.1.17" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.17.tgz#4029469252a62ea599902e5a92b537120cc89721" - integrity sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw== - dependencies: - framesync "5.3.0" - hey-listen "^1.0.8" - popmotion "9.3.6" - style-value-types "4.1.4" - tslib "^2.1.0" - optionalDependencies: - "@emotion/is-prop-valid" "^0.8.2" - framesync@5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/framesync/-/framesync-5.3.0.tgz#0ecfc955e8f5a6ddc8fdb0cc024070947e1a0d9b"