Search code examples
cssreactjshtml-table

reactjs creating part of the table scrollable


To make part of the table scrollable I'm using a div inside of the table but getting the warning:

Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>

I understand the warning, but I would like part of the table (most of it) to be scrollable, thus limiting the maxheight of part of the table:

<div className="main-table">
               <table className="main-edit-table" align="right">
                     <tbody>
                            <tr>
                                 <th>haveri</th>
                             </tr>
                              <div className="inst-container">
                              {this.state.list && this.state.list.map((collection, key) => (
                                    <tr key={key}>
                                        <td>{key+1}</td>
                                        <td>
                                            <div className="main-item-container">
                                                <span>{collection}</span>
                                            </div>
                                        </td>
                                        <td>{collection.subjects[0] && collection.subjects[0].name}</td>
                                    </tr>      
                                    ))}
                                    </div>
                            </tbody>
                        </table>

                    </div>

CSS:

.inst-container {
    border: 1px solid #eeccee;
    max-height: 300px;
    overflow-y: scroll;
    width: 100%;
}

All I'm doing is inserting a div inside the table, after its headings, to make the table itself scrollable.

Two questions:

  1. Is the warning "that bad"? I mean, I get the warning but it's working fine
  2. What would you do to create the heading (which can contain a few columns) and a scrollable table underneath? Is using grid system the only option?

Solution

  • I would rather wrap the whole table inside a div container with the overflow and set the column headers to sticky position.

    See below:

    <div className="container">
        <table className="main-edit-table" align="right">
            <thead>
                <tr>
                    <th className="sticky-column">haveri</th>
                </tr>
            </thead>
            <tbody>
                    {this.state.list && this.state.list.map((collection, key) => (
                        <tr key={key}>
                            <td>{key+1}</td>
                             <td>
                                 <div className="main-item-container">
                                     <span>{collection}</span>
                                 </div>
                                 </td>
                                 <td>{collection.subjects[0] && 
                                 collection.subjects[0].name}</td>
                        </tr>      
                                    ))}
            </tbody>
        </table>
    </div>
    

    CSS:

    .sticky-column {
        position: -webkit-sticky; /* Safari */
        position: sticky;
        top: 0
    }
                    
    .container {
        border: 1px solid #eeccee;
        max-height: 300px;
        overflow-y: scroll;
        width: 100%;
    }
    

    Have a look at the CodeSandBox sample: https://xyv5nl.csb.app/