Telerik blogs
DotNetT2 Light_1200x303

Have you ever wondered how to replace the GridDateTimeColumn’s built-in filter component with a custom control of your choice?

As rare it sounds, there may be cases when you would want to do that.

Here is one example that uses a RadComboBox to Filter on a GridDateTimeColumn showing only records later than or equal to today’s date.

FilterGridDateTimeColumn_opt - OrderDate dropdown has options for View All or Current Term, changing the grid display results

If you would like to see the complete implementation of this scenario, check out the Knowledge Base: Apply filter on a GridDateTimeColumn using RadComboBox article.

Or you can keep reading the blog to find out more.

Probably you have tried to add a Combo to the GridDateTimeColumn’s Filter Template and it didn't work. Worry not! In this blog, I will give you a short summary of what is happening and how you can overcome it.

RadComboBox to the Rescue!

As you might already know, RadGrid offers the possibility to replace the built-in components with custom Controls by exposing the “FilterTemplate” element for its columns. You can find instructions in the Filter Template Documentation article.

However, the Filter Template was designed mainly for the GridBoundColumn and GridTemplateColumn. These columns do not render a dedicated Filter Component based on the Column’s Data Type.

On the other hand, Data Type–specific columns such as the GridDateTimeColumn, or GridNumericColumn render a dedicated filter component that is compatible with the given data. For example, the GridDateTimeColumn renders a RadDatePicker component to handle DateTime values, while the GridNumericColumn renders a RadNumericTextBox to handle Numeric values.

Let’s just say you wanted to use GridDateTimeColumn with a RadComboBox in its Filter Template. You will still need to use a Data Type–specific Control in it (see FilterTemplate for Data Specific Columns). But that is not an issue—you can add a hidden DatePicker which will be found by the Grid’s logic, and it won’t be visible to users.

For example, add the FilterTemplate element to the GridDateTimeColumn. After that, add a RadDatePicker and a RadComboBox. You can hide the RadDatePicker by setting its Visible property to “False.”

<telerik:GridDateTimeColumn DataField="OrderDate" DataType="System.DateTime"
DataFormatString="{0:MM/dd/yyyy}" EnableTimeIndependentFiltering="true"
FilterControlAltText="Filter OrderDate column" HeaderText="OrderDate (mm/dd/yyyy)"
SortExpression="OrderDate" UniqueName="OrderDate" FilterControlWidth="160px">
<FilterTemplate>
<telerik:RadDatePicker ID="RadDatePicker1" runat="server" Visible="false">
</telerik:RadDatePicker>
<telerik:RadComboBox ID="RadComboBox1" runat="server">
<Items>
<telerik:RadComboBoxItem Text="View All" />
<telerik:RadComboBoxItem Text="Current Term" />
</Items>
</telerik:RadComboBox>
</FilterTemplate>
</telerik:GridDateTimeColumn>

The Column will now have a ComboBox as Filter component.

dateColumn

Next, you can attach the OnClientSelectedIndexChanged client-side event to the RadComboBox and disable the AutoPostBack to prevent this control from making PostBacks.

<telerik:RadComboBox ID="RadComboBox1" runat="server" OnClientSelectedIndexChanged="OnClientSelectedIndexChanged"AutoPostBack="false">
<Items>
<telerik:RadComboBoxItem Text="View All" />
<telerik:RadComboBoxItem Text="Current Term" />
</Items>
</telerik:RadComboBox>

In the OnClientSelectedIndexChanged event handler, you will have JavaScript code that will call the filter() client-side function of the Grid similar to how it is shown in the Filter Template documentation article. This will make the Grid fire the Filter Command.

function OnClientSelectedIndexChanged(sender, args) {
// Get reference to the Grid's TableView Object
var tableView = $find('<%# ((GridItem)Container).OwnerTableView.ClientID %>');
// Get the Combo's selected value
var selectedValue = args.get_item().get_value();
// Condition to check if the Value exists
if (!selectedValue) {
// If false, apply the "NoFilter" with Empty values
tableView.filter('OrderDate', "", "NoFilter");
} else {
// If true, appl a Filter Function with the Selected Value
tableView.filter('OrderDate', selectedValue, "GreaterThanOrEqualTo");
}
}

Although there are Items in the ComboBox, those do not have values. This example uses the backend to assign values dynamically. This way, you can assign any date from the past, present or the future automatically.

To do that, you can use the DataBinding event of the RadComboBox.

<telerik:RadComboBox ID="RadComboBox1" runat="server" AutoPostBack="false" OnDataBinding="RadComboBox1_DataBinding"
OnClientSelectedIndexChanged="OnClientSelectedIndexChanged">
<Items>
<telerik:RadComboBoxItem Text="View All" />
<telerik:RadComboBoxItem Text="Current Term" />
</Items>
</telerik:RadComboBox>

When the event fires, you can assign the current “Today” Date dynamically like so:

protected void RadComboBox1_DataBinding(object sender, EventArgs e)
{
var combo = (sender as RadComboBox);
// Find the ComboBoxItem by "Current Term" text and set it's Value to Today's Date
combo.FindItemByText("Current Term").Value = DateTime.Now.Date.ToShortDateString();
}

At this point, the filtering will work—however, the selected item in the Combo will not reflect that. To keep the item selected after the filtering, you will need to bind the SelectedValue property to the value coming from the Column’s Filter Value.

<telerik:RadComboBox ID="RadComboBox1" runat="server" AutoPostBack="false" EmptyMessage="Select a date"
OnDataBinding="RadComboBox1_DataBinding"
OnClientSelectedIndexChanged="OnClientSelectedIndexChanged"
SelectedValue='<%# ((GridItem)Container).OwnerTableView.GetColumn("OrderDate").CurrentFilterValue %>'>
<Items>
<telerik:RadComboBoxItem Text="View All" />
<telerik:RadComboBoxItem Text="Current Term" />
</Items>
</telerik:RadComboBox>

That is it!

The GridDateTimeColumn now has a RadComboBox as Filter component and you can use the Combo’s Selected Values to filter on it.

Complete Code

<telerik:GridDateTimeColumn DataField="OrderDate" DataType="System.DateTime"
DataFormatString="{0:MM/dd/yyyy}" EnableTimeIndependentFiltering="true"
FilterControlAltText="Filter OrderDate column" HeaderText="OrderDate (mm/dd/yyyy)"
SortExpression="OrderDate" UniqueName="OrderDate" FilterControlWidth="160px">
<FilterTemplate>
<telerik:RadDatePicker ID="RadDatePicker1" runat="server" Visible="false">
</telerik:RadDatePicker>
<telerik:RadComboBox ID="RadComboBox1" runat="server" AutoPostBack="false"
EmptyMessage="Select a date"
OnDataBinding="RadComboBox1_DataBinding"
OnClientSelectedIndexChanged="OnClientSelectedIndexChanged"
SelectedValue='<%# ((GridItem)Container).OwnerTableView.GetColumn("OrderDate").CurrentFilterValue %>'>
<Items>
<telerik:RadComboBoxItem Text="View All" />
<telerik:RadComboBoxItem Text="Current Term" />
</Items>
</telerik:RadComboBox>
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script>
function OnClientSelectedIndexChanged(sender, args) {
// Get reference to the Grid's TableView Object
var tableView = $find('<%# ((GridItem)Container).OwnerTableView.ClientID %>');
// Get the Combo's selected value
var selectedValue = args.get_item().get_value();
// Condition to check if the Value exists
if (!selectedValue) {
// If false, apply the "NoFilter" with Empty values
tableView.filter("OrderDate", "", "NoFilter");
} else {
// If true, appl a Filter Function with the Selected Value
tableView.filter("OrderDate", selectedValue, "GreaterThanOrEqualTo");
}
}
</script>
</telerik:RadScriptBlock>
</FilterTemplate>
</telerik:GridDateTimeColumn>

Code-Behind Code

C#
protected void RadComboBox1_DataBinding(object sender, EventArgs e)
{
var combo = (sender as RadComboBox);
// Find the ComboBoxItem by "Current Term" text and set it's Value to Today's Date
combo.FindItemByText("Current Term").Value = DateTime.Now.Date.ToShortDateString();
}

VB
Protected Sub RadComboBox1_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
Dim combo = (TryCast(sender, RadComboBox))
combo.FindItemByText("Current Term").Value = DateTime.Now.Date.ToShortDateString()
End Sub

The following code snippet is responsible for applying different background color to the cells. (OPTIONAL.)

C#
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
var dataItem = (e.Item as GridDataItem);
// If it's a GridDataItem
if (dataItem != null)
{
// Access the Cell
var dateCell = dataItem["OrderDate"];
if (DateTime.ParseExact(dateCell.Text, "MM/dd/yyyy", CultureInfo.GetCultureInfo("en-US")) < DateTime.Now.Date)
{
dateCell.BackColor = System.Drawing.Color.Yellow;
}
else
{
dateCell.BackColor = System.Drawing.Color.LimeGreen;
}
}
}

VB
Protected Sub RadGrid1_ItemDataBound(ByVal sender As Object, ByVal e As GridItemEventArgs)
Dim dataItem = (TryCast(e.Item, GridDataItem))
If dataItem IsNot Nothing Then
Dim dateCell = dataItem("OrderDate")
If DateTime.ParseExact(dateCell.Text, "MM/dd/yyyy", CultureInfo.GetCultureInfo("en-US")) < DateTime.Now.Date Then
dateCell.BackColor = System.Drawing.Color.Yellow
Else
dateCell.BackColor = System.Drawing.Color.LimeGreen
End If
End If
End Sub

Related Articles


Attila Antal
About the Author

Attila Antal

Attila is a Senior Technical Support Engineer at Progress working with the Telerik AJAX, MVC and Kendo UI components. Prior to Progress, he worked as a Technical Trainer. Driven by his passion for technologies, he has experience with multiple scripting languages, but his main focus is on web development. In his free time he loves to hike, travel and do sport activities.

Related Posts

Comments

Comments are disabled in preview mode.