'Close accordions on radio button click
I have an accordion component in my React Native app which is from galio framework . I have populated it with api data. The accordion closes if you click in the title but I want it to close when I select a radio button. Here is my code:
const Step3 = () => {
const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState([]);
const [icon, setIcons] = useState([]);
const [iconColor, setIconsColor] = useState([])
const [refreshing, setRefreshing] = useState(true);
const getQuestions = async () => {
const locale = i18next.language; // TODO: get current locale
const response = await apiStandarts.get(`/questions?locale=${locale}`, {
params: { active: 1, _sortId: [1,2] , _sort: "sortId:ASC"},
});
setRefreshing(false)
setQuestions(response.data);
};
const isOptionSelected = (option) => {
const answer = answers[option.question];
if (answer) {
return option.id == answer.id;
}
return false;
};
const questionIcon = async () => {
const response = await apiStandarts.get(`/commitments-icons`);
setIcons(response.data)
}
const questionIconColor = async () => {
const response = await apiStandarts.get(`/commitments`);
setIconsColor(response.data)
}
const objectMap = (obj, fn) =>
Object.fromEntries(
Object.entries(obj).map(([k, v], i) => [k, fn(v, k, i)])
);
const newAnswers = objectMap(answers, (item) => {
return [item.id, item.description];
});
// useEffect(() => {
// questionIcon();
// }, []);
useEffect(() => {
questionIcon();
getQuestions();
}, []);
const OptionList = (groupOption) => {
return (
groupOption.options.map((item, index) => {
const clickedRadio = () => {
const selectedOption = { [item.question]: { ...item } };
setAnswers({ ...answers, ...selectedOption });
};
let status = isOptionSelected(item) ? true : false;
return (
<Radio
initialValue={status}
label={item.description}
onChange={() => clickedRadio()}
color="rgba(0,0,0,.54)"
radioInnerStyle={{backgroundColor: "#3671a6"}}
labelStyle={ styles.label}
containerStyle={{ width: 300, padding: 5 }}
/>
);
})
);
};
return (
<View style={styles.container}>
<Text style={{ fontWeight: "bold", fontSize: 12, color: "#6B24" }}>
{t("Choose an option/Scroll for more questions")}
</Text>
<FlatList
data={questions}
keyExtractor={(result) => result.id.toString()}
contentContainerStyle={{ padding: 5, paddingBottom: 5 }}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={getQuestions} />}
renderItem={({ item, index }) => {
const arr = [item.commitments[0].commitment_icon];
const questIcon = arr.filter(i => Boolean(i)).map(id => icon.find(o => o.id === id)?.image?.url);
const imgUrl = APIURL + questIcon;
function iconBgColor(){
let bgColor
switch (item.commitments[0].commitment_icon) {
case 1:
bgColor="#78bad3"
break;
case 3:
bgColor = "#027a95"
break;
case 6:
bgColor = "#027a95"
break;
case 4:
bgColor = '#1fc191'
break;
case 5:
bgColor = '#78bad3'
break;
case 2:
bgColor = "#e4da4d"
break;
case 7:
bgColor = "#1fc191"
break;
default:
bgColor= "#fff"
break;
}
return bgColor;
}
const backgroundColor = iconBgColor(item.commitments[0].commitment_icon)
const data = [
{
title: (<>
<View style={[styles.iconWrapper,{backgroundColor: backgroundColor}]}>
{
imgUrl.indexOf('.svg') > 0 ? <SvgUri uri={APIURL + questIcon} height={20} width={20} style={styles.iconColor}/> : null
}
</View>
<Text style={styles.text}>{item.sortId}.</Text>
<Text style={styles.text} key={item.description}>{item.description}</Text>
</>),
content:<View><OptionList key={item?.question_options.id} options={item?.question_options}></OptionList></View>
},
];
return (
<View style={styles.groupOptions} key={index}>
<Accordion style={styles.accordion} headerStyle={styles.headerStyle} contentStyle={styles.contentStyle} dataArray={data} opened={index} />
</View>
);
}}
/>
</View>
);
};
Any ideas how to achieve what I want? Any answer would be appreciated, thanks.
Solution 1:[1]
you have a next code:
<Accordion
style={styles.accordion}
headerStyle={styles.headerStyle}
contentStyle={styles.contentStyle}
dataArray={data}
opened={index} // here you should have "isAccordionOpen"
/>
and handle a variable in state your Step3 component.
In this function you should to change this variable "isAccordionOpen"
const clickedRadio = () => {
const selectedOption = { [item.question]: { ...item } };
setAnswers({ ...answers, ...selectedOption });
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Andrii Svirskyi |
