Skip to content

Commit 740a7b8

Browse files
feat(form): add validation to NumericalInput to accept only numeric values
1 parent 36c9eba commit 740a7b8

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/AnswerOption.jsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { FeedbackBox } from './components/Feedback';
1818
import * as hooks from './hooks';
1919
import { ProblemTypeKeys } from '../../../../../data/constants/problem';
2020
import ExpandableTextArea from '../../../../../sharedComponents/ExpandableTextArea';
21-
import { answerRangeFormatRegex } from '../../../data/OLXParser';
21+
import { answerRangeFormatRegex, numericRegex } from '../../../data/OLXParser';
2222

2323
const AnswerOption = ({
2424
answer,
@@ -53,6 +53,10 @@ const AnswerOption = ({
5353
const cleanedValue = value.replace(/^\s+|\s+$/g, '');
5454
return !cleanedValue.length || answerRangeFormatRegex.test(cleanedValue);
5555
};
56+
const validateAnswerNumeric = (value) => {
57+
const cleanedValue = (value ?? '').trim();
58+
return !cleanedValue.length || numericRegex.test(cleanedValue);
59+
}
5660

5761
const getInputArea = () => {
5862
if ([ProblemTypeKeys.SINGLESELECT, ProblemTypeKeys.MULTISELECT].includes(problemType)) {
@@ -70,16 +74,26 @@ const AnswerOption = ({
7074
);
7175
}
7276
if (problemType !== ProblemTypeKeys.NUMERIC || !answer.isAnswerRange) {
77+
const isValidValue = validateAnswerNumeric(answer.title)
7378
return (
74-
<Form.Control
75-
as="textarea"
76-
className="answer-option-textarea text-gray-500 small"
77-
autoResize
78-
rows={1}
79-
value={answer.title}
80-
onChange={setAnswerTitle}
81-
placeholder={intl.formatMessage(messages.answerTextboxPlaceholder)}
82-
/>
79+
<Form.Group isInvalid={!isValidValue}>
80+
<Form.Control
81+
as="textarea"
82+
className="answer-option-textarea text-gray-500 small"
83+
autoResize
84+
rows={1}
85+
value={answer.title}
86+
onChange={setAnswerTitle}
87+
placeholder={intl.formatMessage(messages.answerTextboxPlaceholder)}
88+
89+
/>
90+
{!isValidValue && (
91+
<Form.Control.Feedback type="invalid">
92+
<FormattedMessage {...messages.AnswerNumericErrorText} />
93+
</Form.Control.Feedback>
94+
)}
95+
96+
</Form.Group>
8397
);
8498
}
8599
// Return Answer Range View

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/messages.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ const messages = defineMessages({
8282
defaultMessage: 'Error: Invalid range format. Use brackets or parentheses with values separated by a comma.',
8383
description: 'Error text describing wrong format of answer ranges',
8484
},
85+
AnswerNumericErrorText: {
86+
id: 'authoring.answerwidget.answer.answerNumericErrorText',
87+
defaultMessage: 'Error: This problem type only supports numeric answers. Did you mean to make a (Text/Math Expression) Input problem?',
88+
description: 'Error numeric describing wrong format',
89+
}
8590
});
8691

8792
export default messages;

src/editors/containers/ProblemEditor/data/OLXParser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export const responseKeys = [
9696
* []
9797
*/
9898
export const answerRangeFormatRegex = /^[([]\s*-?(?:\d+(?:\.\d+)?|\d+\/\d+)\s*,\s*-?(?:\d+(?:\.\d+)?|\d+\/\d+)\s*[)\]]$/m;
99-
99+
export const numericRegex = /^[+-]?(\d+(\.\d*)?|\.\d+)$/;
100100
export const stripNonTextTags = ({ input, tag }) => {
101101
const stripedTags = {};
102102
Object.entries(input).forEach(([key, value]) => {

0 commit comments

Comments
 (0)