diff --git a/packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js b/packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
new file mode 100644
index 0000000..e67541d
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
@@ -0,0 +1,94 @@
+/* eslint react/prop-types: 0 */
+import React from 'react';
+
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const { ToggleList } = ColumnToggle;
+const products = productsGenerator();
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ sort: true,
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ sort: true,
+ filter: textFilter()
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
+import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
+
+const { ToggleList } = ColumnToggle;
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name',
+ sort: true,
+ filter: textFilter()
+}, {
+ dataField: 'price',
+ text: 'Product Price',
+ sort: true,
+ filter: textFilter()
+}];
+
+
+ {
+ props => (
+
+
+
+
+
+ )
+ }
+
+`;
+
+export default () => (
+
+
Table will keep the filter/sort state when column toggle
+
+ {
+ props => (
+
+
+
+
+
+ )
+ }
+
+
{ sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 93ca8c4..6acd9b9 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -210,6 +210,7 @@ import BasicColumnToggle from 'examples/column-toggle';
import DefaultVisibility from 'examples/column-toggle/default-visibility';
import StylingColumnToggle from 'examples/column-toggle/styling-toggle-list';
import CustomToggleList from 'examples/column-toggle/custom-toggle-list';
+import ColumnToggleWithFilter from 'examples/column-toggle/column-toggle-with-filter';
// loading overlay
import EmptyTableOverlay from 'examples/loading-overlay/empty-table-overlay';
@@ -451,7 +452,8 @@ storiesOf('Column Toggle', module)
.add('Basic Column Toggle', () => )
.add('Default Visibility', () => )
.add('Styling Column Toggle', () => )
- .add('Custom Column Toggle', () => );
+ .add('Custom Column Toggle', () => )
+ .add('Column Toggle with Filter', () => );
storiesOf('Export CSV', module)
.addDecorator(bootstrapStyle())
diff --git a/packages/react-bootstrap-table2-filter/src/components/date.js b/packages/react-bootstrap-table2-filter/src/components/date.js
index 578f558..3d8ff45 100644
--- a/packages/react-bootstrap-table2-filter/src/components/date.js
+++ b/packages/react-bootstrap-table2-filter/src/components/date.js
@@ -83,14 +83,27 @@ class DateFilter extends Component {
return optionTags;
}
- getDefaultDate() {
- let defaultDate = '';
- const { defaultValue } = this.props;
- if (defaultValue && defaultValue.date) {
- // Set the appropriate format for the input type=date, i.e. "YYYY-MM-DD"
- defaultDate = dateParser(new Date(defaultValue.date));
+ getDefaultComparator() {
+ const { defaultValue, filterState } = this.props;
+ if (filterState && filterState.filterVal) {
+ return filterState.filterVal.comparator;
}
- return defaultDate;
+ if (defaultValue && defaultValue.comparator) {
+ return defaultValue.comparator;
+ }
+ return '';
+ }
+
+ getDefaultDate() {
+ // Set the appropriate format for the input type=date, i.e. "YYYY-MM-DD"
+ const { defaultValue, filterState } = this.props;
+ if (filterState && filterState.filterVal && filterState.filterVal.date) {
+ return dateParser(filterState.filterVal.date);
+ }
+ if (defaultValue && defaultValue.date) {
+ return dateParser(new Date(defaultValue.date));
+ }
+ return '';
}
applyFilter(value, comparator, isInitial) {
@@ -122,8 +135,7 @@ class DateFilter extends Component {
dateStyle,
className,
comparatorClassName,
- dateClassName,
- defaultValue
+ dateClassName
} = this.props;
return (
@@ -143,7 +155,7 @@ class DateFilter extends Component {
style={ comparatorStyle }
className={ `date-filter-comparator form-control ${comparatorClassName}` }
onChange={ this.onChangeComparator }
- defaultValue={ defaultValue ? defaultValue.comparator : '' }
+ defaultValue={ this.getDefaultComparator() }
>
{ this.getComparatorOptions() }
@@ -169,6 +181,7 @@ class DateFilter extends Component {
DateFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
+ filterState: PropTypes.object,
delay: PropTypes.number,
defaultValue: PropTypes.shape({
date: PropTypes.oneOfType([PropTypes.object]),
@@ -210,6 +223,7 @@ DateFilter.defaultProps = {
date: undefined,
comparator: ''
},
+ filterState: {},
withoutEmptyComparatorOption: false,
comparators: legalComparators,
placeholder: undefined,
diff --git a/packages/react-bootstrap-table2-filter/src/components/multiselect.js b/packages/react-bootstrap-table2-filter/src/components/multiselect.js
index ae8714e..1d8794c 100644
--- a/packages/react-bootstrap-table2-filter/src/components/multiselect.js
+++ b/packages/react-bootstrap-table2-filter/src/components/multiselect.js
@@ -69,6 +69,14 @@ class MultiSelectFilter extends Component {
}
}
+ getDefaultValue() {
+ const { filterState, defaultValue } = this.props;
+ if (filterState && typeof filterState.filterVal !== 'undefined') {
+ return filterState.filterVal;
+ }
+ return defaultValue;
+ }
+
getOptions() {
const optionTags = [];
const { options, placeholder, column, withoutEmptyOption } = this.props;
@@ -106,6 +114,7 @@ class MultiSelectFilter extends Component {
const {
style,
className,
+ filterState,
defaultValue,
onFilter,
column,
@@ -135,7 +144,7 @@ class MultiSelectFilter extends Component {
className={ selectClass }
onChange={ this.filter }
onClick={ e => e.stopPropagation() }
- defaultValue={ defaultValue !== undefined ? defaultValue : '' }
+ defaultValue={ this.getDefaultValue() }
>
{ this.getOptions() }
@@ -148,6 +157,7 @@ MultiSelectFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
options: PropTypes.object.isRequired,
+ filterState: PropTypes.object,
comparator: PropTypes.oneOf([LIKE, EQ]),
placeholder: PropTypes.string,
style: PropTypes.object,
@@ -160,6 +170,7 @@ MultiSelectFilter.propTypes = {
MultiSelectFilter.defaultProps = {
defaultValue: [],
+ filterState: {},
className: '',
withoutEmptyOption: false,
comparator: EQ,
diff --git a/packages/react-bootstrap-table2-filter/src/components/number.js b/packages/react-bootstrap-table2-filter/src/components/number.js
index 29e0370..7abea58 100644
--- a/packages/react-bootstrap-table2-filter/src/components/number.js
+++ b/packages/react-bootstrap-table2-filter/src/components/number.js
@@ -94,6 +94,28 @@ class NumberFilter extends Component {
onFilter(column, FILTER_TYPE.NUMBER)({ number: value, comparator });
}
+ getDefaultComparator() {
+ const { defaultValue, filterState } = this.props;
+ if (filterState && filterState.filterVal) {
+ return filterState.filterVal.comparator;
+ }
+ if (defaultValue && defaultValue.comparator) {
+ return defaultValue.comparator;
+ }
+ return '';
+ }
+
+ getDefaultValue() {
+ const { defaultValue, filterState } = this.props;
+ if (filterState && filterState.filterVal) {
+ return filterState.filterVal.number;
+ }
+ if (defaultValue && defaultValue.number) {
+ return defaultValue.number;
+ }
+ return '';
+ }
+
getComparatorOptions() {
const optionTags = [];
const { withoutEmptyComparatorOption } = this.props;
@@ -148,7 +170,6 @@ class NumberFilter extends Component {
render() {
const { isSelected } = this.state;
const {
- defaultValue,
column,
options,
style,
@@ -184,7 +205,7 @@ class NumberFilter extends Component {
id={ `number-filter-comparator-${column.text}` }
className={ `number-filter-comparator form-control ${comparatorClassName}` }
onChange={ this.onChangeComparator }
- defaultValue={ defaultValue ? defaultValue.comparator : '' }
+ defaultValue={ this.getDefaultComparator() }
>
{ this.getComparatorOptions() }
@@ -202,7 +223,7 @@ class NumberFilter extends Component {
style={ numberStyle }
className={ selectClass }
onChange={ this.onChangeNumberSet }
- defaultValue={ defaultValue ? defaultValue.number : '' }
+ defaultValue={ this.getDefaultValue() }
>
{ this.getNumberOptions() }
@@ -217,7 +238,7 @@ class NumberFilter extends Component {
className={ `number-filter-input form-control ${numberClassName}` }
placeholder={ placeholder || `Enter ${column.text}...` }
onChange={ this.onChangeNumber }
- defaultValue={ defaultValue ? defaultValue.number : '' }
+ defaultValue={ this.getDefaultValue() }
/>
}
@@ -229,6 +250,7 @@ class NumberFilter extends Component {
NumberFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
+ filterState: PropTypes.object,
options: PropTypes.arrayOf(PropTypes.number),
defaultValue: PropTypes.shape({
number: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -273,6 +295,7 @@ NumberFilter.defaultProps = {
number: undefined,
comparator: ''
},
+ filterState: {},
withoutEmptyComparatorOption: false,
withoutEmptyNumberOption: false,
comparators: legalComparators,
diff --git a/packages/react-bootstrap-table2-filter/src/components/select.js b/packages/react-bootstrap-table2-filter/src/components/select.js
index db5348a..7b83827 100644
--- a/packages/react-bootstrap-table2-filter/src/components/select.js
+++ b/packages/react-bootstrap-table2-filter/src/components/select.js
@@ -44,7 +44,7 @@ class SelectFilter extends Component {
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
- const isSelected = getOptionValue(props.options, props.defaultValue) !== undefined;
+ const isSelected = getOptionValue(props.options, this.getDefaultValue()) !== undefined;
this.state = { isSelected };
}
@@ -82,6 +82,14 @@ class SelectFilter extends Component {
}
}
+ getDefaultValue() {
+ const { filterState, defaultValue } = this.props;
+ if (filterState && typeof filterState.filterVal !== 'undefined') {
+ return filterState.filterVal;
+ }
+ return defaultValue;
+ }
+
getOptions() {
const optionTags = [];
const { options, placeholder, column, withoutEmptyOption } = this.props;
@@ -132,6 +140,7 @@ class SelectFilter extends Component {
withoutEmptyOption,
caseSensitive,
getFilter,
+ filterState,
...rest
} = this.props;
@@ -152,7 +161,7 @@ class SelectFilter extends Component {
className={ selectClass }
onChange={ this.filter }
onClick={ e => e.stopPropagation() }
- defaultValue={ defaultValue !== undefined ? defaultValue : '' }
+ defaultValue={ this.getDefaultValue() || '' }
>
{ this.getOptions() }
@@ -164,6 +173,7 @@ class SelectFilter extends Component {
SelectFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
+ filterState: PropTypes.object,
options: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
comparator: PropTypes.oneOf([LIKE, EQ]),
placeholder: PropTypes.string,
@@ -177,6 +187,7 @@ SelectFilter.propTypes = {
SelectFilter.defaultProps = {
defaultValue: '',
+ filterState: {},
className: '',
withoutEmptyOption: false,
comparator: EQ,
diff --git a/packages/react-bootstrap-table2-filter/src/components/text.js b/packages/react-bootstrap-table2-filter/src/components/text.js
index 1995ebe..a359a95 100644
--- a/packages/react-bootstrap-table2-filter/src/components/text.js
+++ b/packages/react-bootstrap-table2-filter/src/components/text.js
@@ -13,8 +13,14 @@ class TextFilter extends Component {
this.filter = this.filter.bind(this);
this.handleClick = this.handleClick.bind(this);
this.timeout = null;
+ function getDefaultValue() {
+ if (props.filterState && typeof props.filterState.filterVal !== 'undefined') {
+ return props.filterState.filterVal;
+ }
+ return props.defaultValue;
+ }
this.state = {
- value: props.defaultValue
+ value: getDefaultValue()
};
}
@@ -89,6 +95,7 @@ class TextFilter extends Component {
caseSensitive,
defaultValue,
getFilter,
+ filterState,
...rest
} = this.props;
@@ -119,6 +126,7 @@ class TextFilter extends Component {
TextFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
+ filterState: PropTypes.object,
comparator: PropTypes.oneOf([LIKE, EQ]),
defaultValue: PropTypes.string,
delay: PropTypes.number,
@@ -131,6 +139,7 @@ TextFilter.propTypes = {
TextFilter.defaultProps = {
delay: FILTER_DELAY,
+ filterState: {},
defaultValue: '',
caseSensitive: false
};
diff --git a/packages/react-bootstrap-table2-filter/src/context.js b/packages/react-bootstrap-table2-filter/src/context.js
index 058d7ff..013be6e 100644
--- a/packages/react-bootstrap-table2-filter/src/context.js
+++ b/packages/react-bootstrap-table2-filter/src/context.js
@@ -108,7 +108,8 @@ export default (
{ this.props.children }
diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js
index b2ac582..42d419e 100644
--- a/packages/react-bootstrap-table2/src/bootstrap-table.js
+++ b/packages/react-bootstrap-table2/src/bootstrap-table.js
@@ -91,6 +91,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
sortOrder={ this.props.sortOrder }
onSort={ this.props.onSort }
onFilter={ this.props.onFilter }
+ currFilters={ this.props.currFilters }
onExternalFilter={ this.props.onExternalFilter }
selectRow={ selectRow }
expandRow={ expandRow }
diff --git a/packages/react-bootstrap-table2/src/header-cell.js b/packages/react-bootstrap-table2/src/header-cell.js
index 3321507..18f69c0 100644
--- a/packages/react-bootstrap-table2/src/header-cell.js
+++ b/packages/react-bootstrap-table2/src/header-cell.js
@@ -18,6 +18,7 @@ const HeaderCell = (props) => {
sortOrder,
isLastSorting,
onFilter,
+ currFilters,
onExternalFilter
} = props;
@@ -99,7 +100,14 @@ const HeaderCell = (props) => {
const onCustomFilter = onExternalFilter(column, filter.props.type);
filterElm = filterRenderer(onCustomFilter, column);
} else if (filter) {
- filterElm = ;
+ filterElm = (
+
+ );
}
const children = headerFormatter ?
@@ -162,6 +170,7 @@ HeaderCell.propTypes = {
sortCaret: PropTypes.func,
isLastSorting: PropTypes.bool,
onFilter: PropTypes.func,
+ currFilters: PropTypes.object,
onExternalFilter: PropTypes.func
};
diff --git a/packages/react-bootstrap-table2/src/header.js b/packages/react-bootstrap-table2/src/header.js
index 77ee127..4360b2c 100644
--- a/packages/react-bootstrap-table2/src/header.js
+++ b/packages/react-bootstrap-table2/src/header.js
@@ -18,6 +18,7 @@ const Header = (props) => {
sortField,
sortOrder,
selectRow,
+ currFilters,
onExternalFilter,
expandRow
} = props;
@@ -50,6 +51,7 @@ const Header = (props) => {
onSort={ onSort }
sorting={ currSort }
onFilter={ onFilter }
+ currFilters={ currFilters }
onExternalFilter={ onExternalFilter }
sortOrder={ sortOrder }
isLastSorting={ isLastSorting }
@@ -89,6 +91,7 @@ Header.propTypes = {
sortField: PropTypes.string,
sortOrder: PropTypes.string,
selectRow: PropTypes.object,
+ currFilters: PropTypes.object,
onExternalFilter: PropTypes.func,
className: PropTypes.string,
expandRow: PropTypes.object