diff --git a/__tests__/demo/demo-components/index.js b/__tests__/demo/demo-components/index.js
index 82f45cb9..a0e5ced3 100644
--- a/__tests__/demo/demo-components/index.js
+++ b/__tests__/demo/demo-components/index.js
@@ -1,6 +1,13 @@
import React, { useState, useEffect, useRef } from 'react';
-import { Box, Input, InputAdornment } from '@mui/material';
+import {
+ Box,
+ Input,
+ InputAdornment,
+ TextField,
+ Select,
+ MenuItem
+} from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
// root of this project
@@ -1467,3 +1474,122 @@ export function LocalizationWithCustomComponents() {
/>
);
}
+
+function CustomFilterWithOperatorSelection({ columnDef, onFilterChanged }) {
+ const [operator, setOperator] = React.useState('=');
+ const [value, setValue] = React.useState(undefined);
+ const operatorRef = React.useRef(operator);
+ const valueRef = React.useRef(value);
+
+ React.useEffect(() => {
+ if (operatorRef.current !== operator || valueRef.current !== value) {
+ onFilterChanged(columnDef.tableData.id, value, operator);
+ operatorRef.current = operator;
+ valueRef.current = value;
+ }
+ }, [operator, value]);
+
+ return (
+
+
+ setValue(e.target.value)}
+ />
+
+ );
+}
+
+const columns_with_custom_filter = [
+ { title: 'Name', field: 'name', filtering: true },
+ {
+ title: 'Some Number',
+ field: 'some_number',
+ filtering: true,
+ filterComponent: ({ columnDef, onFilterChanged }) => (
+
+ )
+ }
+];
+
+const data_with_custom_filter = [
+ { name: 'Juan', some_number: 1 },
+ { name: 'John', some_number: 4 },
+ { name: 'Pedro', some_number: 8 },
+ { name: 'Mary', some_number: 12 },
+ { name: 'Oliver', some_number: 2 },
+ { name: 'Ignacio', some_number: 4 }
+];
+
+export function FilterWithOperatorSelection() {
+ return (
+
+ new Promise((resolve, _reject) => {
+ if (query.filters.length > 0) {
+ query.filters.forEach((filter) => {
+ if (
+ filter.value !== undefined &&
+ filter.value !== null &&
+ filter.value !== ''
+ ) {
+ switch (filter.operator) {
+ case '=':
+ resolve({
+ data: data_with_custom_filter.filter(
+ (row) => row[filter.column.field] == filter.value
+ ),
+ page: 1,
+ totalCount: data_with_custom_filter.length
+ });
+ break;
+ case '>':
+ resolve({
+ data: data_with_custom_filter.filter(
+ (row) => row[filter.column.field] > filter.value
+ ),
+ page: 1,
+ totalCount: data_with_custom_filter.length
+ });
+ break;
+ case '<':
+ resolve({
+ data: data_with_custom_filter.filter(
+ (row) => row[filter.column.field] < filter.value
+ ),
+ page: 1,
+ totalCount: data_with_custom_filter.length
+ });
+ break;
+ }
+ }
+ });
+ }
+ resolve({
+ data: data_with_custom_filter,
+ page: 1,
+ totalCount: data_with_custom_filter.length
+ });
+ })
+ }
+ columns={columns_with_custom_filter}
+ options={{
+ search: false,
+ filtering: true
+ }}
+ />
+ );
+}
diff --git a/__tests__/demo/demo.js b/__tests__/demo/demo.js
index f281eda8..8f8eb8d4 100644
--- a/__tests__/demo/demo.js
+++ b/__tests__/demo/demo.js
@@ -48,6 +48,7 @@ import {
TableWithSummary,
TableWithNumberOfPagesAround,
FixedColumnWithEdit,
+ FilterWithOperatorSelection,
TableMultiSorting,
LocalizationWithCustomComponents
} from './demo-components';
@@ -154,6 +155,8 @@ function Demo() {
Localization with Custom Components
+ Filter with operator selection
+
Remote Data Related
-
diff --git a/src/material-table.js b/src/material-table.js
index 784bcb9b..5a56cd7a 100644
--- a/src/material-table.js
+++ b/src/material-table.js
@@ -788,8 +788,9 @@ export default class MaterialTable extends React.Component {
}
}, this.props.options.debounceInterval);
- onFilterChange = (columnId, value) => {
+ onFilterChange = (columnId, value, operator = '=') => {
this.dataManager.changeFilterValue(columnId, value);
+ this.dataManager.changeFilterOperator(columnId, operator);
this.setState({}, this.onFilterChangeDebounce);
};
@@ -801,7 +802,7 @@ export default class MaterialTable extends React.Component {
.filter((a) => a.tableData.filterValue)
.map((a) => ({
column: a,
- operator: '=',
+ operator: a.tableData.filterOperator,
value: a.tableData.filterValue
}));
@@ -815,7 +816,7 @@ export default class MaterialTable extends React.Component {
.filter((a) => a.tableData.filterValue)
.map((a) => ({
column: a,
- operator: '=',
+ operator: a.tableData.filterOperator,
value: a.tableData.filterValue
}));
this.props.onFilterChange(appliedFilters);
diff --git a/src/utils/data-manager.js b/src/utils/data-manager.js
index 872c1708..63c0a2ca 100644
--- a/src/utils/data-manager.js
+++ b/src/utils/data-manager.js
@@ -273,6 +273,13 @@ export default class DataManager {
this.filtered = false;
}
+ changeFilterOperator(columnId, operator) {
+ const column = this.columns.find((c) => c.tableData.id === columnId);
+
+ column.tableData.filterOperator = operator;
+ this.filtered = false;
+ }
+
changeRowSelected(checked, path) {
const rowData = this.findDataByPath(this.sortedData, path);
rowData.tableData.checked = checked;