简体   繁体   中英

How to open multiple Accordion tabs in react-bootstrap?

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

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

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>

Documentation here

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.

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}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM