Google-like Filtering
It allows displaying the available options while the user types in a RadComboBox in RadGrid filtering item. Filtering is confirmed when item is selected or Enter is pressed.
Here is the list of actions needed to achieve this:
-
Extend the default GridBoundColumn to remove the default textbox and embed RadComboBox inside the filtering cell.
-
Configure the options for RadComboBox control as per your requirements (the essential parts are to set ShowToggleImage = false, ID for the combobox, EnableLoadOnDemand=true, MarkFirstMatch = true and attach the ItemsRequested/SelectedIndexChanged events). These operation should take place in the overridden SetupFilterControls(TableCell cell) method.
-
Override the SetCurrentFilterValueToControl(TableCell cell) / GetCurrentFilterValueFromControl(TableCell cell) methods to set/get the user input.
-
Filter the combobox items in the ItemsRequested handler depending on the UniqueName of the currently filtered column.
-
Raise command event for the GridFilteringItem calling its FireCommandEvent(commandName, new Pair(filterFunctionName, columnUniqueName)) method.
This example is expanded by enabling the AJAXmechanism of the grid along with its built-in paging and sorting features. The filtering action will be triggered when you choose item from a look-up textbox or type inside filtering input and press Enter from the keyboard.
In addition, there is Clear filter button on the page which restores the initial grid content.
Note: In this case search is performed for matches in the default grid source on each filter command. That is why each column's CurrentFilterFunction is set to *GridKnownFunction.NoFilter *and CurrentFilterValue to String.Empty on filter operation.
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadGrid1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
<telerik:AjaxSetting AjaxControlID="clrFilters">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
<telerik:AjaxUpdatedControl ControlID="clrFilters" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" AutoGenerateColumns="false" AllowPaging="true" AllowSorting="true"
AllowFilteringByColumn="true" Width="560px" Skin="Office2007" runat="server"
OnColumnCreating="RadGrid1_ColumnCreating" OnItemCommand="RadGrid1_ItemCommand"
OnNeedDataSource="RadGrid1_NeedDataSource">
<PagerStyle Mode="NumericPages" />
</telerik:RadGrid>
<br />
<asp:Button ID="clrFilters" runat="server" Text="Clear filters" CssClass="button"
OnClick="clrFilters_Click">
</asp:Button>
public class MyCustomFilteringColumnCS : GridBoundColumn
{
public static string ConnectionString
{
get { return ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString; }
}
//RadGrid will call this method when it initializes the controls inside the filtering item cells
protected override void SetupFilterControls(TableCell cell)
{
base.SetupFilterControls(cell);
cell.Controls.RemoveAt(0);
RadComboBox combo = new RadComboBox();
combo.ID = ("RadComboBox1" + this.UniqueName);
combo.ShowToggleImage = false;
combo.Skin = "Office2007";
combo.EnableLoadOnDemand = true;
combo.AutoPostBack = true;
combo.MarkFirstMatch = true;
combo.Height = Unit.Pixel(100);
combo.ItemsRequested += this.list_ItemsRequested;
combo.SelectedIndexChanged += this.list_SelectedIndexChanged;
cell.Controls.AddAt(0, combo);
cell.Controls.RemoveAt(1);
}
//RadGrid will cal this method when the value should be set to the filtering input control(s)
protected override void SetCurrentFilterValueToControl(TableCell cell)
{
base.SetCurrentFilterValueToControl(cell);
RadComboBox combo = (RadComboBox)cell.Controls[0];
if ((this.CurrentFilterValue != string.Empty))
{
combo.Text = this.CurrentFilterValue;
}
}
//RadGrid will cal this method when the filtering value should be extracted from the filtering input control(s)
protected override string GetCurrentFilterValueFromControl(TableCell cell)
{
RadComboBox combo = (RadComboBox)cell.Controls[0];
return combo.Text;
}
private void list_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
{
((RadComboBox)o).DataTextField = this.DataField;
((RadComboBox)o).DataValueField = this.DataField;
((RadComboBox)o).DataSource = GetDataTable("SELECT DISTINCT " + this.UniqueName + " FROM Customers WHERE " + this.UniqueName + " LIKE '" + e.Text + "%'");
((RadComboBox)o).DataBind();
}
private void list_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
{
GridFilteringItem filterItem = (GridFilteringItem)((RadComboBox)o).NamingContainer;
if ((this.UniqueName == "Index"))
{
//this is filtering for integer column type
filterItem.FireCommandEvent("Filter", new Pair("EqualTo", this.UniqueName));
}
//filtering for string column type
filterItem.FireCommandEvent("Filter", new Pair("Contains", this.UniqueName));
}
public static DataTable GetDataTable(string query)
{
SqlConnection conn = new SqlConnection(ConnectionString);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(query, conn);
DataTable myDataTable = new DataTable();
conn.Open();
try
{
adapter.Fill(myDataTable);
}
finally
{
conn.Close();
}
return myDataTable;
}
}