Kendo UI MVC Grid with Custom Calendar Filter

Here is my code for filtering a Kendo Grid using the Kendo Calendar control.

Important things to note:

  1. The read method needs to accept a DataSourceRequest object. This will allow the filters you apply to the grid in JavaScript to be performed on the data you retrieve on the server side.

  2. The grid must have .Filterable() option to allow filtering.

  3. I use Moment.js to convert the date that extracted from the Kendo Calendar into a format that the controller accepts.

If you know a better way please leave a comment, I’d love to hear about it :-)

Controller

public class TripController : Controller
{
    public ActionResult Index()
    {
        var today = DateTime.Now.Date;
        return View(new TripListViewModel() { Trips = GetTrips().Where(t => t.DepartureDate == today).ToList() });
    }
    private IQueryable<TripViewModel> GetTrips()
    {
        return db.Trips.Select(t => new TripViewModel()
        {
            ID = t.ID,
            Name = t.Name,
            DepartureDate = (DateTime) t.DepartureDateTime
        });
    }
    public ActionResult GetTrips([DataSourceRequest] DataSourceRequest request)
    {
        return Json(GetTrips().ToDataSourceResult(request));
    }
}

View

@model TripListViewModel
@{
ViewBag.Title = "Index";
}

@section scripts {
<script src="@Url.Content("/Scripts/json2.js")"></script>
<script src="@Url.Content("/Scripts/moment.min.js")"></script>
}

@using (Html.BeginForm()) {
<div class="workspace">
<div class="side-nav side-nav-main">
<div class="side-nav-padding">
<h2>Trip Listing</h2>

@Html.Kendo().Calendar().Name("tripDate").Depth( CalendarView.Month).Events(e=>e.Change("filterGridByDate"))
</div>
</div>
<div class="main">
<div class="main-padding">
@(Html.Kendo().Grid(Model.Trips)
.Name("TripGrid")
.Columns(columns =>
{
columns.Bound(e => e.Name);
columns.Bound(e => e.DepartureDate).Format("{0:d-MMM-yyyy}");
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("GetTrips", "Trip"))
)
.Filterable()
)
</div>
</div>
</div>
}
<script>

function filterGridByDate() {
$("#txtFirstName").val(JSON.stringify(moment($("#tripDate").data("kendoCalendar").value())));

filter = new Array();
dateToFilter = moment($("#tripDate").data("kendoCalendar").value()).toJSON();
if (dateToFilter) {
filter.push({ field: "DepartureDate", operator: "eq", value: dateToFilter });
}

var grid = $("#TripGrid").data("kendoGrid");
grid.dataSource.filter(filter);
}

</script>

Do you agree with this solution? Do you know a better way? Please feel free to leave a comment and help us all in our quest for perfect code :-)

comments powered by Disqus