I am making sidebar menu from .json. Menu items are BMW models. example data bellow
My return:
<List>
{Menuhandler( menuDataHandler(JsonSeries) )}
</List>
MenuDataHandler makes json to this format
let seriesData = {
"name": 1-series,
"url" : /1-series,
"children" : [
{
"name": e82,
"url" : /1-series/e82,
{
"name": e87,
"url" : /1-series/e87
}
}
]}, {
"name": 2-series,
"url" : /2-series,
"children" : [
{
"name": e82,
"url" : /2-series/e82
},{
"name": e87,
"url" : /2-series/e87
}
]},
{
"name": 3-series,
"url" : /3-series,
"children" : [
{
"name": e82,
"url" : /3-series/e82
}, {
"name": e87,
"url" : /3-series/e87
}
]},
{
"name": 4-series,
"url" : /4-series,
"children" : [
{
"name": e82,
"url" : /4-series/e82
},
{
"name": e87,
"url" : /4-series/e87
}
]}
Menuhandler is build like this.
const Menuhandler = ( menulist ) => {
return menulist.map( ( oneMenuItem, i ) => {
//console.log( oneMenuItem.index)
/*
If oneMenuitem does not have children return listitem to go wanted url.
*/
if (!oneMenuItem.children) {
return (
<div key={i}>
<ThemeProvider theme={theme}>
<ListItem button>
<Link to={ oneMenuItem.url } className="dropdown-link">
<ListItemText inset primary={ oneMenuItem.name }/>
</Link>
</ListItem>
</ThemeProvider>
</div>
)
}
/*
If oneMenuItem have children. Return Listitem and Collapse. Inside
Collapse call {Menuhandler(oneMenuItem.children)} so inside Collapse
will be children. This is Loop will go until there is no childrens and
it will return above ListItem
*/
return (
<div key={i}>
<ThemeProvider theme={theme}>
<div className="dropdownItem">
<ListItem
button
key={oneMenuItem.index}
onClick={() => handleClick(oneMenuItem.url)}
>
<Link to={oneMenuItem.url} className="dropdown-link">
<ListItemText inset primary={oneMenuItem.name} />
</Link>
{ open[ oneMenuItem.url ] ?
<ExpandLess /> :
<ExpandMore />
}
</ListItem>
<div className="menubar-handler">
</div>
<Collapse
in={open[oneMenuItem.url]}
unmountOnExit
className="childrenItem"
>
{Menuhandler(oneMenuItem.children)}
</Collapse>
</div>
</ThemeProvider>
</div>
);
});
};
HandleClick
const handleClick = ( ComingUrl ) => {
//console.log(ComingUrl)
setOpen( prevState => ( {...open, [ ComingUrl ]: !prevState[ ComingUrl ] } ) )
}
Now there comes the fun part. Collapse works now in one state. open[oneMenuItem.url]. HandleClick will make only one object open. In there it will add item : value.
*click* {/1-series:true}.
*next click* {/1-series:true, /2-series: true}.
Now two collapses are open. If i click the same item again it will make value false and vice versa. Then one collapse closes.
I want to make HandleClick that will automatically closes in samelevel items.
So if open has:
{/1-series:true, /2-series: true, /3-series: true,/4-series: true}
This could not happen. How i want it to be.
// one scenario
{/1-series:true, /2-series: false, /3-series: false,/4-series: false}
// Second one
{/1-series:false, /2-series: true, /3-series: false,/4-series: false}
Same would be in children level. If /1-series/e82 is true /1-series/e87 will be false.