I have made a collapsible button with tokens inside using reactstrap and everything is working fine for button click collapse.
I would like to have this scenario as it is, but in the other hand how could I modify this to make all the collapsible buttons open on initial render of page.
While visiting the page, all the tokens needs to be visible means all the collapsible items needs to get opened.
If we give,
this.state = {
open: [0 , 1, 2]
};
then it will be opened but for this post it will work whereas in real applciation I don’t know what would be the exact index so hard coding like this won’t work.
Kindly help me to open all the n
numbers of collapsible data to be opened on intial state and upon clicking the button it should be as like now (open/close) tokens.
const data = [{"orderId":1,"orderNo":"123", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3"]}] },
{"orderId":2,"orderNo":"456", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1","Token3"]}] },
{"orderId":3,"orderNo":"789", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3", "Token4"]}] }
]
const {Component, Fragment} = React;
const {Button, Collapse} = Reactstrap;
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
open: []
};
}
toggle = idx => () => {
this.setState(prevState => ({open: this.state.open.includes(idx) ? prevState.open.filter(x => x !== idx) : [...prevState.open, idx]})
)}
render() {
const { open } = this.state;
return <div>
{
data.map((levelOneItem, i) => {
return(
<div>
<div> Order Id: {levelOneItem.orderId} </div>
{
levelOneItem.orderParts.map((levelTwoItem, j) => {
return(
<div>
<div> Order Part Id: {levelTwoItem.orderPartsId} </div>
<Button onClick={this.toggle(i)}>Display Token</Button>
<Collapse isOpen={open.includes(i)}>
{
<div>
{levelTwoItem.regTokens.map((levelThreeItem, k) => {
return(<span> {levelThreeItem} </span>)
})
}
</div>
}
</Collapse>
</div>
)
})
}
</div>
)
})
}
</div>;
}
}
ReactDOM.render(<Menu />, document.getElementById("root"));
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>
<div id="root"></div>
2
Answers
If you want all of them been opened when init.
Which means the index list of all the items
You can generate a list like
[0, 1, 2...]
based on the length of dataIt looks like reactstrap don’t support such things. But here is an workaround to that.
Here isFirstTime indicates the initial state, so all collapse will get true, when any one of them changes, isFirstTime will be false, and rest will be done as is