mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
Merge pull request #1053 from react-bootstrap-table/develop
20190810 release
This commit is contained in:
commit
47848e7f34
@ -140,7 +140,7 @@ const columns = [
|
||||
text: 'Job Type',
|
||||
editor: {
|
||||
type: Type.SELECT,
|
||||
getOptions: () => [.....]
|
||||
getOptions: (setOptions, { row, column }) => [.....]
|
||||
}
|
||||
}];
|
||||
|
||||
@ -152,7 +152,7 @@ const columns = [
|
||||
text: 'Job Type',
|
||||
editor: {
|
||||
type: Type.SELECT,
|
||||
getOptions: (setOptions) => {
|
||||
getOptions: (setOptions, { row, column }) => {
|
||||
setTimeout(() => setOptions([...]), 1500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,13 @@ class DropDownEditor extends Component {
|
||||
super(props);
|
||||
let options = props.options;
|
||||
if (props.getOptions) {
|
||||
options = props.getOptions(this.setOptions.bind(this)) || [];
|
||||
options = props.getOptions(
|
||||
this.setOptions.bind(this),
|
||||
{
|
||||
row: props.row,
|
||||
column: props.column
|
||||
}
|
||||
) || [];
|
||||
}
|
||||
this.state = { options };
|
||||
}
|
||||
@ -54,6 +60,8 @@ class DropDownEditor extends Component {
|
||||
}
|
||||
|
||||
DropDownEditor.propTypes = {
|
||||
row: PropTypes.object.isRequired,
|
||||
column: PropTypes.object.isRequired,
|
||||
defaultValue: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number
|
||||
|
||||
@ -201,7 +201,7 @@ export default (_, onStartEdit) =>
|
||||
if (_.isFunction(column.editorRenderer)) {
|
||||
editor = column.editorRenderer(editorProps, value, row, column, rowIndex, columnIndex);
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.SELECT) {
|
||||
editor = <DropdownEditor { ...editorProps } />;
|
||||
editor = <DropdownEditor { ...editorProps } row={ row } column={ column } />;
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
|
||||
editor = <TextAreaEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.CHECKBOX) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint no-console: 0 */
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
@ -25,22 +26,26 @@ const columns = [{
|
||||
text: 'Job Type1',
|
||||
editor: {
|
||||
type: Type.SELECT,
|
||||
getOptions: () => [{
|
||||
value: 'A',
|
||||
label: 'A'
|
||||
}, {
|
||||
value: 'B',
|
||||
label: 'B'
|
||||
}, {
|
||||
value: 'C',
|
||||
label: 'C'
|
||||
}, {
|
||||
value: 'D',
|
||||
label: 'D'
|
||||
}, {
|
||||
value: 'E',
|
||||
label: 'E'
|
||||
}]
|
||||
getOptions: (setOptions, { row, column }) => {
|
||||
console.log(`current editing row id: ${row.id}`);
|
||||
console.log(`current editing column: ${column.dataField}`);
|
||||
return [{
|
||||
value: 'A',
|
||||
label: 'A'
|
||||
}, {
|
||||
value: 'B',
|
||||
label: 'B'
|
||||
}, {
|
||||
value: 'C',
|
||||
label: 'C'
|
||||
}, {
|
||||
value: 'D',
|
||||
label: 'D'
|
||||
}, {
|
||||
value: 'E',
|
||||
label: 'E'
|
||||
}];
|
||||
}
|
||||
}
|
||||
}, {
|
||||
dataField: 'type2',
|
||||
@ -88,22 +93,26 @@ const columns = [{
|
||||
text: 'Job Type1',
|
||||
editor: {
|
||||
type: Type.SELECT,
|
||||
getOptions: () => [{
|
||||
value: 'A',
|
||||
label: 'A'
|
||||
}, {
|
||||
value: 'B',
|
||||
label: 'B'
|
||||
}, {
|
||||
value: 'C',
|
||||
label: 'C'
|
||||
}, {
|
||||
value: 'D',
|
||||
label: 'D'
|
||||
}, {
|
||||
value: 'E',
|
||||
label: 'E'
|
||||
}]
|
||||
getOptions: (setOptions, { row, column }) => {
|
||||
console.log(\`current editing row id: $\{row.id}\`);
|
||||
console.log(\`current editing column: $\{column.dataField}\`);
|
||||
return [{
|
||||
value: 'A',
|
||||
label: 'A'
|
||||
}, {
|
||||
value: 'B',
|
||||
label: 'B'
|
||||
}, {
|
||||
value: 'C',
|
||||
label: 'C'
|
||||
}, {
|
||||
value: 'D',
|
||||
label: 'D'
|
||||
}, {
|
||||
value: 'E',
|
||||
label: 'E'
|
||||
}];
|
||||
}
|
||||
}
|
||||
}, {
|
||||
dataField: 'type2',
|
||||
|
||||
@ -12,11 +12,11 @@ import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
class Table extends React.Component {
|
||||
filterByPrice = (filterVal) => {
|
||||
filterByPrice = (filterVal, data) => {
|
||||
if (filterVal) {
|
||||
return products.filter(product => product.price == filterVal);
|
||||
return data.filter(product => product.price == filterVal);
|
||||
}
|
||||
return products;
|
||||
return data;
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -50,11 +50,11 @@ class Table extends React.Component {
|
||||
`;
|
||||
|
||||
export default class Table extends React.Component {
|
||||
filterByPrice = (filterVal) => {
|
||||
filterByPrice = (filterVal, data) => {
|
||||
if (filterVal) {
|
||||
return products.filter(product => product.price == filterVal);
|
||||
return data.filter(product => product.price == filterVal);
|
||||
}
|
||||
return products;
|
||||
return data;
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -75,7 +75,7 @@ export default class Table extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Implement Custom Filter</h2>
|
||||
<h2>Implement a eq price filter</h2>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
|
||||
94
packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
vendored
Normal file
94
packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
vendored
Normal file
@ -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()
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Table will keep the filter/sort state when column toggle</h3>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@ -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';
|
||||
@ -443,7 +444,7 @@ storiesOf('Table Search', module)
|
||||
.add('Default Search Table', () => <DefaultSearch />)
|
||||
.add('Default Custom Search', () => <DefaultCustomSearch />)
|
||||
.add('Fully Custom Search', () => <FullyCustomSearch />)
|
||||
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
||||
.add('Search Formatted Value', () => <SearchFormattedData />)
|
||||
.add('Custom Search Value', () => <CustomSearchValue />);
|
||||
|
||||
storiesOf('Column Toggle', module)
|
||||
@ -451,7 +452,8 @@ storiesOf('Column Toggle', module)
|
||||
.add('Basic Column Toggle', () => <BasicColumnToggle />)
|
||||
.add('Default Visibility', () => <DefaultVisibility />)
|
||||
.add('Styling Column Toggle', () => <StylingColumnToggle />)
|
||||
.add('Custom Column Toggle', () => <CustomToggleList />);
|
||||
.add('Custom Column Toggle', () => <CustomToggleList />)
|
||||
.add('Column Toggle with Filter', () => <ColumnToggleWithFilter />);
|
||||
|
||||
storiesOf('Export CSV', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
|
||||
@ -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() }
|
||||
</select>
|
||||
@ -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,
|
||||
|
||||
@ -65,10 +65,18 @@ class MultiSelectFilter extends Component {
|
||||
needFilter = true;
|
||||
}
|
||||
if (needFilter) {
|
||||
this.applyFilter(this.selectInput.value);
|
||||
this.applyFilter(getSelections(this.selectInput));
|
||||
}
|
||||
}
|
||||
|
||||
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() }
|
||||
</select>
|
||||
@ -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,
|
||||
|
||||
@ -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() }
|
||||
</select>
|
||||
@ -202,7 +223,7 @@ class NumberFilter extends Component {
|
||||
style={ numberStyle }
|
||||
className={ selectClass }
|
||||
onChange={ this.onChangeNumberSet }
|
||||
defaultValue={ defaultValue ? defaultValue.number : '' }
|
||||
defaultValue={ this.getDefaultValue() }
|
||||
>
|
||||
{ this.getNumberOptions() }
|
||||
</select>
|
||||
@ -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() }
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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() }
|
||||
</select>
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ export default (
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// let nextData = nextProps.data;
|
||||
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.data)) {
|
||||
this.doFilter(nextProps, undefined, this.isEmitDataChange);
|
||||
this.doFilter(nextProps, this.isEmitDataChange);
|
||||
} else {
|
||||
this.data = nextProps.data;
|
||||
}
|
||||
@ -76,12 +76,7 @@ export default (
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let result;
|
||||
if (filter.props.onFilter) {
|
||||
result = filter.props.onFilter(filterVal);
|
||||
}
|
||||
this.doFilter(this.props, result);
|
||||
this.doFilter(this.props);
|
||||
};
|
||||
}
|
||||
|
||||
@ -95,11 +90,9 @@ export default (
|
||||
return this.data;
|
||||
}
|
||||
|
||||
doFilter(props, customResult, ignoreEmitDataChange = false) {
|
||||
let result = customResult;
|
||||
|
||||
doFilter(props, ignoreEmitDataChange = false) {
|
||||
const { dataChangeListener, data, columns } = props;
|
||||
result = result || filters(data, columns, _)(this.currFilters);
|
||||
const result = filters(data, columns, _)(this.currFilters);
|
||||
this.data = result;
|
||||
if (dataChangeListener && !ignoreEmitDataChange) {
|
||||
this.isEmitDataChange = true;
|
||||
@ -115,7 +108,8 @@ export default (
|
||||
<FilterContext.Provider value={ {
|
||||
data: this.data,
|
||||
onFilter: this.onFilter,
|
||||
onExternalFilter: this.onExternalFilter
|
||||
onExternalFilter: this.onExternalFilter,
|
||||
currFilters: this.currFilters
|
||||
} }
|
||||
>
|
||||
{ this.props.children }
|
||||
|
||||
@ -237,13 +237,21 @@ export const filters = (data, columns, _) => (currFilters) => {
|
||||
const filterObj = currFilters[dataField];
|
||||
filterFn = factory(filterObj.filterType);
|
||||
let filterValue;
|
||||
let customFilter;
|
||||
for (let i = 0; i < columns.length; i += 1) {
|
||||
if (columns[i].dataField === dataField) {
|
||||
filterValue = columns[i].filterValue;
|
||||
if (columns[i].filter) {
|
||||
customFilter = columns[i].filter.props.onFilter;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = filterFn(result, dataField, filterObj, filterValue);
|
||||
if (customFilter) {
|
||||
result = customFilter(filterObj.filterVal, result);
|
||||
} else {
|
||||
result = filterFn(result, dataField, filterObj, filterValue);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
@ -25,7 +25,7 @@ describe('Select Filter', () => {
|
||||
2: 'Unknown'
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
beforeEach(() => {
|
||||
onFilter.reset();
|
||||
onFilterFirstReturn.reset();
|
||||
|
||||
|
||||
@ -94,7 +94,8 @@ describe('FilterContext', () => {
|
||||
expect(mockBase).toHaveBeenCalledWith({
|
||||
data,
|
||||
onFilter: wrapper.instance().onFilter,
|
||||
onExternalFilter: wrapper.instance().onExternalFilter
|
||||
onExternalFilter: wrapper.instance().onExternalFilter,
|
||||
currFilters: wrapper.instance().currFilters
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -103,7 +104,6 @@ describe('FilterContext', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext(true));
|
||||
wrapper.render();
|
||||
wrapper.instance().currFilters = { price: { filterVal: 20, filterType: FILTER_TYPE.TEXT } };
|
||||
});
|
||||
|
||||
it('should pass original data without internal filtering', () => {
|
||||
@ -111,7 +111,8 @@ describe('FilterContext', () => {
|
||||
expect(mockBase).toHaveBeenCalledWith({
|
||||
data,
|
||||
onFilter: wrapper.instance().onFilter,
|
||||
onExternalFilter: wrapper.instance().onExternalFilter
|
||||
onExternalFilter: wrapper.instance().onExternalFilter,
|
||||
currFilters: wrapper.instance().currFilters
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -228,33 +229,7 @@ describe('FilterContext', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('if filter.props.onFilter is defined', () => {
|
||||
const filterVal = '3';
|
||||
const onFilter = jest.fn();
|
||||
const customColumns = columns.map((column, i) => {
|
||||
if (i === 1) {
|
||||
return {
|
||||
...column,
|
||||
filter: textFilter({ onFilter })
|
||||
};
|
||||
}
|
||||
return column;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext(false, customColumns));
|
||||
wrapper.render();
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
it('should call filter.props.onFilter correctly', () => {
|
||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(onFilter).toHaveBeenCalledTimes(1);
|
||||
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
||||
});
|
||||
});
|
||||
|
||||
describe('if filter.props.onFilter is defined and return an undefined data', () => {
|
||||
describe('if filter.props.onFilter is defined and return data', () => {
|
||||
const mockReturn = [{
|
||||
id: 1,
|
||||
name: 'A'
|
||||
@ -280,7 +255,7 @@ describe('FilterContext', () => {
|
||||
it('should call filter.props.onFilter correctly', () => {
|
||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(onFilter).toHaveBeenCalledTimes(1);
|
||||
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
||||
expect(onFilter).toHaveBeenCalledWith(filterVal, data);
|
||||
});
|
||||
|
||||
it('should set data correctly', () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
.react-bootstrap-table-page-btns-ul {
|
||||
float: right;
|
||||
margin-top: 0px;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
.react-bootstrap-table-pagination-list-hidden {
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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 = <filter.Filter { ...filter.props } onFilter={ onFilter } column={ column } />;
|
||||
filterElm = (
|
||||
<filter.Filter
|
||||
{ ...filter.props }
|
||||
filterState={ currFilters[column.dataField] }
|
||||
onFilter={ onFilter }
|
||||
column={ column }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const children = headerFormatter ?
|
||||
@ -162,6 +170,7 @@ HeaderCell.propTypes = {
|
||||
sortCaret: PropTypes.func,
|
||||
isLastSorting: PropTypes.bool,
|
||||
onFilter: PropTypes.func,
|
||||
currFilters: PropTypes.object,
|
||||
onExternalFilter: PropTypes.func
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Const from '../const';
|
||||
|
||||
export const typeConvert = (type, value) => {
|
||||
if (!type || type === Const.TYPE_STRING) {
|
||||
if (type === Const.TYPE_STRING) {
|
||||
return String(value);
|
||||
} else if (type === Const.TYPE_NUMBER) {
|
||||
return Number(value);
|
||||
|
||||
@ -728,7 +728,9 @@ describe('HeaderCell', () => {
|
||||
Filter
|
||||
}
|
||||
};
|
||||
wrapper = shallow(<HeaderCell column={ column } index={ index } onFilter={ onFilter } />);
|
||||
wrapper = shallow(
|
||||
<HeaderCell column={ column } index={ index } onFilter={ onFilter } currFilters={ {} } />
|
||||
);
|
||||
});
|
||||
|
||||
it('should render successfully', () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user