Search code examples
cssreactjstwitter-bootstraphtml-tablebootstrap-accordion

How to make an html table with many nested accordion elements with bootstrap in react?


I need to make a table with several accordions that will be nested within each other.

The final result I would like to have would be like this: image of my custom table with nested accordions

I would like to create this table dynamically as I fill it with data from APIs but I already can't get it to work exactly as I want it by hard coding it with hard data.

My actual code is the following (it's a React component but I've simplify it so all the html is in the return method of the component):

import React, { useEffect, useState } from 'react';
import { FaMinus, FaPlus } from 'react-icons/fa';

const TableComponent: React.FC = () => {

    return (
        <>
            <div className="container test">
                <div>
                    <table className="table table-sm table-bordered table-fixed accordion" id="firstTable">
                        <thead>
                            <tr>
                                <th className="bg-primary">Open first accordion</th>
                                <th className="bg-primary">First Group of th element</th>
                                <th className="bg-primary">First Group of th element</th>
                                <th className="bg-primary">First Group of th element</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr data-bs-toggle="collapse" data-bs-target="#main-accordion1" data-bs-parent="#firstTable">
                                <th className="bg-primary">accordion button 1 <FaPlus size={20} /></th>
                                <td className="bg-primary">First Group of td element</td>
                                <td className="bg-primary">First Group of td element</td>
                                <td className="bg-primary">First Group of td element</td>
                            </tr>
                            <tr className="collapse accordion-collapse" id="main-accordion1" data-bs-parent="#firstTable">
                                <td colSpan={12}>
                                    <div>
                                        <table className="table" id="secondTable">
                                            <thead>
                                                <tr>
                                                    <th className="bg-success">Open second accordion</th>
                                                    <th className="bg-success">Second Group of th element</th>
                                                    <th className="bg-success">Second Group of th element</th>      
                                                    <th className="bg-success">Second Group of th element</th>  
                                                </tr>
                                            </thead>    
                                            <tbody>
                                                <tr data-bs-toggle="collapse" data-bs-target="#sub-accordion1" data-bs-parent="#secondTable">
                                                    <th className="bg-success">accordion button 2 <FaPlus size={20} /></th>
                                                    <td className="bg-success">Second Group of td element</td>
                                                    <td className="bg-success">Second Group of td element</td>
                                                    <td className="bg-success">Second Group of td element</td>
                                                </tr>
                                                <tr className="collapse accordion-collapse" id="sub-accordion1" data-bs-parent="#secondTable">
                                                    <td colSpan={12}>
                                                        <div> 
                                                            <table className="table" id="thirdTable">
                                                                <thead>
                                                                    <tr>
                                                                        <th className="bg-info">Third Group of th element</th>
                                                                        <th className="bg-info">Third Group of th element</th>
                                                                        <th className="bg-info">Third Group of th element</th>      
                                                                        <th className="bg-info">Third Group of th element</th>     
                                                                    </tr>
                                                                </thead>
                                                                <tbody>
                                                                    <tr>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                    </tr>
                                                                </tbody>
                                                            </table>
                                                        </div>
                                                    </td>
                                                </tr>
                                                <tr data-bs-toggle="collapse" data-bs-target="#sub-accordion3" data-bs-parent="#secondTable">
                                                    <th className="bg-success">accordion button 2 <FaPlus size={20} /></th>
                                                    <td className="bg-success">Second Line of Second Group of td element</td>
                                                    <td className="bg-success">Second Line of Second Group of td element</td>
                                                    <td className="bg-success">Second Line of Second Group of td element</td>
                                                </tr>
                                                <tr className="collapse accordion-collapse" id="sub-accordion3" data-bs-parent="#secondTable">
                                                    <td colSpan={12}>
                                                        <div> 
                                                            <table className="table" id="thirdTable">
                                                                <thead>
                                                                    <tr>
                                                                        <th className="bg-info">Third Group of th element</th>
                                                                        <th className="bg-info">Third Group of th element</th>
                                                                        <th className="bg-info">Third Group of th element</th>      
                                                                        <th className="bg-info">Third Group of th element</th>     
                                                                    </tr>
                                                                </thead>
                                                                <tbody>
                                                                    <tr>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                        <td className="bg-info">Third Group of td element</td>
                                                                    </tr>
                                                                </tbody>
                                                            </table>
                                                        </div>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </td>
                            </tr>
                            <tr data-bs-toggle="collapse" data-bs-target="#main-accordion2" data-bs-parent="#firstTable">
                                <th className="bg-primary">accordion button 1 <FaPlus size={20} /></th>
                                <td className="bg-primary">Second Line of First Group of td element</td>
                                <td className="bg-primary">Second Line of First Group of td element</td>
                                <td className="bg-primary">Second Line of First Group of td element</td>
                            </tr>
                            <tr className="collapse accordion-collapse" id="main-accordion2" data-bs-parent="#firstTable">
                                <td colSpan={12}>
                                    <div>
                                        <table className="table" id="secondTable">
                                            <thead>
                                                <tr>
                                                    <th className="bg-success">Open second accordion</th>
                                                    <th className="bg-success">Second Second Group of th element</th>
                                                    <th className="bg-success">Second Second Group of th element</th>       
                                                    <th className="bg-success">Second Second Group of th element</th>   
                                                </tr>
                                            </thead>    
                                            <tbody>
                                                <tr data-bs-toggle="collapse" data-bs-target="#sub-accordion2" data-bs-parent="#secondTable">
                                                    <th className="bg-success">accordion button 2 <FaPlus size={20} /></th>
                                                    <td className="bg-success">Second Second Group of td element</td>
                                                    <td className="bg-success">Second Second Group of td element</td>
                                                    <td className="bg-success">Second Second Group of td element</td>
                                                </tr>
                                                <tr className="collapse accordion-collapse" id="sub-accordion2" data-bs-parent="#secondTable">
                                                    <td colSpan={12}>
                                                        <div> 
                                                            <table className="table" id="thirdTable">
                                                                <thead>
                                                                    <tr>
                                                                        <th className="bg-info">Third Third Group of th element</th>
                                                                        <th className="bg-info">Third Third Group of th element</th>
                                                                        <th className="bg-info">Third Third Group of th element</th>        
                                                                        <th className="bg-info">Third Third Group of th element</th>       
                                                                    </tr>
                                                                </thead>
                                                                <tbody>
                                                                    <tr>
                                                                        <td className="bg-info">Third Third Group of td element</td>
                                                                        <td className="bg-info">Third Third Group of td element</td>
                                                                        <td className="bg-info">Third Third Group of td element</td>
                                                                        <td className="bg-info">Third Third Group of td element</td>
                                                                    </tr>
                                                                </tbody>
                                                            </table>
                                                        </div>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </>
    )
}

export default TableComponent;

This code gives me the following result: The result from my html code

But I still have two problems:

  • There is no border in my table between the cells even though in my html I have specified the table-bordered class, do you know what this is due to?

  • When I open an accordion while another accordion is already open, the accordion that was already open closes automatically, does anyone know how to prevent this behavior?

The stackbitz example that was requested by StepUp:

stackbitz example with only the application

stackbitz example with react file

I've put the two link because I'm not sure which one you want, I guess it's the second one but I've put both in doubt.


Solution

  • Nesting so many tables inside each other makes the HTML quite unreadable. Maybe you can try to make only the <tr> elements collapse instead of using a new <table> every time.

    You can make accordions stay open by omitting data-bs-parent

    See here