Reputation: 4063
I have a column in Telerik MVC Grid which is of type DateTime. I want to only use the Date part of it for display and filtering. As a result, I used the following code
@(Html.Telerik().Grid<State>()
.Name("tlkStateGrid")
.Columns(col => {
col.Bound(m => m.CreatedOn).Title("Created On").Format("{0:dd/MM/yyyy}");
The Grid does display the Date (CreatedOn) in the format specified. However, the filtering doesn't work as expected. I think that while filtering, the time values are considered too by the Grid. So if two dates are same but having different time values, they are not considered 'equal'. How do I configure grid to neglect the time values and compare only dates, when filtering.
Note: I have posted similar question in Telerik MVC forums but no answer as yet.
Upvotes: 2
Views: 3862
Reputation: 9830
I've created the following code which changes the way a date-filter is defined:
/// <summary>
/// Maps DateTime related filters.
/// * IsEqualTo filter is converted to ('x-date' is GreaterThanOrEqualTo 'SearchDate') AND ('x-date' is LessThan 'SearchDate' + 1 Day)
/// * IsNotEqualTo filter is converted to ('x-date' LessThan 'SearchDate') OR ('x-date' is GreaterThan 'SearchDate' + 1 Day) OR ('x-date' is NULL)
/// * IsLessThanOrEqualTo filter is converted to ('x-date' is LessThan 'SearchDate' + 1 Day)
/// </summary>
/// <param name="copyOfOriginalFilters">A copy from the filters.</param>
/// <param name="newFilters">The new filters</param>
protected void MapDateFilter(ReadOnlyCollection<IFilterDescriptor> copyOfOriginalFilters, IList<IFilterDescriptor> newFilters)
{
newFilters.Clear();
foreach (var currentFilter in copyOfOriginalFilters)
{
Type t = currentFilter.GetType();
if (t == typeof(FilterDescriptor))
{
var filter = currentFilter as FilterDescriptor;
if (filter.ConvertedValue.GetType() == typeof(DateTime))
{
DateTime datePart = ((DateTime)filter.ConvertedValue).Date;
if (filter.Operator == FilterOperator.IsEqualTo)
{
var compositeFilter = new CompositeFilterDescriptor();
compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsGreaterThanOrEqualTo, datePart));
compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart.AddDays(1)));
compositeFilter.LogicalOperator = FilterCompositionLogicalOperator.And;
newFilters.Add(compositeFilter);
}
else if (filter.Operator == FilterOperator.IsNotEqualTo)
{
var compositeFilter = new CompositeFilterDescriptor();
compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart));
compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsGreaterThan, datePart.AddDays(1)));
compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsEqualTo, null));
compositeFilter.LogicalOperator = FilterCompositionLogicalOperator.Or;
newFilters.Add(compositeFilter);
}
else if (filter.Operator == FilterOperator.IsLessThanOrEqualTo)
{
newFilters.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart.AddDays(1)));
}
else
{
newFilters.Add(filter);
}
}
else
{
newFilters.Add(filter);
}
}
else if (t == typeof(CompositeFilterDescriptor))
{
var filter = currentFilter as CompositeFilterDescriptor;
int numberOfDateFilters = filter.FilterDescriptors.Where(fd =>
fd is FilterDescriptor &&
(fd as FilterDescriptor).ConvertedValue != null &&
(fd as FilterDescriptor).ConvertedValue.GetType() == typeof(DateTime))
.Count();
if (numberOfDateFilters == 2)
{
var firstFilter = filter.FilterDescriptors[0] as FilterDescriptor;
firstFilter.Value = ((DateTime)firstFilter.ConvertedValue).Date;
var secondFilter = filter.FilterDescriptors[1] as FilterDescriptor;
secondFilter.Value = ((DateTime)secondFilter.ConvertedValue).Date;
}
else
{
MapDateFilter(new List<IFilterDescriptor>(filter.FilterDescriptors).AsReadOnly(), filter.FilterDescriptors);
}
newFilters.Add(filter);
}
}
}
This can be used like:
protected void MapGridCommand(GridCommand command)
{
this.MapDateFilter(new List<IFilterDescriptor>(command.FilterDescriptors).AsReadOnly(), command.FilterDescriptors);
}
Upvotes: 1
Reputation: 17680
You could modify lambda expression to explicitly modify the CreatedOn property to be just a date. You'll get just the date component of the datetime object.
col.Bound(m => m.CreatedOn.Date)
You new code will now be as below.
@(Html.Telerik().Grid<State>()
.Name("tlkStateGrid")
.Columns(col => {
col.Bound(m => m.CreatedOn.Date).Title("Created On").Format({0:dd/MM/yyyy}");
if CreatedOn is a nullable datetime you'll need to access its Value property before getting the Date component. See below.
col.Bound(m => m.CreatedOn.HasValue? m.CreatedOn.Value.Date : m.CreatedOn)
Upvotes: 2