filter date column with year

1 Answer 791 Views
DatePicker Grid
jan
Top achievements
Rank 1
Iron
jan asked on 13 Oct 2021, 11:03 AM

Hi,

I have a grid with a datasource, where I have a year field (date) and set it's value like this (this is just a sample data):


year: new Date(2021, 0, 1)


On this column I have this filtering:


<kendo-grid-column field="year" title="Év" format="yyyy">
      <ng-template kendoGridFilterCellTemplate let-filter let-column="column">
        <kendo-grid-date-filter-cell
          [showOperators]="false"
          [column]="column"
          [filter]="filter"
          activeView="decade"
          bottomView="decade"
          format="yyyy"
        >
        </kendo-grid-date-filter-cell>
      </ng-template>
    </kendo-grid-column>

As you see, the filter component is limited to year view/selection.  If I select in the filter 2021, I get no record:

But if I type the value in the editor, I get the right results:

How could I get this working with the filter selection too? Why is this behaviour?

 

Thanks.

 

1 Answer, 1 is accepted

Sort by
0
Hetali
Telerik team
answered on 14 Oct 2021, 09:51 PM | edited on 22 Oct 2021, 08:29 PM

Hi Jan,

By default, the DateFilterCellComponent sets the entire date as the filter value i.e. if you select the year 2020, it will set the filter value as Thu Oct 14 2020 00:00:00 GMT-0400 (Eastern Daylight Time) (Today's date) and the operator of the Date Filter Cell is greater than or equal to. Thereby, filtering the data with that or the future date. But when you type the year, it sets the filter value to 1st Jan of that year i.e. Wed Jan 01 2020 00:00:00 GMT-0500 (Eastern Standard Time).

To filter the data by the year selection, please add the following custom function in the dataSateChange or the filterChange event:

public dataStateChange(state: DataStateChangeEvent) {
  var filter = this.state.filter.filters;
  var len = filter.length;
  for (let i = 0; i < len; i++) {
    if (
      filter[i]['field'] === 'FirstOrderedOn' &&
      filter[i]['operator'] === 'gte'
    ) {
        // Get the selected year and change the value to 1st Jan of the selected year
        var year = filter[i]['value'].getFullYear();
        filter[i]['value'] = new Date(year, 0, 1);
        if (
          filter[i + 1] &&
          filter[i + 1]['field'] === 'FirstOrderedOn' &&
          filter[i + 1]['operator'] === 'lte'
        ) {
          // Replace the value to 31st Dec of the selected year if the previous filter exists
          filter[i + 1]['value'] = new Date(year, 11, 31);
        } else {
          // Add a new filter for 31st Dec of the selected year if it does not already exist
          filter.push({
            field: 'FirstOrderedOn',
            operator: 'lte',
            value: new Date(year, 11, 31),
          });
        }
      }
    }
}

 

In this StackBlitz example, the Kendo UI Grid date column filters data by the year selection.

Please let me know if this helps or if you have any further questions.

Regards,
Hetali
Progress Telerik

Remote troubleshooting is now easier with Telerik Fiddler Jam. Get the full context to end-users' issues in just three steps! Start your trial here - https://www.telerik.com/fiddler-jam.
jan
Top achievements
Rank 1
Iron
commented on 15 Oct 2021, 05:47 AM | edited

Hi,

thanks for the detailed answer. I had a similar approach in my mind, but couldn't set it up.

While I see, that this works in the provided stackblitz example, I have some errors in my project. I assume, this is due to the strict type checking option, which I would like to keep.

I get errors on this lines:

filter['field']

filter['value']

The error message says: Element implicitly has an 'any' type because expression of type '"field"'

can't be used to index type 'CompositeFilterDescriptor | FilterDescriptor'

Property 'field' does not exist on type 'CompositeFilterDescriptor | FilterDescriptor'

The same is for value too.

The second issue is, that this code in the template causes an error too:


[filter]="state.filter"

It says: Type 'CompositeFilterDescriptor | undefined' is not assignable to type 'CompositeFilterDescriptor'.

Type 'undefined' is not assignable to type 'CompositeFilterDescriptor'.

 

How can I get rid of this errors?

Hetali
Telerik team
commented on 18 Oct 2021, 10:14 PM

Hi Jan,

The first error is not related to the strict template. The value needs to be casted to the respective type that is certain to have the given field i.e. FilterDescriptor has the properties 'value' and 'field' in this case and CompositeFilterDescriptor does not. While the 'filters' property can be any of the two types i.e. CompositeFilterDescriptor or FilterDescriptor, it cannot be safely accessed.

By making the following changes, the field and value error will be resolved:

public dataStateChange(state: DataStateChangeEvent): void {
  this.state.filter.filters.forEach((filter) => {
    if ((filter as FilterDescriptor)['field'] === 'FirstOrderedOn') {
       var year = (filter as FilterDescriptor).value.getFullYear();
      (filter as FilterDescriptor)['value'] = new Date(year, 0, 1);
    }
  });
}


As for the error pertaining to the state.filter, the Grid filter expects to be bound to CompositeFilterDescriptor and when a value is not provided (undefined) this no longer meets the expected type. The workaround is to ensure there is always some default value (initial filter descriptor) or disable the strict null check as seen below:

public state: State = {
// Initial filter descriptor
  filter: {
    logic: 'and',
    filters: [{ field: 'ProductName', value: 'Chai', operator: 'contains' }],
  },
}

OR

<kendo-grid
  [filter]="state.filter!"
>
</kendo-grid>

I hope this helps. Let me know if you have any further questions pertaining to this case.

Regards,
Hetali
Progress Telerik

jan
Top achievements
Rank 1
Iron
commented on 20 Oct 2021, 08:52 AM | edited

Hi,

thanks for your help, the error messages are gone now. But I noticed another strange issue, which you can test in the provided stackblitz example too. Please filter f.e. for the year 2020 (whether via keyboard input or via filter selector), the filtered datas are shown, after that filter for 2021 and you get no records. What could be the issue here?

EDIT: this is due to the fact, that the second filtering is happening on the already filtered data. Is this the default behaviour? I mean, if I change the filter value, the original data source should be filtered and not the before filtered one, shouldn't?

Hetali
Telerik team
commented on 22 Oct 2021, 08:33 PM

Hi Jan,

The strange behavior is due to the filter manually added using the push method but never cleared from the filters array on filter change.

I have updated the answer and added an if condition and replaced forEach method with the for loop. Give it a try and let me know if that helps.

Please note that this is a custom approach and it is not fully tested and/or supported by us.

Regards,
Hetali
Progress Telerik

 

Tags
DatePicker Grid
Asked by
jan
Top achievements
Rank 1
Iron
Answers by
Hetali
Telerik team
Share this question
or