RadGrid for ASP.NET

Custom option for filtering (FilterListOptions -> VaryByDataTypeAllowCustom) Send comments on this topic.
Filtering > How to > Custom option for filtering (FilterListOptions -> VaryByDataTypeAllowCustom)

Glossary Item Box

The VaryByDateTypeAllowCustom option for the FilterListOptions enumeration of a grid column is especially designed to extend the built-in filtering feature of Telerik RadGrid (by giving the developer the freedom to trigger custom filtering action on filter command). A real-life example can visualize the power of this mechanism more clearly:

Let us assume that you have two integer columns in your grid and you would like to disable the 'Between' option for one of them but still want to allow "between" filtering for the second column. 
Because the filtering menu of Telerik RadGrid is presented by single object server-side (this way of implementation has been chosen to speed up the grid performance by merely creating one menu instance server side and cloning the instance for different columns), removing the 'Between' option from the menu will affect all grid columns and this filter will be stripped from each column filter menu options (if available by default for that type of column).

This is where the VaryByDataTypeAllowCustom FilterListOptions value comes into place. Enabling this type of filtering will automatically show 'Custom' filter menu option at the end of the respective column's filter menu. Moreover, choosing this filter will fire the ItemCommand event - thus you can intercept the filter action, cancel the default operation and execute "between" search for this particular column (honoring the pattern typed by the user in the filter box). Of course, you are not limited only to the known filter functions - as long as the filter value contains a valid filter expression (including column UniqueName, operators, etc.) the filter command can be executed successfully.

The forthcoming example shows the approach depicted in the last two paragraphs:

ASPX/ASCX Copy Code
<rad:RadGrid AutoGenerateColumns="false" ID="RadGrid1" DataSourceID="AccessDataSource1" Width="97%" EnableAJAX="True"
           
Skin= "Classic" AllowFilteringByColumn="True" AllowSorting="True" PageSize="15"
           
ShowFooter= "True" AllowPaging="True" runat="server" GridLines="None">
           
<MasterTableView
               
AutoGenerateColumns= "false"
               
EditMode= "InPlace"
               
AllowFilteringByColumn= "True"
               
ShowFooter= "True">
                 
<Columns>
                   
<rad:GridBoundColumn
                       
DataField= "ProductID"
                       
HeaderText= "ProductID"
                       
SortExpression= "ProductID"
                       
UniqueName= "ProductID" FilterListOptions="VaryByDataTypeAllowCustom">
                   
</rad:GridBoundColumn>
                   
<rad:GridBoundColumn
                       
DataField= "ProductName"
                       
HeaderText= "ProductName"
                       
SortExpression= "ProductName"
                       
UniqueName= "ProductName">
                   
</rad:GridBoundColumn>
                   
<rad:GridBoundColumn
                       
DataField= "SupplierID"
                       
HeaderText= "SupplierID"
                       
SortExpression= "SupplierID"
                       
UniqueName= "SupplierID">
                   
</rad:GridBoundColumn>
               
</Columns>
           
</MasterTableView>
       
</rad:RadGrid>
<
asp:AccessDataSource
ID="AccessDataSource1"
DataFile="~/Grid/Data/Access/Nwind.mdb"
SelectCommand="SELECT * FROM Products"
runat="server"></asp:AccessDataSource>
C# Copy Code
private void RadGrid1_PreRender(object sender, System.EventArgs e)
   {
       GridFilterMenu menu = RadGrid1.FilterMenu;
       
int i = 0;
       
while (i < menu.Items.Count)
       {
           
if (menu.Items[i].Text == "Between")
           {
               menu.Items.RemoveAt(i);
           }
           
else
           {
               
i = (i + 1);
           }
       }
   }
   
protected void RadGrid1_ItemCommand(object source, Telerik.WebControls.GridCommandEventArgs e)
   {
       
if (e.CommandName == RadGrid.FilterCommandName)
       {
           Pair filterPair = (Pair)e.CommandArgument;
           
if (filterPair.First.ToString() == "Custom")
           {
               e.Canceled = true;
               gridMessage1 =
"Filter function chosen: '" + filterPair.First + "' for column '" + filterPair.Second + "'";
               
string filterPattern = ((TextBox)(e.Item as GridFilteringItem)[filterPair.Second.ToString()].Controls[0]).Text;
               gridMessage2 =
"<br> Entered pattern for search: " + filterPattern;
               ((GridFilteringItem)e.Item).FireCommandEvent(
"Filter", new Pair("Between", filterPair.Second));
               gridMessage3 =
"<br/>Actual filter operation performed: 'Between' <br/> for range: " + filterPattern;
           }
       }
   }
   
private string gridMessage1 = null, gridMessage2 = null, gridMessage3 = null;
   
protected void RadGrid1_DataBound(object sender, EventArgs e)
   {
       
if (!string.IsNullOrEmpty(gridMessage1))
       {
           DisplayMessage(gridMessage1);
           DisplayMessage(gridMessage2);
           DisplayMessage(gridMessage3);
       }
   }
   
private void DisplayMessage(string text)
   {
       RadGrid1.Controls.Add(
new LiteralControl(string.Format("<span style='color:red'>{0}</span>", text)));
   }
VB .NET Copy Code
    Private Sub RadGrid1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadGrid1.PreRender
        Dim menu As GridFilterMenu = RadGrid1.FilterMenu
        Dim i As Integer = 0
        While i < menu.Items.Count
            If menu.Items(i).Text = "Between" Then
                menu.Items.RemoveAt(i)
            Else
                i = i + 1
            End If
        End While
    End Sub 'RadGrid1_PreRender
    Protected Sub RadGrid1_ItemCommand(ByVal source As Object, ByVal e As Telerik.WebControls.GridCommandEventArgs) Handles RadGrid1.ItemCommand
        If (e.CommandName = RadGrid.FilterCommandName) Then
            Dim filterPair As Pair = e.CommandArgument
            If filterPair.First = "Custom" Then
                e.Canceled = True
                gridMessage1 = "Filter function chosen: '" & filterPair.First & "' for column '" & filterPair.Second & "'"
                Dim filterPattern As String = CType(CType(e.Item, GridFilteringItem)(filterPair.Second).Controls(0), TextBox).Text
                gridMessage2 = "<br> Entered pattern for search: " & filterPattern
                CType(e.Item, GridFilteringItem).FireCommandEvent("Filter", New Pair("Between", filterPair.Second))
                gridMessage3 = "<br/>Actual filter operation performed: 'Between' <br/> for range: " & filterPattern
            End If
        End If
    End Sub
    Private gridMessage1 As String = Nothing, gridMessage2 As String = Nothing, gridMessage3 As String = Nothing
    Protected Sub RadGrid1_DataBound(ByVal sender As Object, ByVal e As EventArgs)
        If Not String.IsNullOrEmpty(gridMessage1) Then
            DisplayMessage(gridMessage1)
            DisplayMessage(gridMessage2)
            DisplayMessage(gridMessage3)
        End If
    End Sub
    Private Sub DisplayMessage(ByVal text As String)
        RadGrid1.Controls.Add(New LiteralControl(String.Format("<span style='color:red'>{0}</span>", text)))
    End Sub

Additional information about the FilterExpression structure is available in this topic.