Telerik RadGrid: filter column on date range
Het filteren van een Telerik RadGrid is doodeenvoudig. Je zet de property AllowFilteringByColumn op true en dat is het eigenlijk. Nu is er een probleem als je niet wil filteren op tekst maar op datum en niet louter op 1 datum maar tussen bepaalde datums…
Daarom moeten we een eigen filter gaan maken; wat vrij eenvoudig is.
In plaats van
<telerik:GridBoundColumn HeaderText="Datum" UniqueName="Datum" DataField="EventDate" AutoPostBackOnFilter="true" />
moeten we nu gebruik maken van
<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
<FilterTemplate>
<telerik:RadDatePicker ID="dateFrom" runat="server" ClientEvents-OnDateSelected="FromDateSelected" SelectedDate='<%# fromDate %>' />
<telerik:RadDatePicker ID="dateTo" runat="server" ClientEvents-OnDateSelected="ToDateSelected" SelectedDate='<%# toDate %>' />
<telerik:RadScriptBlock ID="scriptFilterEventDate" runat="server">
<script type="text/javascript">
function FromDateSelected(sender, args) {
var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
var ToPicker = $find('<%# ((GridItem)Container).FindControl("dateTo").ClientID %>');
var fromDate = FormatSelectedDate(sender);
var toDate = FormatSelectedDate(ToPicker);
if (toDate != '') {
tableView.filter("EventDate", fromDate + " " + toDate, "Between");
}
}
function ToDateSelected(sender, args) {
var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
var FromPicker = $find('<%# ((GridItem)Container).FindControl("dateFrom").ClientID %>');
var fromDate = FormatSelectedDate(FromPicker);
var toDate = FormatSelectedDate(sender);
if (fromDate != '') {
tableView.filter("EventDate", fromDate + " " + toDate, "Between");
}
}
function FormatSelectedDate(picker) {
var date = picker.get_selectedDate();
var dateInput = picker.get_dateInput();
var formattedDate = dateInput.get_dateFormatInfo().FormatDate(date, dateInput.get_displayDateFormat());
return formattedDate;
}
</script>
</telerik:RadScriptBlock>
</FilterTemplate>
</telerik:GridBoundColumn>
Ok, het is een aardig stukje code meer maar als je het eens rustig bekijkt, is er eigenlijk niets aan.
Wat willen we nu juist doen?
Aangezien we gaan filteren tussen bepaalde datums, moeten we dus eerst en vooral de standaard tekstvelden gaan vervangen door twee kalenders.
Dit kunnen we eenvoudig doen door een <FilterTemplate></FilterTemplate> te gaan definïeren voor onze kolom en tussen deze tags onze twee kalenders te gaan plaatsen.
<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
<FilterTemplate>
<telerik:RadDatePicker ID="dateFrom" runat="server" />
<telerik:RadDatePicker ID="dateTo" runat="server" />
</FilterTemplate>
</telerik:GridBoundColumn>
Mooi zo! We hebben nu twee kalenders bovenaan onze kolom.

Nu moeten we nog de code voorzien om de grid te gaan filteren als we een datum hebben gekozen. We mogen pas dit event gaan uitvoeren als zowel de begin- als de einddatum is gekozen.
De events gaan we gaan uitvoeren via Javascript; daarom voegen we aan onze twee kalenders de methodes toe die worden uitgevoerd wanneer er een datum wordt geselecteerd.
<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
<FilterTemplate>
<telerik:RadDatePicker ID="dateFrom" ClientEvents-OnDateSelected="FromDateSelected" runat="server" />
<telerik:RadDatePicker ID="dateTo" ClientEvents-OnDateSelected="ToDateSelected" runat="server" />
</FilterTemplate>
</telerik:GridBoundColumn>
Goed, nu de Javascript-methodes zelf:
<telerik:RadScriptBlock ID="scriptFilterEventDate" runat="server">
<script type="text/javascript">
function FromDateSelected(sender, args) {
var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
var ToPicker = $find('<%# ((GridItem)Container).FindControl("dateTo").ClientID %>');
var fromDate = FormatSelectedDate(sender);
var toDate = FormatSelectedDate(ToPicker);
// filter alleen de tabel als we de andere datum al gekozen hebben
if (toDate != '') {
tableView.filter("EventDate", fromDate + " " + toDate, "Between");
}
}
function ToDateSelected(sender, args) {
var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
var FromPicker = $find('<%# ((GridItem)Container).FindControl("dateFrom").ClientID %>');
var fromDate = FormatSelectedDate(FromPicker);
var toDate = FormatSelectedDate(sender);
// filter alleen de tabel als we de andere datum al gekozen hebben
if (fromDate != '') {
tableView.filter("EventDate", fromDate + " " + toDate, "Between");
}
}
function FormatSelectedDate(picker) {
var date = picker.get_selectedDate();
var dateInput = picker.get_dateInput();
var formattedDate = dateInput.get_dateFormatInfo().FormatDate(date, dateInput.get_displayDateFormat()
return formattedDate;
}
</script>
</telerik:RadScriptBlock>
Voilà! We kunnen onze grid nu filteren en tot nu toe niet echt grote problemen. Maar je zal zien dat de gekozen datums niet worden bewaard tussen de postbacks…
En dit is de reden waarom ik eigenlijk deze blogpost ben begonnnen. Ik vond niet direct de methode om de waardes tussen de postbacks te gaan bewaren…
Het is de bedoeling om aan de kalenders volgende code toe te voegen:
SelectedDate='<%# fromDate %>'
Allemaal goed en wel maar vanwaar komt deze variabele nu?! Ik vond het niet direct terug in de documentatie tot ik bij de demo’s van Telerik kwam.
Blijkbaar moet je in je code-behind twee properties gaan declareren die de waarde gaan bewaren in de ASP.NET ViewState.
Rustig rustig! De code komt er zo aan:
protected DateTime? fromDate {
set {
ViewState["fromDate"] = value;
}
get {
if ( ViewState["fromDate"] != null ) {
return ( DateTime )ViewState["fromDate"];
}
return null;
}
}
protected DateTime? toDate {
set {
ViewState["toDate"] = value;
}
get {
if ( ViewState["toDate"] != null ) {
return ( DateTime )ViewState["toDate"];
}
return null;
}
}
Ziezo! Nu blijven je gekozen waardes bewaard tussen de postbacks en is onze filter volledig!