I am having a trouble here, I created a choices wherein if the user clicked the Other's
button, the TextField will be open, but the problem is, when I click the Others
button again, it will not closed.
What I want here is keep the TextField Open, as long as the button is highlighted and close it when the user
unclicked` it
In this image, I clicked it, so It will open
But when I clicked it again.
It is still open.
So what I did here is I rendered the Question
as well as the Choices
, and check if the choices's essay === true
, then show the TextField
{
"_id": "642d892955e310c62e46b9d3",
"title": "Question Sample",
"choices": [
{
"choices": "GAD Orientation",
"essay": false,
},
{
"choices": "Gender Sensitivity Training",
"essay": false,
},
{
"choices": "Gender Mainstreaming",
"essay": false,
},
{
"choices": "GAD Planning and Budgeting",
"essay": false,
},
{
"choices": "GAD Analysis Tools",
"essay": false,
},
{
"choices": "Harmonized Gender and Development Guidelines",
"essay": false,
},
{
"choices": "Gender Mainstreaming Evaluation Framework",
"essay": false,
},
{
"choices": "Others, enumerate",
"essay": true,
},
{
"choices": "None",
"essay": false,
}
],
"type_of_question": true,
}
So what I did here is, I checked the choice.essay === true
then Open it.
Part4.js
const [openChoiceId, setOpenChoiceId] = useState(null);
const handleClick = (choice) => {
if (choice.essay === true) {
setOpenChoiceId(choice.choices);
} else {
}
};
{currentChoices.map((choice, index) =>(
<Grid item xs={6} key={index}>
<label className="toggle-button" key={choice.id} onClick={() => handleClick(choice)}>
<input className="toggle-button__state" type="checkbox" name="choice" value={choice.choices} onChange={handleChange}/>
<span className="toggle-button__text">{choice.choices}</span>
<Box sx={{position:'absolute', bottom: 50, left: 0, width: '100%', px: 2}}>
{openChoiceId === choice.choices && choice.essay === true &&
<TextField
id="filled-multiline-static"
label="Others"
fullWidth
multiline
rows={3}
name="essay" onChange={handleTextFieldChange}
variant="outlined"
/>}
</Box>
</label>
</Grid>
))}
EDIT:
When I tried this.
const handleClick = (choice) => {
setOpenChoiceId(choice.choices);
};
Additional Info
I created a codesandbox here, I hope this one helps
https://codesandbox.io/s/pensive-star-wj57um?file=/src/sampleData.js
HandleChange comes from my parent component, so this is how it looks like
const [answer,setAnswer] = useState({
email: email,
category: type,
affiliation: affiliation,
part: `part${getSurveyPart}`,
choice: "",
essay: "",
})
HandleChange.js
const handleChange = (e) => {
const value = e.target.value;
const inputType = e.target.type;
let newChoice = answer.choice; // initialize newChoice with the current choice array
if (inputType === 'radio') {
newChoice = [value];
} else if (inputType === 'checkbox') {
const isChecked = e.target.checked;
const choiceIndex = answer.choice.indexOf(value);
if (isChecked) {
newChoice = [...answer.choice, value];
} else {
newChoice = [
...answer.choice.slice(0, choiceIndex),
...answer.choice.slice(choiceIndex + 1),
];
}
}
const newAnswer = { ...answer, choice: newChoice };
setAnswer(newAnswer);
};
4
Answers
From the edited code it looks like you are selecting multiple choices and when you select other you need to have the input shown up. You can do something like below to achieve this.
And in the JSX
I think you just need a simple boolean state and based on the selected choice you can toggle its value.
Replace
With
and condition to show text field should be replaced with
Listen to change event instead of click like below
Final code
When you click any of the buttons, make sure initially to set all "choices.essay" value to false. You can do it by:
Then, you either open or close the essay textarea on button click. If the essay is true, you set to false. If essay value is false, you set to true.
And, when you render component, make sure to render it by only when "choice.essay === true". You can remove "openChoiceId === choice.choice" statement. It goes like this
there are multiple thing you that needs to be fixed
first you are not checking wether the checkbox is actually checked or not so you can either remove it or add it to the state
i removed the span with the text and instead added a label with an htmlFor
so whenever you click on the text it clicks on the actual checkbox
and right now the onClick event handler need to be on the checkbox not the label
last thing is that you are doing a wrong conditional statement
to display the textField you need to be checking against the state and not what you were doing previously
also the conditional chaining
.?
is because the openChoiceId will be set to an empty when the none of checkboxes are checked and will be an object and won’t have essay as a property