Here is my code for filtering a Kendo Grid using the Kendo Calendar control.
Important things to note:
-
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.
-
The grid must have .Filterable() option to allow filtering.
-
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 :-)