This is a migrated thread and some comments may be shown as answers.

DateTime value filters breaks

2 Answers 239 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Sune
Top achievements
Rank 1
Sune asked on 07 Jan 2016, 01:28 PM

I have been scratching my head for a while here, it seemed like a random bug at first but now I can reproduce it. 

It happens when I have more than one column filter and when there is a datetime filter on for instance the second filtered column. 

Say we have the following filter returned from dataSource.filter():

{
    "filters": [
        {
            "logic": "or",
            "filters": [
                {
                    "value": 3,
                    "operator": "eq",
                    "field": "powerState"
                }
            ]
        },
        {
            "logic": "and",
            "filters": [
                {
                    "field": "alarm1Created",
                    "operator": "gt",
                    "value": "2016-01-04T23:00:00.000Z"
                },
                {
                    "field": "alarm1Created",
                    "operator": "lt",
                    "value": "2016-01-28T23:00:00.000Z"
                }
            ]
        }
    ],
    "logic": "and"
}


The odata filter generated from this is:

&$filter=(powerState eq 3 and (alarm1Created gt 2016-01-05T01:00:00+00:00 and alarm1Created gt 2016-01-29T00:00:00+00:00))

Which is as expected.

Now load the filter back using:

dataSource.query({
                   filter: filter,
                   sort: sort,
                   group: group,
                   pageSize: pageSize,
                   page: page
               });

but now the odata url becomes

&$filter=(powerState eq 3 and (alarm1Created gt '2016-01-05T00:00:00.000Z' and alarm1Created lt '2016-01-29T00:00:00.000Z'))

which is of course incorrect. The alarm1Created datetimes are not parsed as datetimes but as strings!
This seems to happen only when the datetime is nested inside a parenthesis. Without the PowerState filters there is no problem with the datetimes.

2 Answers, 1 is accepted

Sort by
0
Accepted
Rosen
Telerik team
answered on 11 Jan 2016, 02:50 PM

Hello Sune,

I'm not sure I have completely understood your scenario. However, having the input you have pasted it is expected to have the request parameters serialize in the described way.

The values of the filter expression are not parse automatically - the developer is responsible to passing the correct value. This also means that the values should be of the correct type, in the case in question they should be a JavaScript date instances. If this is true the filter expression will be serialized into the first query string you have pasted. When the values are string they will be used as such and will be serialized into the second query string.

Having the above in mind, and if the filtering is initially producing the first query string, I guess you are doing something with the filter expression after that. For example serializing it to JSON (via JSON.stringify?) producing the filter expression you have pasted. The JSON.stringify will convert the date instances to their string representation and re-applying this filter descriptor to the DataSource will result in the second query string as the values are strings not dates. In order to correct this you will need to manually traverse the filter descriptors and convert the serialized dates into Date instances. Something similar to the following:

var filter = {
  "filters": [
    {
      "logic": "or",
      "filters": [
        {
          "value": 3,
          "operator": "eq",
          "field": "powerState"
        }
      ]
    },
    {
      "logic": "and",
      "filters": [
        {
          "field": "alarm1Created",
          "operator": "gt",
          "value": "2016-01-04T23:00:00.000Z"
        },
        {
          "field": "alarm1Created",
          "operator": "lt",
          "value": "2016-01-28T23:00:00.000Z"
        }
      ]
    }
  ],
  "logic": "and"
};
 
function flat(filters) {
  var result = [];
  for (var idx = 0; idx < filters.length; idx++) {
    if (filters[idx].filters) {
      result = result.concat(flat(filters[idx].filters));
    } else {
      result.push(filters[idx]);
    }             
  }
  return result;
}
 
$.each($.grep(flat(filter.filters), function(filter) {           
  return filter.field == "alarm1Created";
}), function(_, filter) {           
  filter.value = kendo.parseDate(filter.value);
});
 
dataSource.filter(filter);

Regards,
Rosen
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Sune
Top achievements
Rank 1
answered on 11 Jan 2016, 03:19 PM

Hi Rosen,

Thanks for the tip. I will try parsing them back to date objects, this is easy as I am already traversing the filter structure.

I guess I thought the data source was capable of parsing it since it knows the field is of type date from the schema configuration. A bit strange that it then works for simpler non-nested cases. Oh well.

 

Thanks

Sune

 

Tags
Grid
Asked by
Sune
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Sune
Top achievements
Rank 1
Share this question
or