* implement default sort

* add story for default sort

* add test for default sort

* patch docs for default sort

* a workaround to avoid render twice by story.add
This commit is contained in:
Allen
2017-10-29 16:58:37 +08:00
committed by GitHub
parent ab305a7db2
commit e1e8c00271
8 changed files with 136 additions and 6 deletions

View File

@@ -15,6 +15,7 @@
* [condensed](#condensed)
* [cellEdit](#cellEdit)
* [selectRow](#selectRow)
* [defaultSorted](#defaultSorted)
### <a name='keyField'>keyField(**required**) - [String]</a>
Tells `react-bootstrap-table2` which column is unique.
@@ -41,4 +42,14 @@ Same as bootstrap `.table-condensed` class for making a table more compact by cu
Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail.
### <a name='selectRow'>selectRow - [Object]</a>
Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail.
Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail.
### <a name='defaultSorted'>defaultSorted - [Array]</a>
`defaultSorted` accept an object array which allow you to define the default sort columns when first render.
```js
const defaultSorted = [{
dataField: 'name', // if dataField is not match to any column you defined, it will be ignored.
order: 'desc' // desc or asc
}];
```

View File

@@ -0,0 +1,59 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
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
}, {
dataField: 'price',
text: 'Product Price',
sort: true
}];
const defaultSorted = [{
dataField: 'name',
order: 'desc'
}];
const sourceCode = `\
const columns = [{
dataField: 'id',
text: 'Product ID',
sort: true
}, {
dataField: 'name',
text: 'Product Name',
sort: true
}, {
dataField: 'price',
text: 'Product Price',
sort: true
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } />
`;
class DefaultSortTable extends React.PureComponent {
render() {
return (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } defaultSorted={ defaultSorted } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
export default DefaultSortTable;

View File

@@ -34,6 +34,7 @@ import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
// table sort
import EnableSortTable from 'examples/sort/enable-sort-table';
import DefaultSortTable from 'examples/sort/default-sort-table';
import CustomSortTable from 'examples/sort/custom-sort-table';
// cell editing
@@ -104,6 +105,7 @@ storiesOf('Work on Header Columns', module)
storiesOf('Sort Table', module)
.add('Enable Sort', () => <EnableSortTable />)
.add('Default Sort Table', () => <DefaultSortTable />)
.add('Custom Sort Fuction', () => <CustomSortTable />);
storiesOf('Cell Editing', module)

View File

@@ -139,7 +139,11 @@ BootstrapTable.propTypes = {
hideSelectColumn: PropTypes.bool
}),
onRowSelect: PropTypes.func,
onAllRowsSelect: PropTypes.func
onAllRowsSelect: PropTypes.func,
defaultSorted: PropTypes.arrayOf(PropTypes.shape({
dataField: PropTypes.string.isRequired,
order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired
}))
};
BootstrapTable.defaultProps = {

View File

@@ -12,6 +12,20 @@ class SortWrapper extends Component {
this.handleSort = this.handleSort.bind(this);
}
componentWillMount() {
const { columns, defaultSorted, store } = this.props;
// defaultSorted is an array, it's ready to use as multi / single sort
// when we start to support multi sort, please update following code to use array.forEach
if (defaultSorted && defaultSorted.length > 0) {
const dataField = defaultSorted[0].dataField;
const order = defaultSorted[0].order;
const column = columns.filter(col => col.dataField === dataField);
if (column.length > 0) {
store.sortBy(column[0], order);
}
}
}
handleSort(column) {
const { store } = this.props;
store.sortBy(column);
@@ -25,7 +39,8 @@ class SortWrapper extends Component {
return sortableElement({
...this.props,
ref: node => this.table = node,
onSort: this.handleSort
onSort: this.handleSort,
data: this.props.store.get()
});
}
}

View File

@@ -18,8 +18,10 @@ export default class Store {
return this.data.length === 0;
}
sortBy({ dataField, sortFunc }) {
if (dataField !== this.sortField) {
sortBy({ dataField, sortFunc }, order) {
if (order) {
this.sortOrder = order;
} else if (dataField !== this.sortField) {
this.sortOrder = Const.SORT_DESC;
} else {
this.sortOrder = this.sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC;

View File

@@ -16,7 +16,8 @@ describe('SortWrapper', () => {
sort: true
}, {
dataField: 'name',
text: 'Name'
text: 'Name',
sort: true
}];
const data = [{
@@ -80,4 +81,35 @@ describe('SortWrapper', () => {
expect(store.sortField).toEqual(sortColumn.dataField);
});
});
describe('when defaultSorted prop is defined', () => {
const defaultSorted = [{
dataField: 'name',
order: Const.SORT_DESC
}];
beforeEach(() => {
wrapper = shallow(
<SortWrapper
keyField={ keyField }
data={ data }
columns={ columns }
store={ store }
defaultSorted={ defaultSorted }
/>
);
});
it('should render table with correct default sorted', () => {
expect(wrapper.props().data).toEqual(store.get());
});
it('should update store.sortField correctly', () => {
expect(store.sortField).toEqual(defaultSorted[0].dataField);
});
it('should update store.sortOrder correctly', () => {
expect(store.sortOrder).toEqual(defaultSorted[0].order);
});
});
});

View File

@@ -73,6 +73,11 @@ describe('Store Base', () => {
expect(e[dataField]).toEqual(result[i]);
});
});
it('should force assign sortOrder correctly if second argument is passed', () => {
store.sortBy({ dataField }, Const.SORT_DESC);
expect(store.sortOrder).toEqual(Const.SORT_DESC);
});
});
describe('getRowByRowId', () => {