diff --git a/docs/migration.md b/docs/migration.md
index 5385172..60edbd2 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -82,7 +82,7 @@ Please see [available filter configuration](https://react-bootstrap-table.github
- [x] Text Filter
- [x] Custom Text Filter
- [x] Remote Filter
-- [ ] Custom Filter Component
+- [x] Custom Filter Component
- [ ] Regex Filter
- [x] Select Filter
- [x] Custom Select Filter
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/advance-custom-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/advance-custom-filter.js
new file mode 100644
index 0000000..3736dea
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/advance-custom-filter.js
@@ -0,0 +1,184 @@
+/* eslint no-return-assign: 0 */
+import React from 'react';
+import PropTypes from 'prop-types';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+class PriceFilter extends React.Component {
+ static propTypes = {
+ column: PropTypes.object.isRequired,
+ onFilter: PropTypes.func.isRequired
+ }
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ this.getValue = this.getValue.bind(this);
+ this.onChange = this.onChange.bind(this);
+ this.state = { value: 2100 };
+ }
+ onChange(e) {
+ this.setState({ value: e.target.value });
+ }
+ getValue() {
+ return parseInt(this.range.value, 10);
+ }
+ filter() {
+ this.props.onFilter({
+ number: this.getValue(),
+ comparator: this.select.value
+ });
+ }
+ render() {
+ return [
+ this.range = node }
+ type="range"
+ min="2100"
+ max="2110"
+ onChange={ this.onChange }
+ />,
+
this.showValue = node }
+ style={ { textAlign: 'center' } }
+ >
+ { this.state.value }
+
,
+ ,
+
+ ];
+ }
+}
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: customFilter({
+ type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
+ }),
+ filterRenderer: (onFilter, column) =>
+
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
+
+class PriceFilter extends React.Component {
+ static propTypes = {
+ column: PropTypes.object.isRequired,
+ onFilter: PropTypes.func.isRequired
+ }
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ this.getValue = this.getValue.bind(this);
+ this.onChange = this.onChange.bind(this);
+ this.state = { value: 2100 };
+ }
+ onChange(e) {
+ this.setState({ value: e.target.value });
+ }
+ getValue() {
+ return parseInt(this.range.value, 10);
+ }
+ filter() {
+ this.props.onFilter({
+ number: this.getValue(),
+ comparator: this.select.value
+ });
+ }
+ render() {
+ return [
+ this.range = node }
+ type="range"
+ min="2100"
+ max="2110"
+ onChange={ this.onChange }
+ />,
+ this.showValue = node }
+ style={ { textAlign: 'center' } }
+ >
+ { this.state.value }
+
,
+ ,
+
+ ];
+ }
+}
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: customFilter({
+ type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
+ }),
+ filterRenderer: (onFilter, column) =>
+
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/examples/column-filter/custom-filter.js b/packages/react-bootstrap-table2-example/examples/column-filter/custom-filter.js
new file mode 100644
index 0000000..97fec6c
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-filter/custom-filter.js
@@ -0,0 +1,128 @@
+/* eslint no-return-assign: 0 */
+import React from 'react';
+import PropTypes from 'prop-types';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const products = productsGenerator(8);
+
+class PriceFilter extends React.Component {
+ static propTypes = {
+ column: PropTypes.object.isRequired,
+ onFilter: PropTypes.func.isRequired
+ }
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ this.getValue = this.getValue.bind(this);
+ }
+ getValue() {
+ return this.input.value;
+ }
+ filter() {
+ this.props.onFilter(this.getValue());
+ }
+ render() {
+ return [
+ this.input = node }
+ type="text"
+ placeholder="Input price"
+ />,
+
+ ];
+ }
+}
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: customFilter(),
+ filterRenderer: (onFilter, column) =>
+
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
+
+class PriceFilter extends React.Component {
+ static propTypes = {
+ column: PropTypes.object.isRequired,
+ onFilter: PropTypes.func.isRequired
+ }
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ this.getValue = this.getValue.bind(this);
+ }
+ getValue() {
+ return this.input.value;
+ }
+ filter() {
+ this.props.onFilter(this.getValue());
+ }
+ render() {
+ return [
+ this.input = node }
+ type="text"
+ placeholder="Input price"
+ />,
+
+ ];
+ }
+}
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ filter: customFilter(),
+ filterRenderer: (onFilter, column) =>
+
+}];
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 08eaf85..64c4909 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -55,6 +55,8 @@ import ProgrammaticallyTextFilter from 'examples/column-filter/programmatically-
import ProgrammaticallySelectFilter from 'examples/column-filter/programmatically-select-filter';
import ProgrammaticallyNumberFilter from 'examples/column-filter/programmatically-number-filter';
import ProgrammaticallyDateFilter from 'examples/column-filter/programmatically-date-filter';
+import CustomFilter from 'examples/column-filter/custom-filter';
+import AdvanceCustomFilter from 'examples/column-filter/advance-custom-filter';
// work on rows
import RowStyleTable from 'examples/rows/row-style';
@@ -186,7 +188,9 @@ storiesOf('Column Filter', module)
.add('Programmatically Text Filter', () => )
.add('Programmatically Select Filter', () => )
.add('Programmatically Number Filter', () => )
- .add('Programmatically Date Filter', () => );
+ .add('Programmatically Date Filter', () => )
+ .add('Custom Filter', () => )
+ .add('Advance Custom Filter', () => );
storiesOf('Work on Rows', module)
.add('Customize Row Style', () => )
diff --git a/packages/react-bootstrap-table2-filter/README.md b/packages/react-bootstrap-table2-filter/README.md
index dc9e621..0af54da 100644
--- a/packages/react-bootstrap-table2-filter/README.md
+++ b/packages/react-bootstrap-table2-filter/README.md
@@ -20,6 +20,7 @@ You can get all types of filters via import and these filters are a factory func
* SelectFilter
* NumberFilter
* DateFilter
+* CustomFilter
* **Coming soon!**
## Add CSS
@@ -189,4 +190,54 @@ const dateFilter = dateFilter({
})
// omit...
-```
\ No newline at end of file
+```
+
+## Custom Filter
+
+```js
+import filterFactory, { customFilter } from 'react-bootstrap-table2-filter';
+
+const columns = [..., {
+ dataField: 'date',
+ text: 'Product Name',
+ filter: customFilter(),
+ filterRenderer: (onFilter, column) => .....
+}];
+
+
+```
+
+In custom filter case, you are suppose to finish following two steps:
+1. Call `customFilter` and pass to `column.filter`
+2. Give `column.filterRenderer` as a callback function and return your custom filter element.
+
+### column.filterRenderer
+
+This function will pass two argument to you:
+1. `onFilter`: call it to trigger filter when you need.
+2. `column`: Just the column object!
+
+In the end, please remember to return your custom filter element!
+
+### customFilter
+
+`customFilter` function just same as `textFilter`, `selectFilter` etc, it is for customization reason. However, in the custom filter case, there's only one props is valid: `type`
+
+
+```js
+import filterFactory, { FILTER_TYPES } from 'react-bootstrap-table2-filter';
+
+const customFilter = customFilter({
+ type: FILTER_TYPES.NUMBER, // default is FILTER_TYPES.TEXT
+})
+```
+
+`type` is a way to ask `react-bootstrap-table` to filter you data as number, select, date or normal text.
+
+### FILTER_TYPES
+
+Following properties is valid in `FILTER_TYPES`:
+* TEXT
+* SELECT
+* NUMBER
+* DATE
\ 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 0f17bd3..fe60268 100644
--- a/packages/react-bootstrap-table2-filter/index.js
+++ b/packages/react-bootstrap-table2-filter/index.js
@@ -4,12 +4,15 @@ import NumberFilter from './src/components/number';
import DateFilter from './src/components/date';
import wrapperFactory from './src/wrapper';
import * as Comparison from './src/comparison';
+import { FILTER_TYPE } from './src/const';
export default (options = {}) => ({
wrapperFactory,
options
});
+export const FILTER_TYPES = FILTER_TYPE;
+
export const Comparator = Comparison;
export const textFilter = (props = {}) => ({
@@ -31,3 +34,7 @@ export const dateFilter = (props = {}) => ({
Filter: DateFilter,
props
});
+
+export const customFilter = (props = {}) => ({
+ props
+});
diff --git a/packages/react-bootstrap-table2-filter/src/components/date.js b/packages/react-bootstrap-table2-filter/src/components/date.js
index adff6c6..02468aa 100644
--- a/packages/react-bootstrap-table2-filter/src/components/date.js
+++ b/packages/react-bootstrap-table2-filter/src/components/date.js
@@ -1,4 +1,5 @@
/* eslint react/require-default-props: 0 */
+/* eslint jsx-a11y/no-static-element-interactions: 0 */
/* eslint no-return-assign: 0 */
/* eslint prefer-template: 0 */
import React, { Component } from 'react';
@@ -121,7 +122,11 @@ class DateFilter extends Component {
} = this.props;
return (
-
+
e.stopPropagation() }
+ className={ `filter date-filter ${className}` }
+ style={ style }
+ >