Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Header Rows support? #617

Open
bookworm2death opened this issue Oct 17, 2018 · 29 comments
Open

Multiple Header Rows support? #617

bookworm2death opened this issue Oct 17, 2018 · 29 comments

Comments

@bookworm2death
Copy link

Hi @AllenFang I'm a big fan of your react-bootstrap-table(s). My current project is using your original react-bootstrap-table, but i'm trying to migrate to your react-bootstrap-table-next because my customer wants that autoSelectText option. But my current table has 2 header rows, the first spanning multiple columns. And it looks like the new table structure doesn't handle that since datafield is required, and the column definition is missing the row & colspan attributes. Is there any plans to migrate this functionality or do you know of a way to insert an extra header?
image

Thank you!

@AllenFang
Copy link
Member

@bookworm2death firstly, say thanks to you.

Currently, I dont have plan to support the header colspan or rowspan. However, I will try to implement it ASAP. Sorry I can not tell you when I can support it. It's depends on my time. thanks!

@benkotch
Copy link

Hi @bookworm2death, were you ever able to get this to work? I see they have an example on the React Bootstrap Table home page, but I must be missing how to do this in the docs.
react-bootstrap-table2-sample

@arhimmel
Copy link

@bookworm2death any luck with this?

@benkotch
Copy link

@arhimmel It looks like they removed that feature in the current versions. I ended up going with a different solution.

@Fornori
Copy link

Fornori commented Sep 28, 2019

any news about multi header?

@tcboles
Copy link

tcboles commented Oct 30, 2019

Can we revisit this? I was excited when I saw the image on the homepage, but disappointed that it is not a feature.

@dstruyve
Copy link

Hi @AllenFang, Were you able to put this feature on the roadmap? The example image on the homepage looks promising, but I cannot find an implemented example of the multiple header rows.

@thedmeyer
Copy link

Any update?

@amcm23
Copy link

amcm23 commented Apr 20, 2020

Any update?

Ended using http://allenfang.github.io/react-bootstrap-table/example.html , that supports header groups

@Ksenia0479
Copy link

Hi team

Any update on this?

@Mikeez
Copy link

Mikeez commented Sep 1, 2020

I also would like to know 👍

@josearaujo
Copy link

Any update?

1 similar comment
@sashasemeniuk
Copy link

Any update?

@dennysemko
Copy link

Any news on this? This seems like a really important function and I'm surprised it's not included yet.

@skg-thienpg
Copy link

hi, any update?

@duhmojo
Copy link

duhmojo commented Feb 22, 2022

At least give us a way of hooking into the header so we can implement ourselves. There's no work around to this and something completely normal for HTML tables. It's been 4 years.

@arjunsoota
Copy link

Any update on this ? @AllenFang

@duhmojo
Copy link

duhmojo commented Sep 26, 2022

Last release was 2018. Not a single one of the 38+ contributors has commented in years.

@HZSamir
Copy link

HZSamir commented Oct 5, 2022

I know a doomed requested feature when I see one, but bump anyway.

@HASSANI8046
Copy link

can we combine bootstrap tags and react bootstrap table next component?

@Atchaya-Kodeeswaran
Copy link

Atchaya-Kodeeswaran commented May 16, 2023

I tried combined headers by using headerformater and columnformater
headerFormatter: (column) => ( <><Row className="combine-col-header">Heading</Row> <Row gutter={24}> <Col span={12}>Sub heading one </Col> <Col span={12}>Sub heading two </Col> </Row> </> ), formatter: (cell, row, rowIndex, extraData) => ( <Row gutter={24}> <Col span={12}>{cell} </Col> <Col span={12}>{row.Subheadingtwo}</Col> </Row> )

image

@duhmojo
Copy link

duhmojo commented Jun 22, 2023

I finally got a chance to take another look at grouped headings. @Atchaya-Kodeeswaran your approach can of course work but we lose column sort, and all sortValue/filterValue/etc... all need to implement all grouped values into the combo grouped column. The format and filter definition functions can be implemented all at one, but sorting is gone. Your work around is fine for unsorted columns. Thanks for the contribution.

@duhmojo
Copy link

duhmojo commented Jun 23, 2023

Also, like every Node project this one has a million build dependencies and specialized tweaks. I tried patching it, but simply building is a challenge in itself.

@duhmojo
Copy link

duhmojo commented Jun 23, 2023

OK, I used patch-package to create a patch for header.js and bootstrap-table.js. I added a columnGroups table prop that takes an optional object ( { <column idx #>: { title: <''>, colspan: <#>, className: <> } ) and if set, I have some logic that creates a TD/TH row before the normal header row.

The styling and the real header row work out, sorting and filtering work. However I'll need to do a bit more work to deal with column widths which, though it can be set in headerStyle, only the top/highest TD width will dictate the column width. For nested heading to work you need a matching TD above the existing TDs, even if they're not colspanned with a title.

Here's my patch file:

diff --git a/node_modules/react-bootstrap-table-next/dist/react-bootstrap-table-next.js b/node_modules/react-bootstrap-table-next/dist/react-bootstrap-table-next.js
index 2b73668..b3a06b8 100644
--- a/node_modules/react-bootstrap-table-next/dist/react-bootstrap-table-next.js
+++ b/node_modules/react-bootstrap-table-next/dist/react-bootstrap-table-next.js
@@ -3144,6 +3144,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
 var Header = function Header(props) {
   var className = props.className,
       columns = props.columns,
+      columnGroups = props.columnGroups,
       onSort = props.onSort,
       onFilter = props.onFilter,
       sortField = props.sortField,
@@ -3213,9 +3214,46 @@ var Header = function Header(props) {
     }
   }
 
+  // { idx #: { title: <>, colspan: <#>, className: <> }
+  let headGroups = undefined
+  if (columnGroups) {
+    let colCount = 0
+    for (let i = 0; i < columns.length; i++) {
+      const columnGroup = columnGroups[i]
+      if (columnGroup) {
+        headGroups.push(
+          _react2.default.createElement(
+            'td',
+            { className: c.className },
+            { colspan: c.colspan },
+            c.title
+          )
+        )
+        colCount = c.colspan
+      } else {
+        // either this is a column to add a placeholder for, or a spaned column
+        if (colCount === 0) {
+          _react2.default.createElement(
+            'td',
+            { className: c.className }
+          )
+        }
+      }
+      if(colCount > 0) colCount -= 1
+    }
+  }
+
+  if (headGroups) {
+    headGroups = _react2.default.createElement(
+      'tr',
+      headGroups
+    )
+  }
+
   return _react2.default.createElement(
     'thead',
     { className: wrapperClasses },
+    headGroups,
     _react2.default.createElement(
       'tr',
       { className: className },
@@ -3225,6 +3263,7 @@ var Header = function Header(props) {
 };
 
 Header.propTypes = {
+  columnGroups: _propTypes2.default.object,
   columns: _propTypes2.default.array.isRequired,
   onSort: _propTypes2.default.func,
   onFilter: _propTypes2.default.func,
diff --git a/node_modules/react-bootstrap-table-next/lib/src/bootstrap-table.js b/node_modules/react-bootstrap-table-next/lib/src/bootstrap-table.js
index 4bb7a5e..468b90e 100644
--- a/node_modules/react-bootstrap-table-next/lib/src/bootstrap-table.js
+++ b/node_modules/react-bootstrap-table-next/lib/src/bootstrap-table.js
@@ -111,6 +111,7 @@ var BootstrapTable = function (_PropsBaseResolver) {
     value: function renderTable() {
       var _props2 = this.props,
           columns = _props2.columns,
+          columnGroups = _props2.columnGroups,
           keyField = _props2.keyField,
           tabIndexCell = _props2.tabIndexCell,
           id = _props2.id,
@@ -163,6 +164,7 @@ var BootstrapTable = function (_PropsBaseResolver) {
           tableCaption,
           _react2.default.createElement(_header2.default, {
             columns: columns,
+            columnGroups: this.props.columnGroups,
             className: this.props.headerClasses,
             wrapperClasses: this.props.headerWrapperClasses,
             sortField: this.props.sortField,
@@ -222,6 +224,7 @@ BootstrapTable.propTypes = {
   keyField: _propTypes2.default.string.isRequired,
   data: _propTypes2.default.array.isRequired,
   columns: _propTypes2.default.array.isRequired,
+  columnGroups: _propTypes2.default.object,
   bootstrap4: _propTypes2.default.bool,
   remote: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.shape({
     pagination: _propTypes2.default.bool
diff --git a/node_modules/react-bootstrap-table-next/lib/src/header.js b/node_modules/react-bootstrap-table-next/lib/src/header.js
index 968a435..752ae79 100644
--- a/node_modules/react-bootstrap-table-next/lib/src/header.js
+++ b/node_modules/react-bootstrap-table-next/lib/src/header.js
@@ -42,6 +42,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
 var Header = function Header(props) {
   var className = props.className,
       columns = props.columns,
+      columnGroups = props.columnGroups,
       onSort = props.onSort,
       onFilter = props.onFilter,
       sortField = props.sortField,
@@ -111,18 +112,56 @@ var Header = function Header(props) {
     }
   }
 
-  return _react2.default.createElement(
-    'thead',
-    { className: wrapperClasses },
-    _react2.default.createElement(
-      'tr',
-      { className: className },
-      childrens
-    )
-  );
+    // { idx #: { title: <>, colspan: <#>, className: <> }
+    let headGroups = []
+    if (columnGroups) {
+      let colCount = 0
+      for (let i = 0; i < columns.length; i++) {
+        const columnGroup = columnGroups[i]
+        if (columnGroup) {
+          headGroups.push(
+            _react2.default.createElement(
+              'th',
+              { className: columnGroup.className, colSpan: columnGroup.colspan },
+              columnGroup.title
+            )
+          )
+          colCount = columnGroup.colspan > 1 ? (columnGroup.colspan - 1) : columnGroup.colspan
+        } else {
+          // either this is a column to add a placeholder for, or a spaned column
+          if (colCount === 0) {
+            headGroups.push(_react2.default.createElement(
+              'th'
+            ))
+          }
+        }
+        if(colCount > 0) colCount -= 1
+      }
+    }
+  
+    let groupHeader = undefined
+    if (headGroups.length > 0) {
+      groupHeader = _react2.default.createElement(
+        'tr',
+        { className: className },
+        headGroups
+      )
+    }
+  
+    return _react2.default.createElement(
+      'thead',
+      { className: wrapperClasses },
+      groupHeader,
+      _react2.default.createElement(
+        'tr',
+        { className: className },
+        childrens
+      )
+    );
 };
 
 Header.propTypes = {
+  columnGroups: _propTypes2.default.object,
   columns: _propTypes2.default.array.isRequired,
   onSort: _propTypes2.default.func,
   onFilter: _propTypes2.default.func,

@duhmojo
Copy link

duhmojo commented Jun 23, 2023

Note that I account for the existence of the selectRow prop (the checkbox first column) and bump the index of which columns to colspan over by 1 in a component that includes BootstrapTable.

@LG64BIT
Copy link

LG64BIT commented Mar 6, 2024

You can create multi header by adding multiple tags inside table header and using colSpan property.

And the result is:
image

@nazcoder
Copy link

You can create multi header by adding multiple tags inside table header and using colSpan property.

And the result is: image

Hi, Could you please provide the code how you're achieving this. Also, Filter and sorting are working or not after the implementations!

@LG64BIT
Copy link

LG64BIT commented Mar 12, 2024

Code:
function BasicExample() { return ( <Table striped bordered hover> <thead> <tr> <th colSpan={3}>Personal</th> <th>Other</th> </tr> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> </tbody> </Table> ); }
Haven't tried filtering and sorting, I don't see why it wouldn't work, also question was just about headers.

@duhmojo
Copy link

duhmojo commented Mar 12, 2024

You'll loose sorting. See my comment above and the other person that suggested something similar. Also your example doesn't appear to be related to this React component, it's just a table. In this component you can format the header and define columns, separately. Sorting doesn't automatically get attached to your own custom heading format. It's an integrated feature.

This should be a feature of this aging, but extremely useful component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests