react-bootstrap-table2
react-bootstrap-table2 copied to clipboard
Multiple Header Rows support?
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?

Thank you!
@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!
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.

@bookworm2death any luck with this?
@arhimmel It looks like they removed that feature in the current versions. I ended up going with a different solution.
any news about multi header?
Can we revisit this? I was excited when I saw the image on the homepage, but disappointed that it is not a feature.
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.
Any update?
Any update?
Ended using http://allenfang.github.io/react-bootstrap-table/example.html , that supports header groups
Hi team
Any update on this?
I also would like to know 👍
Any update?
Any update?
Any news on this? This seems like a really important function and I'm surprised it's not included yet.
hi, any update?
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.
Any update on this ? @AllenFang
Last release was 2018. Not a single one of the 38+ contributors has commented in years.
I know a doomed requested feature when I see one, but bump anyway.
can we combine bootstrap tags and react bootstrap table next component?
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> )
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.
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.
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,
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.
You can create multi header by adding multiple
And the result is:
You can create multi header by adding multiple tags inside table header and using colSpan property.
And the result is:
Hi, Could you please provide the code how you're achieving this. Also, Filter and sorting are working or not after the implementations!
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.
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.
