Skip to content

Commit 00f1105

Browse files
chunming-cAllenFang
authored andcommitted
Development/sorted classes and style (#136)
* fix missing defaultSorted props for default sort sample * implement customized classes for sorted header * [test] test for sorted header classes * implement customized style for sorted header * [test] test for sorted header style * update document * add missing props check and fix typo * seperate sorting style and header into two props * [test] add test case if column.headerStyle and column.headerClasses were defined * implement customized header style and classes in column level * [test] test for customized header style and classes in column level * [DOC] document for customized classes and styles * sample for customized classes and styles * typo fix for document * tuning the wording for test and documents
1 parent 574a314 commit 00f1105

File tree

11 files changed

+431
-11
lines changed

11 files changed

+431
-11
lines changed

docs/columns.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Available properties in a column object:
2525
* [headerEvents](#headerEvents)
2626
* [headerAlign](#headerAlign)
2727
* [headerAttrs](#headerAttrs)
28+
* [headerSortingClasses](#headerSortingClasses)
29+
* [headerSortingStyle](#headerSortingStyle)
2830
* [editable](#editable)
2931
* [validator](#validator)
3032
* [editCellStyle](#editCellStyle)
@@ -419,6 +421,35 @@ A new `Object` will be the result of element headerAttrs.
419421
> Same as [column.attrs](#attrs), it has lower priority and will be
420422
> overwrited when other props related to HTML attributes were given.
421423
424+
### <a name='headerSortingClasses'>headerSortingClasses - [String | Function]</a>
425+
426+
`headerSortingClasses` allows to customize `class` for header cell when this column is sorting.
427+
428+
```js
429+
const headerSortingClasses = 'demo-sorting';
430+
```
431+
432+
Furthermore, it also accepts a callback which takes **4** arguments and `String` is expected to return:
433+
434+
```js
435+
const headerSortingClasses = (column, sortOrder, isLastSorting, colIndex) => { ... }
436+
```
437+
438+
* `column`: The value of current column.
439+
* `sortOrder`: The order of current sorting
440+
* `isLastSorting`: Is the last one of sorted columns.
441+
* `colIndex`: The index of the current column being processed in BootstrapTable.
442+
443+
### <a name='headerSortingStyle'>headerSortingStyle - [Object | Function]</a>
444+
445+
It's similiar to [headerSortingClasses](#headerSortingClasses). It allows to customize the style of header cell when this column is sorting. A style `Object` and `callback` are acceptable. `callback` takes **4** arguments and an `Object` is expected to return:
446+
447+
```js
448+
const sortingHeaderStyle = {
449+
backgroundColor: 'red'
450+
};
451+
```
452+
422453
## <a name='editable'>column.editable - [Bool | Function]</a>
423454
`column.editable` default is true, means every column is editable if you configure [`cellEdit`](./README.md#cellEdit). But you can disable some columns editable via setting `false`.
424455

packages/react-bootstrap-table2-example/examples/sort/default-sort-table.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,17 @@ const columns = [{
4141
sort: true
4242
}];
4343
44-
<BootstrapTable keyField='id' data={ products } columns={ columns } />
44+
const defaultSorted = [{
45+
dataField: 'name',
46+
order: 'desc'
47+
}];
48+
49+
<BootstrapTable
50+
keyField="id"
51+
data={ products }
52+
columns={ columns }
53+
defaultSorted={ defaultSorted }
54+
/>
4555
`;
4656

4757

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* eslint
2+
no-unused-vars: 0
3+
arrow-body-style: 0
4+
*/
5+
6+
import React from 'react';
7+
8+
import BootstrapTable from 'react-bootstrap-table2';
9+
import Code from 'components/common/code-block';
10+
import { productsGenerator } from 'utils/common';
11+
12+
const products = productsGenerator();
13+
14+
const headerSortingClasses = (column, sortOrder, isLastSorting, colIndex) => (
15+
sortOrder === 'asc' ? 'demo-sorting-asc' : 'demo-sorting-desc'
16+
);
17+
18+
const columns = [{
19+
dataField: 'id',
20+
text: 'Product ID',
21+
sort: true,
22+
headerSortingClasses
23+
}, {
24+
dataField: 'name',
25+
text: 'Product Name',
26+
sort: true,
27+
headerSortingClasses
28+
}, {
29+
dataField: 'price',
30+
text: 'Product Price'
31+
}];
32+
33+
const sourceCode = `\
34+
const headerSortingClasses = (column, sortOrder, isLastSorting, colIndex) => (
35+
sortOrder === 'asc' ? 'demo-sorting-asc' : 'demo-sorting-desc'
36+
);
37+
38+
const columns = [{
39+
dataField: 'id',
40+
text: 'Product ID',
41+
sort: true,
42+
headerSortingClasses
43+
}, {
44+
dataField: 'name',
45+
text: 'Product Name',
46+
sort: true,
47+
headerSortingClasses
48+
}, {
49+
dataField: 'price',
50+
text: 'Product Price'
51+
}];
52+
53+
<BootstrapTable keyField="id" data={ products } columns={ columns } />
54+
`;
55+
56+
export default () => (
57+
<div>
58+
<BootstrapTable keyField="id" data={ products } columns={ columns } />
59+
<Code>{ sourceCode }</Code>
60+
</div>
61+
);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* eslint no-unused-vars: 0 */
2+
import React from 'react';
3+
4+
import BootstrapTable from 'react-bootstrap-table2';
5+
import Code from 'components/common/code-block';
6+
import { productsGenerator } from 'utils/common';
7+
8+
const products = productsGenerator();
9+
10+
const headerSortingStyle = { backgroundColor: '#c8e6c9' };
11+
12+
const columns = [{
13+
dataField: 'id',
14+
text: 'Product ID',
15+
sort: true,
16+
headerSortingStyle
17+
}, {
18+
dataField: 'name',
19+
text: 'Product Name',
20+
sort: true,
21+
headerSortingStyle
22+
}, {
23+
dataField: 'price',
24+
text: 'Product Price'
25+
}];
26+
27+
28+
const sourceCode = `\
29+
const headerSortingStyle = { backgroundColor: '#c8e6c9' };
30+
31+
const columns = [{
32+
dataField: 'id',
33+
text: 'Product ID',
34+
sort: true,
35+
headerSortingStyle
36+
}, {
37+
dataField: 'name',
38+
text: 'Product Name',
39+
sort: true,
40+
headerSortingStyle
41+
}, {
42+
dataField: 'price',
43+
text: 'Product Price'
44+
}];
45+
46+
<BootstrapTable keyField="id" data={ products } columns={ columns } />
47+
`;
48+
49+
export default () => (
50+
<div>
51+
<BootstrapTable keyField="id" data={ products } columns={ columns } />
52+
<Code>{ sourceCode }</Code>
53+
</div>
54+
);

packages/react-bootstrap-table2-example/stories/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import RowEventTable from 'examples/rows/row-event';
4141
import EnableSortTable from 'examples/sort/enable-sort-table';
4242
import DefaultSortTable from 'examples/sort/default-sort-table';
4343
import CustomSortTable from 'examples/sort/custom-sort-table';
44+
import HeaderSortingClassesTable from 'examples/sort/header-sorting-classes';
45+
import HeaderSortingStyleTable from 'examples/sort/header-sorting-style';
4446

4547
// cell editing
4648
import ClickToEditTable from 'examples/cell-edit/click-to-edit-table';
@@ -127,7 +129,9 @@ storiesOf('Work on Rows', module)
127129
storiesOf('Sort Table', module)
128130
.add('Enable Sort', () => <EnableSortTable />)
129131
.add('Default Sort Table', () => <DefaultSortTable />)
130-
.add('Custom Sort Fuction', () => <CustomSortTable />);
132+
.add('Custom Sort Fuction', () => <CustomSortTable />)
133+
.add('Custom Classes on Sorting Header Column', () => <HeaderSortingClassesTable />)
134+
.add('Custom Style on Sorting Header Column', () => <HeaderSortingStyleTable />);
131135

132136
storiesOf('Cell Editing', module)
133137
.add('Click to Edit', () => <ClickToEditTable />)

packages/react-bootstrap-table2-example/stories/stylesheet/base/_base.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ $grey-900: #212121;
1010
$pink-500: #E91E63;
1111
$green-lighten-2: #81c784;
1212
$green-lighten-4: #c8e6c9;
13+
$light-blue: #00BFFF;
1314
$markdown-color: #f6f8fa;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.demo-sorting,
2+
.demo-sorting-asc {
3+
background-color: $green-lighten-2;
4+
}
5+
6+
.demo-sorting-desc {
7+
background-color: $light-blue;
8+
}

packages/react-bootstrap-table2-example/stories/stylesheet/storybook.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
@import "cell-edit/index";
99
@import "row-selection/index";
1010
@import "rows/index";
11-
@import "loading-overlay/index";
11+
@import "sort/index";
12+
@import "loading-overlay/index";

packages/react-bootstrap-table2/src/header-cell.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ const HeaderCell = (props) => {
1515
index,
1616
onSort,
1717
sorting,
18-
sortOrder
18+
sortOrder,
19+
isLastSorting
1920
} = props;
21+
2022
const {
2123
text,
2224
sort,
@@ -27,18 +29,20 @@ const HeaderCell = (props) => {
2729
headerEvents,
2830
headerClasses,
2931
headerStyle,
30-
headerAttrs
32+
headerAttrs,
33+
headerSortingClasses,
34+
headerSortingStyle
3135
} = column;
3236

3337
const cellAttrs = {
3438
..._.isFunction(headerAttrs) ? headerAttrs(column, index) : headerAttrs,
3539
...headerEvents
3640
};
3741
const children = headerFormatter ? headerFormatter(column, index) : text;
38-
const cellClasses = _.isFunction(headerClasses) ? headerClasses(column, index) : headerClasses;
3942

4043
let cellStyle = {};
4144
let sortSymbol;
45+
let cellClasses = _.isFunction(headerClasses) ? headerClasses(column, index) : headerClasses;
4246

4347
if (headerStyle) {
4448
cellStyle = _.isFunction(headerStyle) ? headerStyle(column, index) : headerStyle;
@@ -56,10 +60,6 @@ const HeaderCell = (props) => {
5660
cellStyle.display = 'none';
5761
}
5862

59-
if (cellClasses) cellAttrs.className = cellClasses;
60-
61-
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
62-
6363
if (sort) {
6464
const customClick = cellAttrs.onClick;
6565
cellAttrs.onClick = (e) => {
@@ -70,11 +70,30 @@ const HeaderCell = (props) => {
7070

7171
if (sorting) {
7272
sortSymbol = <SortCaret order={ sortOrder } />;
73+
74+
// append customized classes or style if table was sorting based on the current column.
75+
cellClasses = cs(
76+
cellClasses,
77+
_.isFunction(headerSortingClasses)
78+
? headerSortingClasses(column, sortOrder, isLastSorting, index)
79+
: headerSortingClasses
80+
);
81+
82+
cellStyle = {
83+
...cellStyle,
84+
..._.isFunction(headerSortingStyle)
85+
? headerSortingStyle(column, sortOrder, isLastSorting, index)
86+
: headerSortingStyle
87+
};
7388
} else {
7489
sortSymbol = <SortSymbol />;
7590
}
7691
}
7792

93+
if (cellClasses) cellAttrs.className = cs(cellAttrs.className, cellClasses);
94+
95+
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
96+
7897
return (
7998
<th { ...cellAttrs }>
8099
{ children }{ sortSymbol }
@@ -112,7 +131,8 @@ HeaderCell.propTypes = {
112131
index: PropTypes.number.isRequired,
113132
onSort: PropTypes.func,
114133
sorting: PropTypes.bool,
115-
sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC])
134+
sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC]),
135+
isLastSorting: PropTypes.bool
116136
};
117137

118138
export default HeaderCell;

packages/react-bootstrap-table2/src/header.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const Header = (props) => {
2727
{
2828
columns.map((column, i) => {
2929
const currSort = column.dataField === sortField;
30+
const isLastSorting = column.dataField === sortField;
31+
3032
return (
3133
<HeaderCell
3234
index={ i }
@@ -35,6 +37,7 @@ const Header = (props) => {
3537
onSort={ onSort }
3638
sorting={ currSort }
3739
sortOrder={ sortOrder }
40+
isLastSorting={ isLastSorting }
3841
/>);
3942
})
4043
}

0 commit comments

Comments
 (0)