Kendo DateTime Filter Not Working In Grid

3.4k views Asked by At

I am using Kendo Grid in which I have added a column for displaying date and time and I have used kendo grid date filter for filtering datetime. But the problem I am facing is that I am not able to filter the datetime by selecting isequalto option from filter .

I tried to do this on my column, but it didn't work:

columns.Bound(o => o.Time).Title("Time").Format("{0:MM/dd/yyyy HH:mm:ss}").Filterable(f => f.UI("DateTimeFilter")).Width("5%");

And have applied below script :

    <script type="text/javascript">
function DateTimeFilter(control) 
{
$(control).kendoDateTimePicker();
}
</script>

The above code works when I select exact datetime from datetimepicker but it doesn't work when I select isequalto.

For eg : If I have this datetime "12/21/2013 07:15:45" displayed in my kendo grid column and when I copy this datetime to isequalto option under filter it does not gives any data.

I will be thankful if anybody could help me out in solving my issue. Thanks in advance.


I have attached a link for sample project to clarify my above problem clearly. In that I have added a datetime column in the grid but when I try to filter through the datetime shown in grid (ie. by copying it to the filter) it display empty grid after reloading.

You can find Sample Project Here

I have also attached a image below where I have added description of my problem. You can find link for image here Please help me out in solving my issue.

1

There are 1 answers

0
Balázs On

I know I am late with this answer, but it might still help someone.

I guess you are experiencing this because your server-side DateTime values contain fractional second data as well and the equals operator does not ignore them at comparison. I have found it easier to come up with a server-side solution instead of writing all sort of dirty JS workarounds.

The idea is that whenever you find a filter in the DataSourceRequest object that would filter on a DateTime property, you manually replace it with a CompositeFilterDescriptor, which truncates the value to the desired precision, sets it as the lower bound and then adds one unit of the desired precision (sec, min, hour, etc.) and sets it as the upper bound.

The code is the following:

public static class KendoHelpers
{
    public enum DateTimePrecision
    {
        Seconds = 1,
        Minutes = 2,
        Hours = 4
    }

    public static DataSourceRequest NormalizeDateFilters(this DataSourceRequest request, DateTimePrecision precision)
    {
        // TODO: Add parameter validation.

        for (int i = 0; i < request.Filters.Count; ++i)
        {
            FilterDescriptor filter = request.Filters[i] as FilterDescriptor;
            if (filter != null && filter.ConvertedValue is DateTime && filter.Operator == FilterOperator.IsEqualTo)
            {
                DateTime val = (DateTime)filter.ConvertedValue;

                CompositeFilterDescriptor newFilter = new CompositeFilterDescriptor
                {
                    LogicalOperator = FilterCompositionLogicalOperator.And
                };

                DateTime lowerBound;
                DateTime upperBound;

                if (precision == DateTimePrecision.Seconds)
                {
                    lowerBound = val.TruncateToWholeSeconds();
                    upperBound = lowerBound.AddSeconds(1);
                }
                else if (precision == DateTimePrecision.Minutes)
                {
                    lowerBound = val.TruncateToWholeMinutes();
                    upperBound = lowerBound.AddMinutes(1);
                }
                else if (precision == DateTimePrecision.Hours)
                {
                    lowerBound = val.TruncateToWholeHours();
                    upperBound = lowerBound.AddHours(1);
                }
                else
                {
                    // If someone would be stupid enough to supply Hours | Minutes
                    throw new ArgumentException("Not supported precision. Only Second, Minute, Hour values are supported.", "precision");
                }

                newFilter.FilterDescriptors.Add(new FilterDescriptor
                {
                    Member = filter.Member,
                    MemberType = filter.MemberType,
                    Operator = FilterOperator.IsGreaterThanOrEqualTo,
                    Value = lowerBound
                });

                newFilter.FilterDescriptors.Add(new FilterDescriptor
                {
                    Member = filter.Member,
                    MemberType = filter.MemberType,
                    Operator = FilterOperator.IsLessThan,
                    Value = upperBound
                });

                request.Filters[i] = newFilter;
            }
        }

        return request;
    }
}

Remarks:

  • The DateTime truncater extension is based on this answer.
  • This method will only do anything if the operator is equals, because if you select Is later than or the like, the default behavior will work just as well.
  • This method does not care about any present CompositeFilterDescriptors becasue an expression dateToSearch = 2016-11-21 11:22:00 AND dateToSearch = 2016-11-21 11:59:00 makes no sense anyway.
  • Similar thing could be done for DateTimeOffset values.