diff --git a/docs/columns.md b/docs/columns.md
index a18a073..cf546a8 100644
--- a/docs/columns.md
+++ b/docs/columns.md
@@ -542,6 +542,7 @@ Or take a callback function
Configure `column.filter` will able to setup a column level filter on the header column. Currently, `react-bootstrap-table2` support following filters:
* Text(`textFilter`)
+* Select(`selectFilter`)
We have a quick example to show you how to use `column.filter`:
diff --git a/docs/migration.md b/docs/migration.md
index f66b7f7..fb294c3 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -83,7 +83,8 @@ Please see [available filter configuration](https://react-bootstrap-table.github
- [x] Remote Filter
- [ ] Custom Filter Component
- [ ] Regex Filter
-- [ ] Select Filter
+- [x] Select Filter
+- [x] Custom Select Filter
- [ ] Number Filter
- [ ] Date Filter
- [ ] Array Filter
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index f124ae9..77b5c9f 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -24,6 +24,7 @@ const JS_SKIPS = `+(${TEST}|${LIB}|${DIST}|${NODE_MODULES})`;
const STYLE_PKGS = [
'react-bootstrap-table2',
+ 'react-bootstrap-table2-filter',
'react-bootstrap-table2-paginator'
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
diff --git a/packages/react-bootstrap-table2-example/.storybook/webpack.config.js b/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
index 166aef5..a2c12e2 100644
--- a/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
+++ b/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
@@ -7,6 +7,7 @@ const filterSourcePath = path.join(__dirname, '../../react-bootstrap-table2-filt
const editorSourcePath = path.join(__dirname, '../../react-bootstrap-table2-editor/index.js');
const sourceStylePath = path.join(__dirname, '../../react-bootstrap-table2/style');
const paginationStylePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/style');
+const filterStylePath = path.join(__dirname, '../../react-bootstrap-table2-filter/style');
const storyPath = path.join(__dirname, '../stories');
const examplesPath = path.join(__dirname, '../examples');
const srcPath = path.join(__dirname, '../src');
@@ -40,7 +41,7 @@ const loaders = [{
}, {
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
- include: [storyPath, sourceStylePath, paginationStylePath],
+ include: [storyPath, sourceStylePath, paginationStylePath, filterStylePath],
}, {
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000',
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/custom-select-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/custom-select-filter.js
new file mode 100644
index 0000000..be7a366
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/custom-select-filter.js
@@ -0,0 +1,80 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsQualityGenerator } from 'utils/common';
+
+const products = productsQualityGenerator(6);
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ withoutEmptyOption: true,
+ style: {
+ backgroundColor: 'pink'
+ },
+ className: 'test-classname',
+ datamycustomattr: 'datamycustomattr'
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ withoutEmptyOption: true,
+ style: {
+ backgroundColor: 'pink'
+ },
+ className: 'test-classname',
+ datamycustomattr: 'datamycustomattr'
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-default-value.js b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-default-value.js
new file mode 100644
index 0000000..848766a
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-default-value.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsQualityGenerator } from 'utils/common';
+
+const products = productsQualityGenerator(6);
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ defaultValue: 2
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions,
+ defaultValue: 2
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-like-comparator.js b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-like-comparator.js
new file mode 100644
index 0000000..306bdc8
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter-like-comparator.js
@@ -0,0 +1,69 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter, Comparator } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(6);
+
+const selectOptions = {
+ '03': '03',
+ '04': '04',
+ '01': '01'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: selectFilter({
+ options: selectOptions,
+ comparator: Comparator.LIKE // default is Comparator.EQ
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+const selectOptions = {
+ '03': '03',
+ '04': '04',
+ '01': '01'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: selectFilter({
+ options: selectOptions,
+ comparator: Comparator.LIKE // default is Comparator.EQ
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
Select Filter with LIKE Comparator
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/select-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter.js
new file mode 100644
index 0000000..6acf849
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/select-filter.js
@@ -0,0 +1,68 @@
+import React from 'react';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsQualityGenerator } from 'utils/common';
+
+const products = productsQualityGenerator(6);
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions
+ })
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions
+ })
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/src/utils/common.js b/packages/react-bootstrap-table2-example/src/utils/common.js
index 0d5ad84..0f1c9f1 100644
--- a/packages/react-bootstrap-table2-example/src/utils/common.js
+++ b/packages/react-bootstrap-table2-example/src/utils/common.js
@@ -20,6 +20,13 @@ export const productsGenerator = (quantity = 5, callback) => {
);
};
+export const productsQualityGenerator = (quantity = 5) =>
+ Array.from({ length: quantity }, (value, index) => ({
+ id: index,
+ name: `Item name ${index}`,
+ quality: index % 3
+ }));
+
export const jobsGenerator = (quantity = 5) =>
Array.from({ length: quantity }, (value, index) => ({
id: index,
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 8037edb..f5e3db7 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -39,6 +39,10 @@ import TextFilterWithDefaultValue from 'examples/column-filter/text-filter-defau
import TextFilterComparator from 'examples/column-filter/text-filter-eq-comparator';
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';
// work on rows
import RowStyleTable from 'examples/rows/row-style';
@@ -98,6 +102,7 @@ import 'stories/stylesheet/tomorrow.min.css';
import 'stories/stylesheet/storybook.scss';
import '../../react-bootstrap-table2/style/react-bootstrap-table2.scss';
import '../../react-bootstrap-table2-paginator/style/react-bootstrap-table2-paginator.scss';
+import '../../react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss';
// import { action } from '@storybook/addon-actions';
@@ -140,6 +145,10 @@ storiesOf('Column Filter', module)
.add('Text Filter with Comparator', () => )
.add('Custom Text Filter', () => )
// add another filter type example right here.
+ .add('Select Filter', () => )
+ .add('Select Filter with Default Value', () => )
+ .add('Select Filter with Comparator', () => )
+ .add('Custom Select Filter', () => )
.add('Custom Filter Value', () => );
storiesOf('Work on Rows', module)
diff --git a/packages/react-bootstrap-table2-filter/README.md b/packages/react-bootstrap-table2-filter/README.md
index f8b6788..74192b5 100644
--- a/packages/react-bootstrap-table2-filter/README.md
+++ b/packages/react-bootstrap-table2-filter/README.md
@@ -17,6 +17,7 @@ $ npm install react-bootstrap-table2-filter --save
You can get all types of filters via import and these filters are a factory function to create a individual filter instance. Currently, we support following filters:
* TextFilter
+* SelectFilter
* **Coming soon!**
## Text Filter
@@ -51,5 +52,50 @@ const priceFilter = textFilter({
delay: 1000 // how long will trigger filtering after user typing, default is 500 ms
});
+// omit...
+```
+
+## Select Filter
+A quick example:
+
+```js
+import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
+
+// omit...
+const selectOptions = {
+ 0: 'good',
+ 1: 'Bad',
+ 2: 'unknown'
+};
+
+const columns = [
+ ..., {
+ dataField: 'quality',
+ text: 'Product Quailty',
+ formatter: cell => selectOptions[cell],
+ filter: selectFilter({
+ options: selectOptions
+ })
+}];
+
+
+```
+
+Following is an example for custom select filter:
+
+```js
+import filterFactory, { selectFilter, Comparator } from 'react-bootstrap-table2-filter';
+// omit...
+
+const qualityFilter = selectFilter({
+ options: selectOptions,
+ placeholder: 'My Custom PlaceHolder', // custom the input placeholder
+ className: 'my-custom-text-filter', // custom classname on input
+ defaultValue: '2', // default filtering value
+ comparator: Comparator.LIKE, // default is Comparator.EQ
+ style: { ... }, // your custom styles on input
+ withoutEmptyOption: true // hide the default select option
+});
+
// 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 f6335a8..068b508 100644
--- a/packages/react-bootstrap-table2-filter/index.js
+++ b/packages/react-bootstrap-table2-filter/index.js
@@ -1,4 +1,5 @@
import TextFilter from './src/components/text';
+import SelectFilter from './src/components/select';
import wrapperFactory from './src/wrapper';
import * as Comparison from './src/comparison';
@@ -13,3 +14,8 @@ export const textFilter = (props = {}) => ({
Filter: TextFilter,
props
});
+
+export const selectFilter = (props = {}) => ({
+ Filter: SelectFilter,
+ props
+});
diff --git a/packages/react-bootstrap-table2-filter/src/components/select.js b/packages/react-bootstrap-table2-filter/src/components/select.js
new file mode 100644
index 0000000..0374280
--- /dev/null
+++ b/packages/react-bootstrap-table2-filter/src/components/select.js
@@ -0,0 +1,132 @@
+/* eslint react/require-default-props: 0 */
+/* eslint no-return-assign: 0 */
+/* eslint react/no-unused-prop-types: 0 */
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { LIKE, EQ } from '../comparison';
+import { FILTER_TYPE } from '../const';
+
+function optionsEquals(currOpts, prevOpts) {
+ const keys = Object.keys(currOpts);
+ for (let i = 0; i < keys.length; i += 1) {
+ if (currOpts[keys[i]] !== prevOpts[keys[i]]) {
+ return false;
+ }
+ }
+ return Object.keys(currOpts).length === Object.keys(prevOpts).length;
+}
+
+class SelectFilter extends Component {
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ const isSelected = props.options[props.defaultValue] !== undefined;
+ this.state = { isSelected };
+ }
+
+ componentDidMount() {
+ const value = this.selectInput.value;
+ if (value && value !== '') {
+ this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ }
+ }
+
+ componentDidUpdate(prevProps) {
+ let needFilter = false;
+ if (this.props.defaultValue !== prevProps.defaultValue) {
+ needFilter = true;
+ } else if (!optionsEquals(this.props.options, prevProps.options)) {
+ needFilter = true;
+ }
+ if (needFilter) {
+ const value = this.selectInput.value;
+ if (value) {
+ this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ }
+ }
+ }
+
+ getOptions() {
+ const optionTags = [];
+ const { options, placeholder, column, withoutEmptyOption } = this.props;
+ if (!withoutEmptyOption) {
+ optionTags.push((
+
+ ));
+ }
+ Object.keys(options).forEach(key =>
+ optionTags.push()
+ );
+ return optionTags;
+ }
+
+ cleanFiltered() {
+ const value = (this.props.defaultValue !== undefined) ? this.props.defaultValue : '';
+ this.setState(() => ({ isSelected: value !== '' }));
+ this.selectInput.value = value;
+ this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ }
+
+ applyFilter(value) {
+ this.selectInput.value = value;
+ this.setState(() => ({ isSelected: value !== '' }));
+ this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ }
+
+ filter(e) {
+ const { value } = e.target;
+ this.setState(() => ({ isSelected: value !== '' }));
+ this.props.onFilter(this.props.column, value, FILTER_TYPE.SELECT);
+ }
+
+ render() {
+ const {
+ style,
+ className,
+ defaultValue,
+ onFilter,
+ column,
+ options,
+ comparator,
+ withoutEmptyOption,
+ ...rest
+ } = this.props;
+
+ const selectClass =
+ `filter select-filter form-control ${className} ${this.state.isSelected ? '' : 'placeholder-selected'}`;
+
+ return (
+
+ );
+ }
+}
+
+SelectFilter.propTypes = {
+ onFilter: PropTypes.func.isRequired,
+ column: PropTypes.object.isRequired,
+ options: PropTypes.object.isRequired,
+ comparator: PropTypes.oneOf([LIKE, EQ]),
+ placeholder: PropTypes.string,
+ style: PropTypes.object,
+ className: PropTypes.string,
+ withoutEmptyOption: PropTypes.bool,
+ defaultValue: PropTypes.any
+};
+
+SelectFilter.defaultProps = {
+ defaultValue: '',
+ className: '',
+ withoutEmptyOption: false,
+ comparator: EQ
+};
+
+export default SelectFilter;
diff --git a/packages/react-bootstrap-table2-filter/src/const.js b/packages/react-bootstrap-table2-filter/src/const.js
index 25faae0..64e8361 100644
--- a/packages/react-bootstrap-table2-filter/src/const.js
+++ b/packages/react-bootstrap-table2-filter/src/const.js
@@ -1,5 +1,6 @@
export const FILTER_TYPE = {
- TEXT: 'TEXT'
+ TEXT: 'TEXT',
+ SELECT: 'SELECT'
};
export const FILTER_DELAY = 500;
diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js
index 7e197fa..3e6822a 100644
--- a/packages/react-bootstrap-table2-filter/src/wrapper.js
+++ b/packages/react-bootstrap-table2-filter/src/wrapper.js
@@ -3,7 +3,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { filters } from './filter';
-import { LIKE } from './comparison';
+import { LIKE, EQ } from './comparison';
+import { FILTER_TYPE } from './const';
export default (Base, {
_,
@@ -47,7 +48,8 @@ export default (Base, {
if (!_.isDefined(filterVal) || filterVal === '') {
delete currFilters[dataField];
} else {
- const { comparator = LIKE } = filter.props;
+ // select default comparator is EQ, others are LIKE
+ const { comparator = (filterType === FILTER_TYPE.SELECT ? EQ : LIKE) } = filter.props;
currFilters[dataField] = { filterVal, filterType, comparator };
}
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
new file mode 100644
index 0000000..16aa6dd
--- /dev/null
+++ b/packages/react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss
@@ -0,0 +1,14 @@
+.react-bootstrap-table > table > thead > tr > th .filter {
+ font-weight: normal;
+}
+
+.react-bootstrap-table > table > thead > tr > th .select-filter option[value=''],
+.react-bootstrap-table > table > thead > tr > th .select-filter.placeholder-selected {
+ color: lightgrey;
+ font-style: italic;
+}
+
+.react-bootstrap-table > table > thead > tr > th .select-filter.placeholder-selected option:not([value='']) {
+ color: initial;
+ font-style: initial;
+}
\ No newline at end of file
diff --git a/packages/react-bootstrap-table2-filter/test/components/select.test.js b/packages/react-bootstrap-table2-filter/test/components/select.test.js
new file mode 100644
index 0000000..2ed39a6
--- /dev/null
+++ b/packages/react-bootstrap-table2-filter/test/components/select.test.js
@@ -0,0 +1,296 @@
+import 'jsdom-global/register';
+import React from 'react';
+import sinon from 'sinon';
+import { mount } from 'enzyme';
+import SelectFilter from '../../src/components/select';
+import { FILTER_TYPE } from '../../src/const';
+
+
+describe('Select Filter', () => {
+ let wrapper;
+ let instance;
+ const onFilter = sinon.stub();
+ const column = {
+ dataField: 'quality',
+ text: 'Product Quality'
+ };
+ const options = {
+ 0: 'Bad',
+ 1: 'Good',
+ 2: 'Unknow'
+ };
+
+ afterEach(() => {
+ onFilter.reset();
+ });
+
+ describe('initialization', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ });
+
+ it('should have correct state', () => {
+ expect(instance.state.isSelected).toBeFalsy();
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('select')).toHaveLength(1);
+ expect(wrapper.find('.select-filter')).toHaveLength(1);
+ expect(wrapper.find('.placeholder-selected')).toHaveLength(1);
+ });
+
+ it('should rendering select options correctly', () => {
+ const select = wrapper.find('select');
+ expect(select.find('option')).toHaveLength(Object.keys(options).length + 1);
+ expect(select.childAt(0).text()).toEqual(`Select ${column.text}...`);
+
+ Object.keys(options).forEach((key, i) => {
+ expect(select.childAt(i + 1).prop('value')).toEqual(key);
+ expect(select.childAt(i + 1).text()).toEqual(options[key]);
+ });
+ });
+ });
+
+ describe('when defaultValue is defined', () => {
+ let defaultValue;
+
+ describe('and it is valid', () => {
+ beforeEach(() => {
+ defaultValue = '0';
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ });
+
+ it('should have correct state', () => {
+ expect(instance.state.isSelected).toBeTruthy();
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('.placeholder-selected')).toHaveLength(0);
+ });
+
+ it('should calling onFilter on componentDidMount', () => {
+ expect(onFilter.calledOnce).toBeTruthy();
+ expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+ });
+
+ describe('when placeholder is defined', () => {
+ const placeholder = 'test';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ const select = wrapper.find('select');
+ expect(select.childAt(0).text()).toEqual(placeholder);
+ });
+ });
+
+ describe('when style is defined', () => {
+ const style = { backgroundColor: 'red' };
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering component successfully', () => {
+ expect(wrapper).toHaveLength(1);
+ expect(wrapper.find('select').prop('style')).toEqual(style);
+ });
+ });
+
+ describe('when withoutEmptyOption is defined', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ });
+
+ it('should rendering select without default empty option', () => {
+ const select = wrapper.find('select');
+ expect(select.find('option')).toHaveLength(Object.keys(options).length);
+ });
+ });
+
+ describe('componentDidUpdate', () => {
+ let prevProps;
+
+ describe('when props.defaultValue is diff from prevProps.defaultValue', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ prevProps = {
+ column,
+ options,
+ defaultValue: '1'
+ };
+ instance = wrapper.instance();
+ instance.componentDidUpdate(prevProps);
+ });
+
+ it('should update', () => {
+ expect(onFilter.callCount).toBe(2);
+ expect(onFilter.calledWith(
+ column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+
+ describe('when props.options is diff from prevProps.options', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ prevProps = {
+ column,
+ options
+ };
+ instance = wrapper.instance();
+ instance.componentDidUpdate(prevProps);
+ });
+
+ it('should update', () => {
+ expect(onFilter.callCount).toBe(2);
+ expect(onFilter.calledWith(
+ column, instance.props.defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+ });
+
+ describe('cleanFiltered', () => {
+ describe('when props.defaultValue is defined', () => {
+ const defaultValue = '0';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ instance.cleanFiltered();
+ });
+
+ it('should setting state correctly', () => {
+ expect(instance.state.isSelected).toBeTruthy();
+ });
+
+ it('should calling onFilter correctly', () => {
+ expect(onFilter.callCount).toBe(2);
+ expect(onFilter.calledWith(column, defaultValue, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+
+ describe('when props.defaultValue is not defined', () => {
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ instance.cleanFiltered();
+ });
+
+ it('should setting state correctly', () => {
+ expect(instance.state.isSelected).toBeFalsy();
+ });
+
+ it('should calling onFilter correctly', () => {
+ expect(onFilter.callCount).toBe(1);
+ });
+ });
+ });
+
+ describe('applyFilter', () => {
+ const value = '2';
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ instance.applyFilter(value);
+ });
+
+ it('should setting state correctly', () => {
+ expect(instance.state.isSelected).toBeTruthy();
+ });
+
+ it('should calling onFilter correctly', () => {
+ expect(onFilter.callCount).toBe(1);
+ expect(onFilter.calledWith(column, value, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+
+ describe('filter', () => {
+ const event = { target: { value: 'tester' } };
+
+ beforeEach(() => {
+ wrapper = mount(
+
+ );
+ instance = wrapper.instance();
+ instance.filter(event);
+ });
+
+ it('should setting state correctly', () => {
+ expect(instance.state.isSelected).toBeTruthy();
+ });
+
+ it('should calling onFilter correctly', () => {
+ expect(onFilter.callCount).toBe(1);
+ expect(onFilter.calledWith(column, event.target.value, FILTER_TYPE.SELECT)).toBeTruthy();
+ });
+ });
+});
diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
index bcb5799..c0069e2 100644
--- a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
+++ b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
@@ -34,12 +34,12 @@ describe('', () => {
});
});
- describe('handleRowClick', () => {
+ describe('handleClick', () => {
describe('when was been clicked', () => {
const rowKey = 1;
const selected = true;
let mockOnRowSelect;
- const spy = sinon.spy(SelectionCell.prototype, 'handleRowClick');
+ const spy = sinon.spy(SelectionCell.prototype, 'handleClick');
beforeEach(() => {
mockOnRowSelect = sinon.stub();