diff --git a/docs/README.md b/docs/README.md
index 828cae1..096ca24 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -145,7 +145,7 @@ Custom the events on row:
```js
const rowEvents = {
- onClick: (e) => {
+ onClick: (e, row, rowIndex) => {
....
}
};
diff --git a/docs/columns.md b/docs/columns.md
index cf546a8..b80c48a 100644
--- a/docs/columns.md
+++ b/docs/columns.md
@@ -12,6 +12,7 @@ Available properties in a column object:
* [formatExtraData](#formatExtraData)
* [sort](#sort)
* [sortFunc](#sortFunc)
+* [onSort](#onSort)
* [classes](#classes)
* [style](#style)
* [title](#title)
@@ -122,6 +123,19 @@ Enable the column sort via a `true` value given.
```
> The possible value of `order` argument is **`asc`** and **`desc`**.
+## column.onSort - [Function]
+`column.onSort` is an event listener for sort change event:
+
+```js
+{
+ // omit...
+ sort: true,
+ onSort: (field, order) => {
+ // ....
+ }
+}
+```
+
## column.classes - [String | Function]
It's availabe to have custom class on table column:
diff --git a/docs/migration.md b/docs/migration.md
index fb294c3..ae009e4 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -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
@@ -85,7 +86,7 @@ Please see [available filter configuration](https://react-bootstrap-table.github
- [ ] Regex Filter
- [x] Select Filter
- [x] Custom Select Filter
-- [ ] Number Filter
+- [X] Number Filter
- [ ] Date Filter
- [ ] Array Filter
- [ ] Programmatically Filter
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/custom-number-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/custom-number-filter.js
new file mode 100644
index 0000000..29c361d
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/custom-number-filter.js
@@ -0,0 +1,74 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ options: [2100, 2103, 2105],
+ delay: 600,
+ placeholder: 'custom placeholder',
+ withoutEmptyComparatorOption: true,
+ comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
+ style: { display: 'inline-grid' },
+ className: 'custom-numberfilter-class',
+ comparatorStyle: { backgroundColor: 'antiquewhite' },
+ comparatorClassName: 'custom-comparator-class',
+ numberStyle: { backgroundColor: 'cadetblue', margin: '0px' },
+ numberClassName: 'custom-number-class'
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ options: [2100, 2103, 2105],
+ delay: 600,
+ placeholder: 'custom placeholder',
+ withoutEmptyComparatorOption: true,
+ comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
+ style: { display: 'inline-grid' },
+ className: 'custom-numberfilter-class',
+ comparatorStyle: { backgroundColor: 'antiquewhite' },
+ comparatorClassName: 'custom-comparator-class',
+ numberStyle: { backgroundColor: 'cadetblue', margin: '0px' },
+ numberClassName: 'custom-number-class'
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/number-filter-default-value.js b/packages/react-bootstrap-table2-example/examples/column-filter/number-filter-default-value.js
new file mode 100644
index 0000000..463b472
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/number-filter-default-value.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ defaultValue: { number: 2103, comparator: Comparator.GT }
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter({
+ defaultValue: { number: 2103, comparator: Comparator.GT }
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/number-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/number-filter.js
new file mode 100644
index 0000000..b01167f
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/number-filter.js
@@ -0,0 +1,50 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter()
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter()
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/text-filter-caseSensitive.js b/packages/react-bootstrap-table2-example/examples/column-filter/text-filter-caseSensitive.js
new file mode 100644
index 0000000..aa1f421
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/text-filter-caseSensitive.js
@@ -0,0 +1,51 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter({ caseSensitive: true })
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter({ caseSensitive: true })
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+
+`;
+
+export default () => (
+
+
Product Name is case sensitive
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/rows/row-event.js b/packages/react-bootstrap-table2-example/examples/rows/row-event.js
index 915f9af..1a57fb6 100644
--- a/packages/react-bootstrap-table2-example/examples/rows/row-event.js
+++ b/packages/react-bootstrap-table2-example/examples/rows/row-event.js
@@ -20,8 +20,8 @@ const columns = [{
}];
const rowEvents = {
- onClick: (e) => {
- alert('click on row');
+ onClick: (e, row, rowIndex) => {
+ alert(`clicked on row with index: ${rowIndex}`);
}
};
@@ -40,8 +40,8 @@ const columns = [{
}];
const rowEvents = {
- onClick: (e) => {
- alert('click on row');
+ onClick: (e, row, rowIndex) => {
+ alert(\`clicked on row with index: \${rowIndex}\`);
}
};
diff --git a/packages/react-bootstrap-table2-example/examples/sort/sort-events.js b/packages/react-bootstrap-table2-example/examples/sort/sort-events.js
new file mode 100644
index 0000000..06b406f
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/sort/sort-events.js
@@ -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'
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index f5e3db7..09bce47 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -37,12 +37,16 @@ import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
import TextFilter from 'examples/column-filter/text-filter';
import TextFilterWithDefaultValue from 'examples/column-filter/text-filter-default-value';
import TextFilterComparator from 'examples/column-filter/text-filter-eq-comparator';
+import TextFilterCaseSensitive from 'examples/column-filter/text-filter-caseSensitive';
import CustomTextFilter from 'examples/column-filter/custom-text-filter';
import CustomFilterValue from 'examples/column-filter/custom-filter-value';
import SelectFilter from 'examples/column-filter/select-filter';
import SelectFilterWithDefaultValue from 'examples/column-filter/select-filter-default-value';
import SelectFilterComparator from 'examples/column-filter/select-filter-like-comparator';
import CustomSelectFilter from 'examples/column-filter/custom-select-filter';
+import NumberFilter from 'examples/column-filter/number-filter';
+import NumberFilterWithDefaultValue from 'examples/column-filter/number-filter-default-value';
+import CustomNumberFilter from 'examples/column-filter/custom-number-filter';
// work on rows
import RowStyleTable from 'examples/rows/row-style';
@@ -52,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';
@@ -143,12 +148,16 @@ storiesOf('Column Filter', module)
.add('Text Filter', () => )
.add('Text Filter with Default Value', () => )
.add('Text Filter with Comparator', () => )
- .add('Custom Text Filter', () => )
+ .add('Text Filter with Case Sensitive', () => )
// add another filter type example right here.
.add('Select Filter', () => )
.add('Select Filter with Default Value', () => )
.add('Select Filter with Comparator', () => )
+ .add('Number Filter', () => )
+ .add('Number Filter with Default Value', () => )
+ .add('Custom Text Filter', () => )
.add('Custom Select Filter', () => )
+ .add('Custom Number Filter', () => )
.add('Custom Filter Value', () => );
storiesOf('Work on Rows', module)
@@ -159,6 +168,7 @@ storiesOf('Work on Rows', module)
storiesOf('Sort Table', module)
.add('Enable Sort', () => )
.add('Default Sort Table', () => )
+ .add('Sort Events', () => )
.add('Custom Sort Fuction', () => )
.add('Custom Classes on Sorting Header Column', () => )
.add('Custom Style on Sorting Header Column', () => );
diff --git a/packages/react-bootstrap-table2-filter/README.md b/packages/react-bootstrap-table2-filter/README.md
index 7557419..07561bf 100644
--- a/packages/react-bootstrap-table2-filter/README.md
+++ b/packages/react-bootstrap-table2-filter/README.md
@@ -18,6 +18,7 @@ You can get all types of filters via import and these filters are a factory func
* TextFilter
* SelectFilter
+* NumberFilter
* **Coming soon!**
## Add CSS
@@ -58,6 +59,7 @@ const priceFilter = textFilter({
className: 'my-custom-text-filter', // custom classname on input
defaultValue: 'test', // default filtering value
comparator: Comparator.EQ, // default is Comparator.LIKE
+ caseSensitive: true, // default is false, and true will only work when comparator is LIKE
style: { ... }, // your custom styles on input
delay: 1000 // how long will trigger filtering after user typing, default is 500 ms
});
@@ -107,5 +109,44 @@ const qualityFilter = selectFilter({
withoutEmptyOption: true // hide the default select option
});
+// omit...
+```
+
+## Number Filter
+
+```js
+import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
+
+const columns = [..., {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: numberFilter()
+}];
+
+
+```
+
+Numner filter is same as other filter, you can custom the number filter via `numberFilter` factory function:
+
+```js
+import filterFactory, { selectFilter, Comparator } from 'react-bootstrap-table2-filter';
+// omit...
+
+const numberFilter = numberFilter({
+ options: [2100, 2103, 2105], // if options defined, will render number select instead of number input
+ delay: 600, // how long will trigger filtering after user typing, default is 500 ms
+ placeholder: 'custom placeholder', // placeholder for number input
+ withoutEmptyComparatorOption: true, // dont render empty option for comparator
+ withoutEmptyNumberOption: true, // dont render empty option for numner select if it is defined
+ comparators: [Comparator.EQ, Comparator.GT, Comparator.LT], // Custom the comparators
+ style: { display: 'inline-grid' }, // custom the style on number filter
+ className: 'custom-numberfilter-class', // custom the class on number filter
+ comparatorStyle: { backgroundColor: 'antiquewhite' }, // custom the style on comparator select
+ comparatorClassName: 'custom-comparator-class', // custom the class on comparator select
+ numberStyle: { backgroundColor: 'cadetblue', margin: '0px' }, // custom the style on number input/select
+ numberClassName: 'custom-number-class', // custom the class on ber input/select
+ defaultValue: { number: 2103, comparator: Comparator.GT } // default value
+})
+
// omit...
```
\ No newline at end of file
diff --git a/packages/react-bootstrap-table2-filter/index.js b/packages/react-bootstrap-table2-filter/index.js
index 068b508..a2bc666 100644
--- a/packages/react-bootstrap-table2-filter/index.js
+++ b/packages/react-bootstrap-table2-filter/index.js
@@ -1,5 +1,6 @@
import TextFilter from './src/components/text';
import SelectFilter from './src/components/select';
+import NumberFilter from './src/components/number';
import wrapperFactory from './src/wrapper';
import * as Comparison from './src/comparison';
@@ -19,3 +20,8 @@ export const selectFilter = (props = {}) => ({
Filter: SelectFilter,
props
});
+
+export const numberFilter = (props = {}) => ({
+ Filter: NumberFilter,
+ props
+});
diff --git a/packages/react-bootstrap-table2-filter/src/comparison.js b/packages/react-bootstrap-table2-filter/src/comparison.js
index cc24214..7e599e7 100644
--- a/packages/react-bootstrap-table2-filter/src/comparison.js
+++ b/packages/react-bootstrap-table2-filter/src/comparison.js
@@ -1,2 +1,7 @@
export const LIKE = 'LIKE';
export const EQ = '=';
+export const NE = '!=';
+export const GT = '>';
+export const GE = '>=';
+export const LT = '<';
+export const LE = '<=';
diff --git a/packages/react-bootstrap-table2-filter/src/components/number.js b/packages/react-bootstrap-table2-filter/src/components/number.js
new file mode 100644
index 0000000..3c2b612
--- /dev/null
+++ b/packages/react-bootstrap-table2-filter/src/components/number.js
@@ -0,0 +1,249 @@
+/* eslint no-return-assign: 0 */
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import * as Comparator from '../comparison';
+import { FILTER_TYPE, FILTER_DELAY } from '../const';
+
+const legalComparators = [
+ Comparator.EQ,
+ Comparator.NE,
+ Comparator.GT,
+ Comparator.GE,
+ Comparator.LT,
+ Comparator.LE
+];
+
+class NumberFilter extends Component {
+ constructor(props) {
+ super(props);
+ this.comparators = props.comparators || legalComparators;
+ this.timeout = null;
+ let isSelected = props.defaultValue !== undefined && props.defaultValue.number !== undefined;
+ if (props.options && isSelected) {
+ isSelected = props.options.indexOf(props.defaultValue.number) > -1;
+ }
+ this.state = { isSelected };
+ this.onChangeNumber = this.onChangeNumber.bind(this);
+ this.onChangeNumberSet = this.onChangeNumberSet.bind(this);
+ this.onChangeComparator = this.onChangeComparator.bind(this);
+ }
+
+ componentDidMount() {
+ const { column, onFilter } = this.props;
+ const comparator = this.numberFilterComparator.value;
+ const number = this.numberFilter.value;
+ if (comparator && number) {
+ onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER);
+ }
+ }
+
+ componentWillUnmount() {
+ clearTimeout(this.timeout);
+ }
+
+ onChangeNumber(e) {
+ const { delay, column, onFilter } = this.props;
+ const comparator = this.numberFilterComparator.value;
+ if (comparator === '') {
+ return;
+ }
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ }
+ const filterValue = e.target.value;
+ this.timeout = setTimeout(() => {
+ onFilter(column, { number: filterValue, comparator }, FILTER_TYPE.NUMBER);
+ }, delay);
+ }
+
+ onChangeNumberSet(e) {
+ const { column, onFilter } = this.props;
+ const comparator = this.numberFilterComparator.value;
+ const { value } = e.target;
+ this.setState(() => ({ isSelected: (value !== '') }));
+ // if (comparator === '') {
+ // return;
+ // }
+ onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ }
+
+ onChangeComparator(e) {
+ const { column, onFilter } = this.props;
+ const value = this.numberFilter.value;
+ const comparator = e.target.value;
+ // if (value === '') {
+ // return;
+ // }
+ onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ }
+
+ getComparatorOptions() {
+ const optionTags = [];
+ const { withoutEmptyComparatorOption } = this.props;
+ if (!withoutEmptyComparatorOption) {
+ optionTags.push();
+ }
+ for (let i = 0; i < this.comparators.length; i += 1) {
+ optionTags.push(
+
+ );
+ }
+ return optionTags;
+ }
+
+ getNumberOptions() {
+ const optionTags = [];
+ const { options, column, withoutEmptyNumberOption } = this.props;
+ if (!withoutEmptyNumberOption) {
+ optionTags.push(
+
+ );
+ }
+ for (let i = 0; i < options.length; i += 1) {
+ optionTags.push();
+ }
+ return optionTags;
+ }
+
+ applyFilter(filterObj) {
+ const { column, onFilter } = this.props;
+ const { number, comparator } = filterObj;
+ this.setState(() => ({ isSelected: (number !== '') }));
+ this.numberFilterComparator.value = comparator;
+ this.numberFilter.value = number;
+ onFilter(column, { number, comparator }, FILTER_TYPE.NUMBER);
+ }
+
+ cleanFiltered() {
+ const { column, onFilter, defaultValue } = this.props;
+ const value = defaultValue ? defaultValue.number : '';
+ const comparator = defaultValue ? defaultValue.comparator : '';
+ this.setState(() => ({ isSelected: (value !== '') }));
+ this.numberFilterComparator.value = comparator;
+ this.numberFilter.value = value;
+ onFilter(column, { number: value, comparator }, FILTER_TYPE.NUMBER);
+ }
+
+ render() {
+ const { isSelected } = this.state;
+ const {
+ defaultValue,
+ column,
+ options,
+ style,
+ className,
+ numberStyle,
+ numberClassName,
+ comparatorStyle,
+ comparatorClassName,
+ placeholder
+ } = this.props;
+ const selectClass = `
+ select-filter
+ number-filter-input
+ form-control
+ ${numberClassName}
+ ${!isSelected ? 'placeholder-selected' : ''}
+ `;
+
+ return (
+
+
+ {
+ options ?
+ :
+ this.numberFilter = n }
+ type="number"
+ style={ numberStyle }
+ className={ `number-filter-input form-control ${numberClassName}` }
+ placeholder={ placeholder || `Enter ${column.text}...` }
+ onChange={ this.onChangeNumber }
+ defaultValue={ defaultValue ? defaultValue.number : '' }
+ />
+ }
+
+ );
+ }
+}
+
+NumberFilter.propTypes = {
+ onFilter: PropTypes.func.isRequired,
+ column: PropTypes.object.isRequired,
+ options: PropTypes.arrayOf(PropTypes.number),
+ defaultValue: PropTypes.shape({
+ number: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+ comparator: PropTypes.oneOf([...legalComparators, ''])
+ }),
+ delay: PropTypes.number,
+ /* eslint consistent-return: 0 */
+ comparators: (props, propName) => {
+ if (!props[propName]) {
+ return;
+ }
+ for (let i = 0; i < props[propName].length; i += 1) {
+ let comparatorIsValid = false;
+ for (let j = 0; j < legalComparators.length; j += 1) {
+ if (legalComparators[j] === props[propName][i] || props[propName][i] === '') {
+ comparatorIsValid = true;
+ break;
+ }
+ }
+ if (!comparatorIsValid) {
+ return new Error(`Number comparator provided is not supported.
+ Use only ${legalComparators}`);
+ }
+ }
+ },
+ placeholder: PropTypes.string,
+ withoutEmptyComparatorOption: PropTypes.bool,
+ withoutEmptyNumberOption: PropTypes.bool,
+ style: PropTypes.object,
+ className: PropTypes.string,
+ comparatorStyle: PropTypes.object,
+ comparatorClassName: PropTypes.string,
+ numberStyle: PropTypes.object,
+ numberClassName: PropTypes.string
+};
+
+NumberFilter.defaultProps = {
+ delay: FILTER_DELAY,
+ options: undefined,
+ defaultValue: {
+ number: undefined,
+ comparator: ''
+ },
+ withoutEmptyComparatorOption: false,
+ withoutEmptyNumberOption: false,
+ comparators: legalComparators,
+ placeholder: undefined,
+ style: undefined,
+ className: '',
+ comparatorStyle: undefined,
+ comparatorClassName: '',
+ numberStyle: undefined,
+ numberClassName: ''
+};
+
+export default NumberFilter;
diff --git a/packages/react-bootstrap-table2-filter/src/components/select.js b/packages/react-bootstrap-table2-filter/src/components/select.js
index 0374280..7e17afd 100644
--- a/packages/react-bootstrap-table2-filter/src/components/select.js
+++ b/packages/react-bootstrap-table2-filter/src/components/select.js
@@ -89,6 +89,7 @@ class SelectFilter extends Component {
options,
comparator,
withoutEmptyOption,
+ caseSensitive,
...rest
} = this.props;
@@ -119,14 +120,16 @@ SelectFilter.propTypes = {
style: PropTypes.object,
className: PropTypes.string,
withoutEmptyOption: PropTypes.bool,
- defaultValue: PropTypes.any
+ defaultValue: PropTypes.any,
+ caseSensitive: PropTypes.bool
};
SelectFilter.defaultProps = {
defaultValue: '',
className: '',
withoutEmptyOption: false,
- comparator: EQ
+ comparator: EQ,
+ caseSensitive: true
};
export default SelectFilter;
diff --git a/packages/react-bootstrap-table2-filter/src/components/text.js b/packages/react-bootstrap-table2-filter/src/components/text.js
index 1c102c3..ffbe702 100644
--- a/packages/react-bootstrap-table2-filter/src/components/text.js
+++ b/packages/react-bootstrap-table2-filter/src/components/text.js
@@ -69,7 +69,16 @@ class TextFilter extends Component {
}
render() {
- const { placeholder, column: { text }, style, className, onFilter, ...rest } = this.props;
+ const {
+ placeholder,
+ column: { text },
+ style,
+ className,
+ onFilter,
+ caseSensitive,
+ defaultValue,
+ ...rest
+ } = this.props;
// stopPropagation for onClick event is try to prevent sort was triggered.
return (
(
data,
dataField,
- { filterVal, comparator = LIKE },
+ { filterVal = '', comparator = LIKE, caseSensitive },
customFilterValue
) =>
data.filter((row) => {
@@ -16,15 +18,81 @@ export const filterByText = _ => (
if (comparator === EQ) {
return cellStr === filterVal;
}
- return cellStr.indexOf(filterVal) > -1;
+ if (caseSensitive) {
+ return cellStr.includes(filterVal);
+ }
+ return cellStr.toLocaleUpperCase().includes(filterVal.toLocaleUpperCase());
+ });
+
+export const filterByNumber = _ => (
+ data,
+ dataField,
+ { filterVal: { comparator, number } },
+ customFilterValue
+) =>
+ data.filter((row) => {
+ if (number === '' || !comparator) return true;
+ let valid = true;
+ let cell = _.get(row, dataField);
+ if (customFilterValue) {
+ cell = customFilterValue(cell, row);
+ }
+
+ switch (comparator) {
+ case EQ: {
+ if (cell != number) {
+ valid = false;
+ }
+ break;
+ }
+ case GT: {
+ if (cell <= number) {
+ valid = false;
+ }
+ break;
+ }
+ case GE: {
+ if (cell < number) {
+ valid = false;
+ }
+ break;
+ }
+ case LT: {
+ if (cell >= number) {
+ valid = false;
+ }
+ break;
+ }
+ case LE: {
+ if (cell > number) {
+ valid = false;
+ }
+ break;
+ }
+ case NE: {
+ if (cell == number) {
+ valid = false;
+ }
+ break;
+ }
+ default: {
+ console.error('Number comparator provided is not supported');
+ break;
+ }
+ }
+ return valid;
});
export const filterFactory = _ => (filterType) => {
let filterFn;
switch (filterType) {
case FILTER_TYPE.TEXT:
+ case FILTER_TYPE.SELECT:
filterFn = filterByText(_);
break;
+ case FILTER_TYPE.NUMBER:
+ filterFn = filterByNumber(_);
+ break;
default:
filterFn = filterByText(_);
}
diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js
index 3e6822a..f48e031 100644
--- a/packages/react-bootstrap-table2-filter/src/wrapper.js
+++ b/packages/react-bootstrap-table2-filter/src/wrapper.js
@@ -49,8 +49,11 @@ export default (Base, {
delete currFilters[dataField];
} else {
// select default comparator is EQ, others are LIKE
- const { comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE) } = filter.props;
- currFilters[dataField] = { filterVal, filterType, comparator };
+ const {
+ comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE),
+ caseSensitive = false
+ } = filter.props;
+ currFilters[dataField] = { filterVal, filterType, comparator, caseSensitive };
}
store.filters = currFilters;
diff --git a/packages/react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss b/packages/react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss
index 16aa6dd..70d4a03 100644
--- a/packages/react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss
+++ b/packages/react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss
@@ -3,7 +3,9 @@
}
.react-bootstrap-table > table > thead > tr > th .select-filter option[value=''],
-.react-bootstrap-table > table > thead > tr > th .select-filter.placeholder-selected {
+.react-bootstrap-table > table > thead > tr > th .select-filter.placeholder-selected,
+.react-bootstrap-table > table > thead > tr > th .filter::-webkit-input-placeholder,
+.react-bootstrap-table > table > thead > tr > th .number-filter-input::-webkit-input-placeholder {
color: lightgrey;
font-style: italic;
}
@@ -11,4 +13,19 @@
.react-bootstrap-table > table > thead > tr > th .select-filter.placeholder-selected option:not([value='']) {
color: initial;
font-style: initial;
+}
+
+.react-bootstrap-table > table > thead > tr > th .number-filter {
+ display: flex;
+}
+
+.react-bootstrap-table > table > thead > tr > th .number-filter-input {
+ margin-left: 5px;
+ float: left;
+ width: calc(100% - 67px - 5px);
+}
+
+.react-bootstrap-table > table > thead > tr > th .number-filter-comparator {
+ width: 67px;
+ float: left;
}
\ No newline at end of file
diff --git a/packages/react-bootstrap-table2-filter/test/components/number.test.js b/packages/react-bootstrap-table2-filter/test/components/number.test.js
new file mode 100644
index 0000000..6ba66f7
--- /dev/null
+++ b/packages/react-bootstrap-table2-filter/test/components/number.test.js
@@ -0,0 +1,310 @@
+import 'jsdom-global/register';
+import React from 'react';
+import sinon from 'sinon';
+import { mount } from 'enzyme';
+import NumberFilter from '../../src/components/number';
+import { FILTER_TYPE } from '../../src/const';
+import * as Comparator from '../../src/comparison';
+
+
+describe('Number Filter', () => {
+ let wrapper;
+ const onFilter = sinon.stub();
+ const column = {
+ dataField: 'price',
+ text: 'Product Price'
+ };
+
+ afterEach(() => {
+ onFilter.reset();
+ });
+
+ describe('initialization', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should have correct state', () => {
+ expect(wrapper.state().isSelected).toBeFalsy();
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('select')).toHaveLength(1);
+ expect(wrapper.find('input[type="number"]')).toHaveLength(1);
+ expect(wrapper.find('.number-filter')).toHaveLength(1);
+ });
+
+ it('should rendering comparator options correctly', () => {
+ const select = wrapper.find('select');
+ expect(select.find('option')).toHaveLength(wrapper.prop('comparators').length + 1);
+ });
+ });
+
+ describe('when withoutEmptyComparatorOption prop is true', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering comparator options correctly', () => {
+ const select = wrapper.find('select');
+ expect(select.find('option')).toHaveLength(wrapper.prop('comparators').length);
+ });
+ });
+
+ describe('when defaultValue.number props is defined', () => {
+ const number = 203;
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering input successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ const input = wrapper.find('input[type="number"]');
+ expect(input).toHaveLength(1);
+ expect(input.props().defaultValue).toEqual(number);
+ });
+ });
+
+ describe('when defaultValue.comparator props is defined', () => {
+ const comparator = Comparator.EQ;
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering comparator select successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ const select = wrapper.find('.number-filter-comparator');
+ expect(select).toHaveLength(1);
+ expect(select.props().defaultValue).toEqual(comparator);
+ });
+ });
+
+ describe('when defaultValue.number and defaultValue.comparator props is defined', () => {
+ const number = 203;
+ const comparator = Comparator.EQ;
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should have correct state', () => {
+ expect(wrapper.state().isSelected).toBeTruthy();
+ });
+
+ it('should calling onFilter on componentDidMount', () => {
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(
+ column, { number: `${number}`, comparator }, FILTER_TYPE.NUMBER)).toBeTruthy();
+ });
+ });
+
+ describe('when options props is defined', () => {
+ const options = [2100, 2103, 2105];
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering number options instead of number input', () => {
+ expect(wrapper).toHaveLength(1);
+ const select = wrapper.find('.select-filter.placeholder-selected');
+ expect(select).toHaveLength(1);
+ expect(select.find('option')).toHaveLength(options.length + 1);
+ });
+
+ describe('when withoutEmptyNumberOption props is defined', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering number options instead of number input', () => {
+ const select = wrapper.find('.select-filter.placeholder-selected');
+ expect(select).toHaveLength(1);
+ expect(select.find('option')).toHaveLength(options.length);
+ });
+ });
+
+ describe('when defaultValue.number props is defined', () => {
+ const number = 203;
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering number options successfully', () => {
+ const select = wrapper.find('.select-filter.placeholder-selected');
+ expect(select).toHaveLength(1);
+ expect(select.props().defaultValue).toEqual(number);
+ });
+ });
+
+ describe('when defaultValue.number and defaultValue.comparator props is defined', () => {
+ const number = options[1];
+ const comparator = Comparator.EQ;
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering number options successfully', () => {
+ let select = wrapper.find('.placeholder-selected');
+ expect(select).toHaveLength(0);
+
+ select = wrapper.find('.select-filter');
+ expect(select).toHaveLength(1);
+ });
+ });
+ });
+
+ describe('when style props is defined', () => {
+ const style = { backgroundColor: 'red' };
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('.number-filter').prop('style')).toEqual(style);
+ });
+ });
+
+ describe('when numberStyle props is defined', () => {
+ const numberStyle = { backgroundColor: 'red' };
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('.number-filter-input').prop('style')).toEqual(numberStyle);
+ });
+ });
+
+ describe('when comparatorStyle props is defined', () => {
+ const comparatorStyle = { backgroundColor: 'red' };
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('select').prop('style')).toEqual(comparatorStyle);
+ });
+ });
+
+ describe('when className props is defined', () => {
+ const className = 'test';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.hasClass(className)).toBeTruthy();
+ });
+ });
+
+ describe('when numberClassName props is defined', () => {
+ const className = 'test';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('.number-filter-input').prop('className').indexOf(className) > -1).toBeTruthy();
+ });
+ });
+
+ describe('when comparatorClassName props is defined', () => {
+ const className = 'test';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('select').prop('className').indexOf(className) > -1).toBeTruthy();
+ });
+ });
+});
diff --git a/packages/react-bootstrap-table2-filter/test/filter.test.js b/packages/react-bootstrap-table2-filter/test/filter.test.js
index e834f17..ae66a38 100644
--- a/packages/react-bootstrap-table2-filter/test/filter.test.js
+++ b/packages/react-bootstrap-table2-filter/test/filter.test.js
@@ -4,7 +4,7 @@ import Store from 'react-bootstrap-table-next/src/store';
import { filters } from '../src/filter';
import { FILTER_TYPE } from '../src/const';
-import { LIKE, EQ } from '../src/comparison';
+import { LIKE, EQ, GT, GE, LT, LE, NE } from '../src/comparison';
const data = [];
for (let i = 0; i < 20; i += 1) {
@@ -37,7 +37,7 @@ describe('filter', () => {
}];
});
- describe('text filter', () => {
+ describe('filterByText', () => {
beforeEach(() => {
filterFn = filters(store, columns, _);
});
@@ -55,6 +55,20 @@ describe('filter', () => {
});
});
+ describe('when caseSensitive is true', () => {
+ it('should returning correct result', () => {
+ currFilters.name = {
+ filterVal: 'NAME',
+ caseSensitive: true,
+ filterType: FILTER_TYPE.TEXT
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toBeDefined();
+ expect(result).toHaveLength(0);
+ });
+ });
+
describe(`when default comparator is ${EQ}`, () => {
it('should returning correct result', () => {
currFilters.name = {
@@ -91,4 +105,114 @@ describe('filter', () => {
});
});
});
+
+ describe('filterByNumber', () => {
+ beforeEach(() => {
+ filterFn = filters(store, columns, _);
+ });
+
+ describe('when currFilters.filterVal.comparator is empty', () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: '', number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ let result = filterFn(currFilters);
+ expect(result).toHaveLength(data.length);
+
+ currFilters.price.filterVal.comparator = undefined;
+ result = filterFn(currFilters);
+ expect(result).toHaveLength(data.length);
+ });
+ });
+
+ describe('when currFilters.filterVal.number is empty', () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: EQ, number: '' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(data.length);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${EQ}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: EQ, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ let result = filterFn(currFilters);
+ expect(result).toHaveLength(1);
+
+ currFilters.price.filterVal.number = '0';
+ result = filterFn(currFilters);
+ expect(result).toHaveLength(0);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${GT}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: GT, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(16);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${GE}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: GE, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(17);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${LT}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: LT, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(3);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${LE}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: LE, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(4);
+ });
+ });
+
+ describe(`when currFilters.filterVal.comparator is ${NE}`, () => {
+ it('should returning correct result', () => {
+ currFilters.price = {
+ filterVal: { comparator: NE, number: '203' },
+ filterType: FILTER_TYPE.NUMBER
+ };
+
+ const result = filterFn(currFilters);
+ expect(result).toHaveLength(19);
+ });
+ });
+ });
});
diff --git a/packages/react-bootstrap-table2/src/header-cell.js b/packages/react-bootstrap-table2/src/header-cell.js
index d5dd47b..b6af21e 100644
--- a/packages/react-bootstrap-table2/src/header-cell.js
+++ b/packages/react-bootstrap-table2/src/header-cell.js
@@ -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]),
diff --git a/packages/react-bootstrap-table2/src/row.js b/packages/react-bootstrap-table2/src/row.js
index fa723af..1b55628 100644
--- a/packages/react-bootstrap-table2/src/row.js
+++ b/packages/react-bootstrap-table2/src/row.js
@@ -13,6 +13,7 @@ class Row extends Component {
super(props);
this.clickNum = 0;
this.handleRowClick = this.handleRowClick.bind(this);
+ this.handleSimpleRowClick = this.handleSimpleRowClick.bind(this);
}
handleRowClick(e) {
@@ -36,7 +37,7 @@ class Row extends Component {
const clickFn = () => {
if (attrs.onClick) {
- attrs.onClick(e);
+ attrs.onClick(e, row, rowIndex);
}
if (selectable) {
const key = _.get(row, keyField);
@@ -57,6 +58,16 @@ class Row extends Component {
}
}
+ handleSimpleRowClick(e) {
+ const {
+ row,
+ rowIndex,
+ attrs
+ } = this.props;
+
+ attrs.onClick(e, row, rowIndex);
+ }
+
render() {
const {
row,
@@ -90,6 +101,8 @@ class Row extends Component {
const trAttrs = { ...attrs };
if (clickToSelect) {
trAttrs.onClick = this.handleRowClick;
+ } else if (attrs.onClick) {
+ trAttrs.onClick = this.handleSimpleRowClick;
}
return (
diff --git a/packages/react-bootstrap-table2/src/sort/wrapper.js b/packages/react-bootstrap-table2/src/sort/wrapper.js
index 45414e3..90a9bb9 100644
--- a/packages/react-bootstrap-table2/src/sort/wrapper.js
+++ b/packages/react-bootstrap-table2/src/sort/wrapper.js
@@ -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 {
@@ -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 {
diff --git a/packages/react-bootstrap-table2/test/sort/wrapper.test.js b/packages/react-bootstrap-table2/test/sort/wrapper.test.js
index d8a3ce7..1c28b8c 100644
--- a/packages/react-bootstrap-table2/test/sort/wrapper.test.js
+++ b/packages/react-bootstrap-table2/test/sort/wrapper.test.js
@@ -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,
@@ -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(
{
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');
@@ -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(
+
+ );
+ 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', () => {
@@ -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(
+
+ );
+ });
+
+ it('should calling column.onSort function correctly', () => {
+ expect(onSortCB).toHaveBeenCalledTimes(1);
+ expect(onSortCB).toHaveBeenCalledWith(defaultSorted[0].dataField, defaultSorted[0].order);
+ });
+ });
});
describe('componentWillReceiveProps', () => {