Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Accept date objects in filter items #6564

Closed
2 tasks done
konrazem opened this issue Oct 19, 2022 · 8 comments · Fixed by #7069
Closed
2 tasks done

[DataGrid] Accept date objects in filter items #6564

konrazem opened this issue Oct 19, 2022 · 8 comments · Fixed by #7069
Assignees
Labels
breaking change component: data grid This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature feature: Filtering Related to the data grid Filtering feature v7.x

Comments

@konrazem
Copy link

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

When I want to set or initialize date GridFilterItem with filter operator like onOrAfter I got

TypeError: filterItem.value.match is not a function

It is because in gridDateOperators.js:10 filterItem.value is suppose to be string type:

const [year, month, day, hour, minute] = filterItem.value.match(showTime ? dateTimeRegex : dateRegex).slice(1).map(Number);

My value for this column is a Date type as this is date operator not a string oprator.

Expected behavior 🤔

Table should filter date like data base on dedicated date filter operators.

Steps to reproduce 🕹

https://codesandbox.io/s/mystifying-tdd-j0wvc6?file=/demo.tsx

Context 🔦

No response

Your environment 🌎

npx @mui/envinfo
  Don't forget to mention which browser you used.
  Output from `npx @mui/envinfo` goes here.

Order ID 💳 (optional)

46820

@konrazem konrazem added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 19, 2022
@konrazem konrazem changed the title Initialize or set date filters casue "TypeError: filterItem.value.match is not a function" Initialize or set date filters cause "TypeError: filterItem.value.match is not a function" Oct 19, 2022
@konrazem konrazem changed the title Initialize or set date filters cause "TypeError: filterItem.value.match is not a function" [Data Grid] Initialize or set date filters cause "TypeError: filterItem.value.match is not a function" Oct 19, 2022
@zannager zannager added the component: data grid This is the name of the generic UI component, not the React module! label Oct 20, 2022
@cherniavskii cherniavskii added feature: Filtering Related to the data grid Filtering feature enhancement This is not a bug, nor a new feature and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 21, 2022
@cherniavskii
Copy link
Member

Hey @konrazem
Thanks for raising this!

I think we can rework date and datetime filter operators to always operate with Date object and move conversion to the input component.
Here's how it would look like:

diff --git a/packages/grid/x-data-grid/src/colDef/gridDateOperators.ts b/packages/grid/x-data-grid/src/colDef/gridDateOperators.ts
index a7c7c6185..e5ccd3710 100644
--- a/packages/grid/x-data-grid/src/colDef/gridDateOperators.ts
+++ b/packages/grid/x-data-grid/src/colDef/gridDateOperators.ts
@@ -3,9 +3,6 @@ import { GridFilterItem } from '../models/gridFilterItem';
 import { GridFilterOperator } from '../models/gridFilterOperator';
 import { GridCellParams } from '../models/params/gridCellParams';
 
-const dateRegex = /(\d+)-(\d+)-(\d+)/;
-const dateTimeRegex = /(\d+)-(\d+)-(\d+)T(\d+):(\d+)/;
-
 function buildApplyFilterFn(
   filterItem: GridFilterItem,
   compareFn: (value1: number, value2: number) => boolean,
@@ -16,12 +13,9 @@ function buildApplyFilterFn(
     return null;
   }
 
-  const [year, month, day, hour, minute] = filterItem.value
-    .match(showTime ? dateTimeRegex : dateRegex)!
-    .slice(1)
-    .map(Number);
-
-  const time = new Date(year, month - 1, day, hour || 0, minute || 0).getTime();
+  const date = new Date(filterItem.value);
+  date.setHours(0, 0, 0, 0);
+  const time = date.getTime();
 
   return ({ value }: GridCellParams<string | number | Date, any, any>): boolean => {
     if (!value) {
diff --git a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx
index 685b738af..bbb38b55c 100644
--- a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx
+++ b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx
@@ -21,14 +21,12 @@ function GridFilterInputDate(props: GridFilterInputDateProps) {
 
   const onFilterChange = React.useCallback(
     (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
-      const value = event.target.value;
-
       clearTimeout(filterTimeout.current);
-      setFilterValueState(String(value));
+      setFilterValueState(event.target.value);
 
       setIsApplying(true);
       filterTimeout.current = setTimeout(() => {
-        applyValue({ ...item, value });
+        applyValue({ ...item, value: event.target.valueAsDate });
         setIsApplying(false);
       }, SUBMIT_FILTER_DATE_STROKE_TIME);
     },
@@ -43,7 +41,11 @@ function GridFilterInputDate(props: GridFilterInputDateProps) {
 
   React.useEffect(() => {
     const itemValue = item.value ?? '';
-    setFilterValueState(String(itemValue));
+    let value = '';
+    if (itemValue instanceof Date) {
+      value = itemValue.toISOString().substring(0, 10);
+    }
+    setFilterValueState(value);
   }, [item.value]);
 
   return (

There's also additional benefit for @mui/x-date-pickers integration, since we can reuse default getGridDateOperators:

diff --git a/docs/data/data-grid/recipes-editing/EditingWithDatePickers.tsx b/docs/data/data-grid/recipes-editing/EditingWithDatePickers.tsx
index 3d796c2f1..8cb2272bf 100644
--- a/docs/data/data-grid/recipes-editing/EditingWithDatePickers.tsx
+++ b/docs/data/data-grid/recipes-editing/EditingWithDatePickers.tsx
@@ -11,6 +11,7 @@ import {
   GridCellParams,
   GridColTypeDef,
   GridFilterInputValueProps,
+  getGridDateOperators,
 } from '@mui/x-data-grid';
 import {
   randomCreatedDate,
@@ -167,7 +168,11 @@ const dateColumnType: GridColTypeDef<Date | string, string> = {
   renderEditCell: (params) => {
     return <GridEditDateCell {...params} />;
   },
-  filterOperators: getDateFilterOperators(),
+  filterOperators: getGridDateOperators(false).map((item) => ({
+    ...item,
+    InputComponent: GridFilterDateInput,
+    InputComponentProps: { showTime: false },
+  })),
   valueFormatter: (params) => {
     if (typeof params.value === 'string') {
       return params.value;

@cherniavskii cherniavskii moved this to 🆕 Needs refinement in MUI X Data Grid Oct 21, 2022
@konrazem
Copy link
Author

konrazem commented Nov 2, 2022

It is quite important issue for us. I am not sure if you want me to work on it or should wait?

@cherniavskii
Copy link
Member

I am not sure if you want me to work on it or should wait?

@konrazem I've added this issue to our backlog.
The code diffs I left above are just a quick PoC I've done to validate the idea.

As a workaround, you can use a string representation of the date instead:

{
  columnField: "dateCreated",
  operatorValue: "onOrAfter",
  value: "2022-01-01"
}

Demo: https://codesandbox.io/s/naughty-yonath-wfx1np?file=/demo.tsx:692-841

@cherniavskii cherniavskii changed the title [Data Grid] Initialize or set date filters cause "TypeError: filterItem.value.match is not a function" [DataGrid] Accept date objects in filter items Nov 25, 2022
@cherniavskii cherniavskii self-assigned this Dec 2, 2022
@konrazem
Copy link
Author

Thank you very much @cherniavskii for taking care of this. In fact my problem is that I have built custom filter panel where I use GridApiContext to set new filter model current.setFilterModel(vals, 'upsertFilterItems');. When I set filter values like:

{
    "items": [
        {
            "id": "a89b173c-a08d-4c63-9c0e-3c8da7754026",
            "columnField": "startDate",
            "value":  HERE DATE TYPE,
            "operatorValue": "onOrAfter"
        },
        {
            "id": "82550ef0-6065-4eb4-8211-d0097ee0a53e",
            "columnField": "startDate",
            "value":  HERE DATE TYPE,
            "operatorValue": "onOrBefore"
        }
    ],
    "linkOperator": "and",
    "quickFilterValues": [],
    "quickFilterLogicOperator": "and"
}

I got this error "An unhandled error was caught from submitForm() TypeError: filterItem.value.match is not a function". If I convert items values to strings it seems to be working well so thank you very much!
I will be waiting for this fix to avoid extra parsing filters.

@joserodolfofreitas joserodolfofreitas moved this from 🆕 Needs refinement to 🏗 In progress in MUI X Data Grid Dec 15, 2022
@konrazem
Copy link
Author

konrazem commented Jan 3, 2023

I think it would resolve also such issues? #6764

@cherniavskii cherniavskii moved this from 🏗 In progress to 🔖 Ready in MUI X Data Grid Apr 6, 2023
@conorstew
Copy link

So the solution is still to convert date objects to string?

@konrazem
Copy link
Author

So the solution is still to convert date objects to string?

I think i MUX-X 6.4.0 it is no longer required. https://mui.com/x/migration/migration-data-grid-v5/#columns

@konrazem
Copy link
Author

@conorstew I am sorry, it looks like still you need to convert to string ISO 8601 format.

 const [year, month, day, hour, minute] = filterItem.value
    .match(showTime ? dateTimeRegex : dateRegex)! // <-- EXPECTS VALUE TO BE STRING
    .slice(1)
    .map(Number);

Source:
https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/src/colDef/gridDateOperators.ts#L20

I am reopennig

@cherniavskii cherniavskii moved this from 🆕 Needs refinement to ✅ Done in MUI X Data Grid Jan 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change component: data grid This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature feature: Filtering Related to the data grid Filtering feature v7.x
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants