Skip to content
14 changes: 14 additions & 0 deletions docs/columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Available properties in a column object:
* [formatExtraData](#formatExtraData)
* [sort](#sort)
* [sortFunc](#sortFunc)
* [onSort](#onSort)
* [classes](#classes)
* [style](#style)
* [title](#title)
Expand Down Expand Up @@ -122,6 +123,19 @@ Enable the column sort via a `true` value given.
```
> The possible value of `order` argument is **`asc`** and **`desc`**.

## <a name='sortFunc'>column.onSort - [Function]</a>
`column.onSort` is an event listener for sort change event:

```js
{
// omit...
sort: true,
onSort: (field, order) => {
// ....
}
}
```

## <a name='classes'>column.classes - [String | Function]</a>
It's availabe to have custom class on table column:

Expand Down
1 change: 1 addition & 0 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Please see [Work with table sort](https://react-bootstrap-table.github.io/react-
- [x] Default Sort
- [x] Remote mode
- [x] Custom the sorting header
- [x] Sort event listener
- [ ] Custom the sort caret
- [ ] Sort management
- [ ] Multi sort
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* eslint no-console: 0 */
import React from 'react';

import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';

const products = productsGenerator();

const columns = [{
dataField: 'id',
text: 'Product ID',
sort: true
}, {
dataField: 'name',
text: 'Product Name',
sort: true,
onSort: (field, order) => {
console.log(`Sort Field: ${field}, Sort Order: ${order}`);
}
}, {
dataField: 'price',
text: 'Product Price'
}];

const defaultSorted = [{
dataField: 'name',
order: 'desc'
}];

const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';

const columns = [{
dataField: 'id',
text: 'Product ID',
sort: true
}, {
dataField: 'name',
text: 'Product Name',
sort: true,
onSort: (field, order) => {
console.log(....);
}
}, {
dataField: 'price',
text: 'Product Price'
}];

<BootstrapTable keyField='id' data={ products } columns={ columns } />
`;

export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } defaultSorted={ defaultSorted } />
<Code>{ sourceCode }</Code>
</div>
);
2 changes: 2 additions & 0 deletions packages/react-bootstrap-table2-example/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import RowEventTable from 'examples/rows/row-event';
// table sort
import EnableSortTable from 'examples/sort/enable-sort-table';
import DefaultSortTable from 'examples/sort/default-sort-table';
import SortEvents from 'examples/sort/sort-events';
import CustomSortTable from 'examples/sort/custom-sort-table';
import HeaderSortingClassesTable from 'examples/sort/header-sorting-classes';
import HeaderSortingStyleTable from 'examples/sort/header-sorting-style';
Expand Down Expand Up @@ -167,6 +168,7 @@ storiesOf('Work on Rows', module)
storiesOf('Sort Table', module)
.add('Enable Sort', () => <EnableSortTable />)
.add('Default Sort Table', () => <DefaultSortTable />)
.add('Sort Events', () => <SortEvents />)
.add('Custom Sort Fuction', () => <CustomSortTable />)
.add('Custom Classes on Sorting Header Column', () => <HeaderSortingClassesTable />)
.add('Custom Style on Sorting Header Column', () => <HeaderSortingStyleTable />);
Expand Down
1 change: 1 addition & 0 deletions packages/react-bootstrap-table2/src/header-cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ HeaderCell.propTypes = {
attrs: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
sort: PropTypes.bool,
sortFunc: PropTypes.func,
onSort: PropTypes.func,
editable: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
editCellStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
editCellClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
Expand Down
8 changes: 8 additions & 0 deletions packages/react-bootstrap-table2/src/sort/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export default Base =>
if (column.length > 0) {
store.setSort(column[0], order);

if (column[0].onSort) {
column[0].onSort(store.sortField, store.sortOrder);
}

if (this.isRemoteSort() || this.isRemotePagination()) {
this.handleSortChange();
} else {
Expand All @@ -48,6 +52,10 @@ export default Base =>
const { store } = this.props;
store.setSort(column);

if (column.onSort) {
column.onSort(store.sortField, store.sortOrder);
}

if (this.isRemoteSort() || this.isRemotePagination()) {
this.handleSortChange();
} else {
Expand Down
71 changes: 60 additions & 11 deletions packages/react-bootstrap-table2/test/sort/wrapper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@ import wrapperFactory from '../../src/sort/wrapper';

describe('SortWrapper', () => {
let wrapper;

const columns = [{
dataField: 'id',
text: 'ID',
sort: true
}, {
dataField: 'name',
text: 'Name',
sort: true
}];
let columns;

const data = [{
id: 1,
Expand All @@ -37,6 +28,15 @@ describe('SortWrapper', () => {
const SortWrapper = wrapperFactory(BootstrapTable);

beforeEach(() => {
columns = [{
dataField: 'id',
text: 'ID',
sort: true
}, {
dataField: 'name',
text: 'Name',
sort: true
}];
wrapper = shallow(
<SortWrapper
keyField={ keyField }
Expand All @@ -58,9 +58,10 @@ describe('SortWrapper', () => {

describe('call handleSort function', () => {
let sortBySpy;
const sortColumn = columns[0];
let sortColumn;

beforeEach(() => {
sortColumn = columns[0];
store = new Store(keyField);
store.data = data;
sortBySpy = sinon.spy(store, 'sortBy');
Expand Down Expand Up @@ -130,6 +131,32 @@ describe('SortWrapper', () => {
expect(onTableChangeCB.calledOnce).toBeTruthy();
});
});

describe('when column.onSort prop is defined', () => {
const onSortCB = jest.fn();

beforeEach(() => {
columns[0].onSort = onSortCB;
wrapper = shallow(
<SortWrapper
keyField={ keyField }
data={ data }
columns={ columns }
store={ store }
/>
);
wrapper.instance().handleSort(sortColumn);
});

it('should calling column.onSort function correctly', () => {
expect(onSortCB).toHaveBeenCalledTimes(1);
expect(onSortCB).toHaveBeenCalledWith(columns[0].dataField, Const.SORT_DESC);

wrapper.instance().handleSort(sortColumn);
expect(onSortCB).toHaveBeenCalledTimes(2);
expect(onSortCB).toHaveBeenCalledWith(columns[0].dataField, Const.SORT_ASC);
});
});
});

describe('when defaultSorted prop is defined', () => {
Expand Down Expand Up @@ -161,6 +188,28 @@ describe('SortWrapper', () => {
it('should update store.sortOrder correctly', () => {
expect(store.sortOrder).toEqual(defaultSorted[0].order);
});

describe('when column.onSort prop is defined', () => {
const onSortCB = jest.fn();

beforeEach(() => {
columns[1].onSort = onSortCB;
wrapper = shallow(
<SortWrapper
keyField={ keyField }
data={ data }
columns={ columns }
store={ store }
defaultSorted={ defaultSorted }
/>
);
});

it('should calling column.onSort function correctly', () => {
expect(onSortCB).toHaveBeenCalledTimes(1);
expect(onSortCB).toHaveBeenCalledWith(defaultSorted[0].dataField, defaultSorted[0].order);
});
});
});

describe('componentWillReceiveProps', () => {
Expand Down