Skip to content

Commit

Permalink
Added multiple choice type - copied from CeMaFac (#138)
Browse files Browse the repository at this point in the history
* Added multiple choice type - copied from CeMaFac

* Added other type as an input

* Added styling

* Fix the import

* Improving styling

* Version bump
  • Loading branch information
mmircea16 authored Apr 4, 2020
1 parent 98e979f commit d15acc5
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@code4ro/taskforce-fe-components",
"version": "1.0.7",
"version": "1.0.8",
"private": false,
"dependencies": {
"bulma": "^0.8.0",
Expand Down
20 changes: 20 additions & 0 deletions src/components/form/decisionTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,26 @@ export default {
},
{
questionId: 6,
questionText: "Ce simptome ai?",
type: "MULTIPLE_CHOICE",
options: [
{
label: "Tuse",
value: 0
},
{
label: "Febra",
value: 1
},
{
type: "OTHER",
label: "Altele",
value: 2
}
]
},
{
questionId: 7,
type: "FINAL",
questionText: "Ce trebuie sa faci?",
options: [
Expand Down
19 changes: 17 additions & 2 deletions src/components/form/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Button } from "../button/button";
import StaticText from "./staticText";
import { groupBy, mapObject } from "underscore";
import FreeText from "./freeText";
import MultipleChoice from "./multipleChoice";

const FIRST_NODE = 1;

Expand Down Expand Up @@ -68,6 +69,15 @@ export const Form = ({ data, evaluateForm, onFinishingForm }) => {
/>
);
}
case "MULTIPLE_CHOICE": {
return (
<MultipleChoice
question={currentQuestion}
currentResponse={formState[currentQuestion.questionId]}
onAnswer={answerCurrentQuestion}
/>
);
}
case "FREE_TEXT": {
return (
<FreeText
Expand All @@ -91,7 +101,7 @@ export const Form = ({ data, evaluateForm, onFinishingForm }) => {
};

const getNextQuestionForOptionValue = (question, optionValue) => {
if (question.type === "FREE_TEXT") {
if (question.type === "FREE_TEXT" || question.type === "MULTIPLE_CHOICE") {
return;
}
const selectedOption = question.options.find(
Expand Down Expand Up @@ -222,7 +232,12 @@ Form.propTypes = {
PropTypes.shape({
questionId: PropTypes.number.isRequired,
questionText: PropTypes.string.isRequired,
type: PropTypes.oneOf(["FINAL", "SINGLE_CHOICE", "FREE_TEXT"]),
type: PropTypes.oneOf([
"FINAL",
"SINGLE_CHOICE",
"MULTIPLE_CHOICE",
"FREE_TEXT"
]),
options: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string.isRequired,
Expand Down
38 changes: 36 additions & 2 deletions src/components/form/form.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ListItem } from "../list-item/list-item";
import { Form } from "./form";
import SingleChoice from "./singleChoice";
import FreeText from "./freeText";
import MultipleChoice from "./multipleChoice";

const clickOnNext = form => {
const forwardButton = form.find(".forward");
Expand All @@ -17,8 +18,13 @@ const writeInFreeText = (form, text) => {
};

const clickOnSingleChoice = (form, choice) => {
const yesAnswer = form.find(SingleChoice).find({ title: choice });
yesAnswer.simulate("click");
const answer = form.find(SingleChoice).find({ title: choice });
answer.simulate("click");
};

const clickOnMultipleChoice = (form, choice) => {
const answer = form.find(MultipleChoice).find({ title: choice });
answer.simulate("click");
};

function startForm(form) {
Expand Down Expand Up @@ -60,6 +66,25 @@ describe("Form", () => {
},
{
questionId: 2,
questionText: "Ce simptome ai?",
type: "MULTIPLE_CHOICE",
options: [
{
label: "Tuse",
value: 0
},
{
label: "Febra",
value: 1
},
{
label: "Dureri de cap",
value: 2
}
]
},
{
questionId: 3,
questionText: "Done!",
type: "FINAL",
options: [
Expand All @@ -86,6 +111,10 @@ describe("Form", () => {
clickOnSingleChoice(form, "Da");
clickOnNext(form);

clickOnMultipleChoice(form, "Febra");
clickOnMultipleChoice(form, "Tuse");
clickOnNext(form);

expectHeaderText(form, "Done!");

const actualAnswers = mockFinishingForm.mock.calls[0][0].answers;
Expand All @@ -94,6 +123,11 @@ describe("Form", () => {
id: 1,
questionText: "Ai peste 60 de ani?",
answer: "1"
},
{
id: 2,
questionText: "Ce simptome ai?",
answer: "1,0"
}
]);
});
Expand Down
99 changes: 99 additions & 0 deletions src/components/form/multipleChoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { ListHeader } from "../list-header/list-header";
import { List } from "../list/list";
import { ListItem } from "../list-item/list-item";
import { Input } from "../input/input";
import "./multipleChoice.scss";

function MultipleChoice({ question, onAnswer, currentResponse = [] }) {
const [answers, setAnswers] = useState([]);
const isSelected = option => {
return currentResponse.includes(option.value);
};

const handleClick = option => {
let newAnswers;
if (answers.includes(option.value)) {
newAnswers = answers.filter(item => item !== option.value);
} else {
newAnswers = [...answers, option.value];
}
setAnswers(newAnswers);
onAnswer({
questionId: question.questionId,
value: newAnswers
});
};

const onInputForOther = event => {
let newValueForAnswers = [...answers];
if (event.target.value !== "") {
newValueForAnswers = [...answers, event.target.value];
}

onAnswer({
questionId: question.questionId,
value: newValueForAnswers
});
};

const choiceFor = option => {
if (option.type === "OTHER") {
const size = currentResponse.length;
let existingValue = "";
if (size > 0 && isNaN(currentResponse[size - 1])) {
existingValue = currentResponse[size - 1];
}
return (
<div className={"__list-item other"}>
<Input
key={`answer_${question.questionId}_${option.value}`}
usePlaceholder={false}
onChange={onInputForOther}
defaultValue={existingValue}
label={option.label}
/>
</div>
);
}

return (
<ListItem
key={`answer_${question.questionId}_${option.value}`}
title={option.label}
active={isSelected(option)}
onClick={() => handleClick(option)}
/>
);
};
return (
<div>
<ListHeader title={question.questionText} />
<div>
<List>{question.options.map(option => choiceFor(option))}</List>
</div>
</div>
);
}
MultipleChoice.propTypes = {
question: PropTypes.shape({
questionId: PropTypes.number.isRequired,
questionText: PropTypes.string.isRequired,
type: PropTypes.oneOf([
"FINAL",
"SINGLE_CHOICE",
"MULTIPLE_CHOICE",
"FREE_TEXT"
]),
options: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.number.isRequired
})
)
}),
onAnswer: PropTypes.func,
currentResponse: PropTypes.arrayOf(PropTypes.number)
};
export default MultipleChoice;
3 changes: 3 additions & 0 deletions src/components/form/multipleChoice.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.other > .field {
width: 100%
}
Loading

1 comment on commit d15acc5

@vercel
Copy link

@vercel vercel bot commented on d15acc5 Apr 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.