Skip to content

Commit

Permalink
[DataGrid] Fix filter not working after deleting the value (#3018)
Browse files Browse the repository at this point in the history
  • Loading branch information
m4theushw authored Nov 9, 2021
1 parent e480822 commit 3d532fb
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,6 @@ function GridFilterInputValue(props: GridTypeFilterInputValueProps & TextFieldPr
clearTimeout(filterTimeout.current);
setFilterValueState(String(value));

if (type !== 'singleSelect' && value === '') {
setIsApplying(false);
return;
}

setIsApplying(true);
// TODO singleSelect doesn't debounce
filterTimeout.current = setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const GRID_NUMERIC_COL_DEF: GridColTypeDef = {
align: 'right',
headerAlign: 'right',
sortComparator: gridNumberComparer,
valueParser: (value) => Number(value),
valueParser: (value) => (value === '' ? null : Number(value)),
valueFormatter: ({ value }) => (value && isNumber(value) && value.toLocaleString()) || value,
filterOperators: getGridNumericColumnOperators(),
};
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,32 @@ describe('<DataGridPro /> - Filter', () => {
expect(getColumnValues()).to.deep.equal([]);
});

it('should call onFilterModelChange when the value is emptied', () => {
const onFilterModelChange = spy();
render(
<TestCase
onFilterModelChange={onFilterModelChange}
filterModel={{
items: [
{
id: 1,
columnField: 'brand',
value: 'a',
operatorValue: 'contains',
},
],
}}
initialState={{
preferencePanel: { openedPanelValue: GridPreferencePanelsValue.filters, open: true },
}}
/>,
);
expect(onFilterModelChange.callCount).to.equal(0);
fireEvent.change(screen.queryByRole('textbox', { name: 'Value' }), { target: { value: '' } });
clock.tick(500);
expect(onFilterModelChange.callCount).to.equal(1);
});

it('should only select visible rows', () => {
const newModel: GridFilterModel = {
items: [
Expand Down
147 changes: 89 additions & 58 deletions packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import * as React from 'react';
import { createRenderer, fireEvent, screen, getByText } from '@material-ui/monorepo/test/utils';
import { expect } from 'chai';
import {
DataGrid,
GridToolbar,
GridPreferencePanelsValue,
GridInitialState,
DataGridProps,
} from '@mui/x-data-grid';
import { useFakeTimers } from 'sinon';
import { DataGrid, GridToolbar, GridPreferencePanelsValue, DataGridProps } from '@mui/x-data-grid';
import { getColumnValues } from 'test/utils/helperFn';

const isJSDOM = /jsdom/.test(window.navigator.userAgent);

describe('<DataGrid /> - Filter', () => {
let clock;

beforeEach(() => {
clock = useFakeTimers();
});

afterEach(() => {
clock.restore();
});

const { render } = createRenderer();

const baselineProps = {
Expand Down Expand Up @@ -60,15 +65,14 @@ describe('<DataGrid /> - Filter', () => {
],
};

const TestCase = (props: {
rows?: any[];
columns?: any[];
operatorValue?: string;
value?: any;
field?: string;
initialState?: GridInitialState;
columnTypes?: any;
}) => {
const TestCase = (
props: {
columns?: any[];
operatorValue?: string;
value?: any;
field?: string;
} & Partial<Omit<DataGridProps, 'columns'>>,
) => {
const { operatorValue, value, rows, columns, field = 'brand', ...other } = props;
return (
<div style={{ width: 300, height: 300 }}>
Expand All @@ -86,6 +90,12 @@ describe('<DataGrid /> - Filter', () => {
],
}}
disableColumnFilter={false}
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
{...other}
/>
</div>
Expand Down Expand Up @@ -303,6 +313,42 @@ describe('<DataGrid /> - Filter', () => {
});
});

['contains', 'startsWith', 'equals', 'endsWith'].forEach((operatorValue) => {
it(`should show all rows when the value is '' and operator='${operatorValue}'`, () => {
render(
<TestCase
filterModel={undefined}
columns={[{ field: 'brand' }]}
rows={[
{
id: 3,
brand: 'Asics',
},
{
id: 4,
brand: 'RedBull',
},
{
id: 5,
brand: 'Hugo',
},
]}
/>,
);
expect(getColumnValues()).to.deep.equal(['Asics', 'RedBull', 'Hugo']);
fireEvent.change(screen.getByRole('combobox', { name: 'Operators' }), {
target: { value: operatorValue },
});
const input = screen.getByRole('textbox', { name: 'Value' });
fireEvent.change(input, { target: { value: 'abc' } });
clock.tick(500);
expect(getColumnValues()).to.deep.equal([]);
fireEvent.change(input, { target: { value: '' } });
clock.tick(500);
expect(getColumnValues()).to.deep.equal(['Asics', 'RedBull', 'Hugo']);
});
});

describe('RegExp', () => {
['contains', 'startsWith', 'endsWith'].forEach((operatorValue) => {
it('should escape RegExp characters if applied as filter values', () => {
Expand Down Expand Up @@ -441,6 +487,31 @@ describe('<DataGrid /> - Filter', () => {
);
expect(getColumnValues(0)).to.deep.equal(['0', '2']);
});

it('should show all rows when the value is empty', () => {
render(
<TestCase
filterModel={undefined}
columns={[
{ field: 'brand', type: 'number', valueFormatter: ({ value }) => String(value) },
]}
rows={[
{ id: 2, brand: 0 },
{ id: 3, brand: 1984 },
{ id: 4, brand: 1954 },
{ id: 5, brand: 1974 },
]}
/>,
);
expect(getColumnValues()).to.deep.equal(['0', '1984', '1954', '1974']);
const input = screen.getByRole('spinbutton', { name: 'Value' });
fireEvent.change(input, { target: { value: 999999 } });
clock.tick(500);
expect(getColumnValues()).to.deep.equal([]);
fireEvent.change(input, { target: { value: '' } });
clock.tick(500);
expect(getColumnValues()).to.deep.equal(['0', '1984', '1954', '1974']);
});
});

describe('date operators', () => {
Expand Down Expand Up @@ -851,12 +922,6 @@ describe('<DataGrid /> - Filter', () => {
]}
field="voltage"
operatorValue="is"
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);
expect(getColumnValues()).to.deep.equal(['Hair Dryer', 'Dishwasher', 'Microwave']);
Expand All @@ -882,12 +947,6 @@ describe('<DataGrid /> - Filter', () => {
]}
field="voltage"
operatorValue="is"
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);
expect(getColumnValues()).to.deep.equal(['Hair Dryer', 'Dishwasher', 'Microwave']);
Expand All @@ -906,12 +965,6 @@ describe('<DataGrid /> - Filter', () => {
columns={[{ field: 'name' }, { field: 'voltage', type: 'singleSelect' }]}
field="voltage"
operatorValue="is"
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);
expect(getColumnValues()).to.deep.equal(['Hair Dryer', 'Dishwasher', 'Microwave']);
Expand Down Expand Up @@ -966,18 +1019,7 @@ describe('<DataGrid /> - Filter', () => {
});

it('should work with numeric values', () => {
const { setProps } = render(
<TestCase
field="status"
operatorValue="is"
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);
const { setProps } = render(<TestCase field="status" operatorValue="is" />);
expect(getColumnValues()).to.deep.equal(['Nike', 'Adidas', 'Puma']);
setProps({ value: 2 });
expect(getColumnValues()).to.deep.equal(['Puma']);
Expand Down Expand Up @@ -1100,18 +1142,7 @@ describe('<DataGrid /> - Filter', () => {

describe('Filter preference panel', () => {
it('should show an empty string as the default filter input value', () => {
render(
<TestCase
field="brand"
operatorValue="contains"
initialState={{
preferencePanel: {
open: true,
openedPanelValue: GridPreferencePanelsValue.filters,
},
}}
/>,
);
render(<TestCase field="brand" operatorValue="contains" />);
expect(screen.getByRole('textbox', { name: 'Value' }).value).to.equal('');
});
});
Expand Down

0 comments on commit 3d532fb

Please sign in to comment.