Reputation: 1231
I am trying to open multiple Accordion if possible. Currently using react-bootstrap
library.
Following is my implementation :
<Accordion>
{data.rows.map((item, index) => {
return (
<Card
style={{
border: "none",
marginTop: "1em",
borderBottom: "1px solid #f1f1f1",
}}
>
<Card.Header
style={{ background: "transparent", padding: "0.75em 0" }}
>
<Row>
<Col lg="10" sm xs="9" style={{ alignSelf: "center" }}>
<p
className="cardtitle"
style={{ fontWeight: "600" }}
>
{item.title}
</p>
</Col>
<Col style={{ textAlign: "right" }} xs sm>
{" "}
<ContextAwareToggle eventKey={index}>
+
</ContextAwareToggle>
</Col>
</Row>
</Card.Header>
<Accordion.Collapse eventKey={index}>
<Card.Body>
<p className="cardcontent">{item.content}</p>
</Card.Body>
</Accordion.Collapse>
</Card>
);
})}{" "}
</Accordion>
...
function ContextAwareToggle({ children, eventKey, callback }) {
const currentEventKey = useContext(Fifth);
const decoratedOnClick = useAccordionToggle(
eventKey,
() => callback && callback(eventKey)
);
const isCurrentEventKey = currentEventKey === eventKey;
console.log(currentEventKey);
return (
<button
type="button"
className="accordianButton"
// style={{ backgroundColor: isCurrentEventKey ? "pink" : "lavender" }}
style={{
backgroundColor: "transparent",
fontSize: "1.8em",
fonWeight: "700",
border: "transparent",
color: "green",
}}
onClick={decoratedOnClick}
>
{isCurrentEventKey ? "-" : "+"}
</button>
);
}
Following is the link where I got my reference of code: https://react-bootstrap.github.io/components/accordion/
Also, if not accordion then please suggest any other component. Been trying to create a FAQ template in my project.
Thanks
Upvotes: 10
Views: 18060
Reputation: 11
i had this problem aswell, i solved it by using reactstrap library's UncontrolledAccordion
here is an example:
// ** Reactstrap Imports
import {
UncontrolledAccordion,
AccordionBody,
AccordionHeader,
AccordionItem,
Label
} from "reactstrap";
// ** Example Component layout in the render() function
<UncontrolledAccordion stayOpen style={{ border: "none", width: "95%" }}>
<Label>ACCORDION MENU</Label>
<AccordionItem>
<AccordionHeader targetId="1">Test 1</AccordionHeader>
<AccordionBody accordionId="date">
<Label className="form-label" for="default-picker">
Test 1
</Label>
</AccordionBody>
</AccordionItem>
<AccordionItem>
<AccordionHeader targetId="2">Test 2</AccordionHeader>
<AccordionBody accordionId="date">
<Label className="form-label" for="default-picker">
Test 2
</Label>
</AccordionBody>
</AccordionItem>
<AccordionItem>
<AccordionHeader targetId="3">Test 3</AccordionHeader>
<AccordionBody accordionId="date">
<Label className="form-label" for="default-picker">
Test 3
</Label>
</AccordionBody>
</AccordionItem>
</UncontrolledAccordion>
Note: you cannot control the state of the accordion items with an accordion like this, the user either needs to refresh the page or close the accordion items themselves.
Upvotes: 0
Reputation: 3498
UPDATE:
It is now possible to keep accordion tabs open when opening another tab. This can be achieved using the alwaysOpen
property:
<Accordion alwaysOpen>
<Accordion.Item eventKey="1">
<Accordion.Header>
Title
</Accordion.Header>
<Accordion.Body>
Test Body
</Accordion.Body>
</Accordion.Item>
<Accordion.Item eventKey="2">
<Accordion.Header>
Title
</Accordion.Header>
<Accordion.Body>
Test Body
</Accordion.Body>
</Accordion.Item>
</Accordion>
Upvotes: 6
Reputation: 1734
I was also facing the similar issue in my application. Due to inherent nature of accordion it is not possible to keep previous tab open while opening other tab. Finally I created multiple accordion for each individual tab using a loop as below.
import React, { Component } from "react";
import { Accordion, Card, Button } from 'react-bootstrap';
class ItemsList extends Component {
constructor(props) {
super(props);
}
render() {
const items = this.props.itemList;
return (<div>
{items.map((item) => {
return (
<Accordion key={item.itemNumber} id={item.itemNumber}>
<Card>
<Card.Header>
<Accordion.Toggle as={Button}
variant="link"
eventKey={item.itemNumber}>
</Accordion.Toggle>
{item.itemName}
</Card.Header>
<Accordion.Collapse eventKey={item.itemNumber}>
<Card.Body>
{item.itemDescription}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
);
})}
</div>);
}
export default ItemsList;
It works perfectly fine and I am able to achieve behaviour of keeping two or more tabs open at the same time which is not possible using a single Accordion. Hope this helps.
Upvotes: 3
Reputation: 475
I achieved this by using a for loop on getElementsByClassName. Don't forget to bind this in the constructor of your component or it will not work.
constructor(props) {
super(props)
this.showAllAccordionTabs = this.showAllAccordionTabs.bind(this)
}
showAllAccordionTabs() {
const getCollapsedAccordionSections = document.getElementsByClassName(
"collapse"
)
for (var i = 0; i < getCollapsedAccordionSections.length; i++) {
getCollapsedAccordionSections[i].classList.add("show")
}
}
Then add the onClick event
onClick={this.showAllAccordionTabs}
Upvotes: -1
Reputation: 2918
The Accordion component is designed to expand one card at once. To achieve the effect of multiple tabs opened, you need to use multiple Accordions like this:
import React from "react";
import { Accordion, Card, Button } from "react-bootstrap";
const tabs = [
{ id: 1, label: "Tab 1", description: "Content of Tab 1" },
{ id: 2, label: "Tab 2", description: "Content of Tab 2" },
{ id: 3, label: "Tab 3", description: "Content of Tab 3" }
];
export default function App() {
return (
<div className="App">
{tabs.map(tab => (
<Accordion key={tab.id} defaultActiveKey={tab.id}>
<Card>
<Card.Header>
<Accordion.Toggle as={Button} variant="link" eventKey={tab.id}>
{tab.label}
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey={tab.id}>
<Card.Body>{tab.description}</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
))}
</div>
);
}
Here is a code sandbox https://codesandbox.io/s/react-bootstrap-multiple-accordion-tabs-oboks
Upvotes: 13