fix: corner cases for new option empty and duplicates in single and multi select

This commit is contained in:
ShubhamPalriwala
2023-09-06 23:33:15 +05:30
parent 4320e36ed3
commit 284361aaba
3 changed files with 52 additions and 11 deletions

View File

@@ -34,7 +34,7 @@ export default function MultipleChoiceMultiForm({
const [isNew, setIsNew] = useState(true);
const [showSubheader, setShowSubheader] = useState(!!question.subheader);
const questionRef = useRef<HTMLInputElement>(null);
const [isInvalidValue, setIsInvalidValue] = useState<string>("");
const [isInvalidValue, setIsInvalidValue] = useState<string | null>(null);
const shuffleOptionsTypes = {
none: {
@@ -89,6 +89,13 @@ export default function MultipleChoiceMultiForm({
return null;
};
const findEmptyLabel = () => {
for (let i = 0; i < question.choices.length; i++) {
if (question.choices[i].label.trim() === "") return true;
}
return false;
};
const addChoice = (choiceIdx?: number) => {
setIsNew(false); // This question is no longer new.
let newChoices = !question.choices ? [] : question.choices;
@@ -125,6 +132,9 @@ export default function MultipleChoiceMultiForm({
const newChoices = !question.choices ? [] : question.choices.filter((_, idx) => idx !== choiceIdx);
const choiceValue = question.choices[choiceIdx].label;
if (isInvalidValue === choiceValue) {
setIsInvalidValue(null);
}
let newLogic: any[] = [];
question.logic?.forEach((logic) => {
let newL: string | string[] | undefined = logic.value;
@@ -215,13 +225,16 @@ export default function MultipleChoiceMultiForm({
const duplicateLabel = findDuplicateLabel();
if (duplicateLabel) {
setIsInvalidValue(duplicateLabel);
} else {
} else if (findEmptyLabel()) {
setIsInvalidValue("");
} else {
setIsInvalidValue(null);
}
}}
isInvalid={
(isInValid != null && question.choices[choiceIdx].label.trim() === "") ||
(isInvalidValue !== null && choice.label.trim() === isInvalidValue.trim())
isInValid &&
((isInvalidValue === "" && choice.label.trim() === "") ||
(isInvalidValue !== null && choice.label.trim() === isInvalidValue.trim()))
}
/>
{question.choices && question.choices.length > 2 && (

View File

@@ -33,6 +33,7 @@ export default function MultipleChoiceSingleForm({
const lastChoiceRef = useRef<HTMLInputElement>(null);
const [isNew, setIsNew] = useState(true);
const [showSubheader, setShowSubheader] = useState(!!question.subheader);
const [isInvalidValue, setIsInvalidValue] = useState<string | null>(null);
const questionRef = useRef<HTMLInputElement>(null);
const shuffleOptionsTypes = {
@@ -53,6 +54,24 @@ export default function MultipleChoiceSingleForm({
},
};
const findDuplicateLabel = () => {
for (let i = 0; i < question.choices.length; i++) {
for (let j = i + 1; j < question.choices.length; j++) {
if (question.choices[i].label.trim() === question.choices[j].label.trim()) {
return question.choices[i].label.trim(); // Return the duplicate label
}
}
}
return null;
};
const findEmptyLabel = () => {
for (let i = 0; i < question.choices.length; i++) {
if (question.choices[i].label.trim() === "") return true;
}
return false;
};
const updateChoice = (choiceIdx: number, updatedAttributes: { label: string }) => {
const newLabel = updatedAttributes.label;
const oldLabel = question.choices[choiceIdx].label;
@@ -113,6 +132,9 @@ export default function MultipleChoiceSingleForm({
const newChoices = !question.choices ? [] : question.choices.filter((_, idx) => idx !== choiceIdx);
const choiceValue = question.choices[choiceIdx].label;
if (isInvalidValue === choiceValue) {
setIsInvalidValue(null);
}
let newLogic: any[] = [];
question.logic?.forEach((logic) => {
let newL: string | string[] | undefined = logic.value;
@@ -198,15 +220,21 @@ export default function MultipleChoiceSingleForm({
value={choice.label}
className={cn(choice.id === "other" && "border-dashed")}
placeholder={choice.id === "other" ? "Other" : `Option ${choiceIdx + 1}`}
onBlur={() => {
const duplicateLabel = findDuplicateLabel();
if (duplicateLabel) {
setIsInvalidValue(duplicateLabel);
} else if (findEmptyLabel()) {
setIsInvalidValue("");
} else {
setIsInvalidValue(null);
}
}}
onChange={(e) => updateChoice(choiceIdx, { label: e.target.value })}
isInvalid={
isInValid &&
(choice.label.trim() === "" ||
question.choices.some((element, index) =>
question.choices
.slice(index + 1)
.some((nextElement) => nextElement.label.trim() === element.label.trim())
))
((isInvalidValue === "" && choice.label.trim() === "") ||
(isInvalidValue !== null && choice.label.trim() === isInvalidValue.trim()))
}
/>
{question.choices && question.choices.length > 2 && (

View File

@@ -23,7 +23,7 @@ export default function UpdateQuestionId({ localSurvey, question, questionIdx, u
toast.error("IDs have to be unique per survey.");
} else if (currentValue.trim() === "" || currentValue.includes(" ")) {
setIsInputInvalid(true);
toast.error("ID should not contain space.");
toast.error("ID should not be empty.");
} else {
setIsInputInvalid(false);
toast.success("Question ID updated.");