This is a migrated thread and some comments may be shown as answers.

Filtering using GridTemplateColumn

10 Answers 635 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Nathan
Top achievements
Rank 2
Nathan asked on 01 Feb 2012, 12:15 AM
Hello,

I'm building up a grid by dynamically adding Template Columns. The reason I'm using "GridTemplateColumn" is due to the structure of the datasource. The bound object must be used to determine the cell value during data binding. I set the Template Column to a implementation of ITemplate, this class contains the databinding event which determines the cell value.

An example would be the "MyTemplate" class in this example:
http://www.telerik.com/help/aspnet-ajax/grid-programmatic-creation.html 

Since I'm setting up all my columns this way, I'm wondering if I will have issues with filtering. I tried setting the "GridTempalteColumn" data type to "DateTime", hoping to get the calendar picker, but it only filtered the filter options. Is it possible to setup my template column with "DateTime" filtering which contains the calendar picker?

I also have a scenario where we would like to have a multi-select dropdown as a filter control. Do you know if this is possible? I've seen examples that use a regular dropdown list, but I haven't noticed anything that allows multiple selections.

Thanks!

10 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 01 Feb 2012, 05:01 AM
Hello,

Take a look into the following documentation for DateTime filtering.
Filtering for DateTime Bound Column with DataFormatString Different from mm/dd/yyyy

This Code Library explains how to use Multi-Selection RadComboBox for filtering grid

Thanks,
Princy.
0
Nathan
Top achievements
Rank 2
answered on 01 Feb 2012, 05:54 PM
This is a great example, exactly what I was looking for. Thanks!!

Do you see any problems with using GridTemplateColumn for all of my columns? I think this is the only option since I must determine the cell value during runtime. Agree? However, I could build up a data table during runtime that I could then bind to the grid, but I'm not sure this would be a better approach.
0
Nathan
Top achievements
Rank 2
answered on 01 Feb 2012, 09:54 PM
Hello,

The example is exactly what I need to implement, however, it needs to be generated dynamically. 

I already set the ItemTemplate to a class that inherits ITemplate. Should I create a new class and perform the same approach for "FilterTemplate"? See my examples below:
GridTemplateColumn column = new GridTemplateColumn();
column.UniqueName = e.ColumnUniqueName;
column.ItemTemplate = new ColumnTemplateForLabel(column);
column.FilterTemplate = new FilterTemplateForMultiSelectCombo(e.ColumnUniqueName);

Below is the "FilterTemplate" I'm attempting to setup:

public class FilterTemplateForMultiSelectCombo : ITemplate
{
 
    protected RadScriptBlock script;
    protected RadComboBox comboBox;
    protected string column = string.Empty;
 
 
    public FilterTemplateForMultiSelectCombo(string column)
    {
        this.column = column;
    }
 
 
    public void InstantiateIn(Control container)
    {
        comboBox = new RadComboBox();
        comboBox.ID = string.Format("cmb_{0}", this.column);
        comboBox.AutoPostBack = true;
        comboBox.DataBinding += new EventHandler(comboBox_DataBinding);
        comboBox.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(comboBox_SelectedIndexChanged);
 
        // comboBox.ItemTemplate = Checkbox control added to item template here...
        //comboBox.EnableEmbeddedSkins = false;
        //comboBox.Skin = "CustomSkin1";
 
        script = new RadScriptBlock();
        script.ID = "script_" + column;
 
        string scriptContent = "";
        (script.Controls[0] as LiteralControl).Text = scriptContent;
 
        container.Controls.Add(comboBox);
        container.Controls.Add(script);
    }
 
 
 
    // Load Control (Set Datasource)
 
    void comboBox_DataBinding(object sender, EventArgs e)
    {
        RadComboBox combo = (RadComboBox)sender;
 
        combo.Items.Add(new RadComboBoxItem(string.Empty, string.Empty));
 
        combo.Items.Add(new RadComboBoxItem("Option 1", "Value1"));
        combo.Items.Add(new RadComboBoxItem("Option 2", "Value2"));
        combo.Items.Add(new RadComboBoxItem("Option 3", "Value3"));
 
    }
 
    void comboBox_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
    {
        ((GridFilteringItem)(((RadComboBox)sender).Parent.Parent)).FireCommandEvent("Filter", new Pair());
 
    }
 
 
 
 
}


Below is the "ItemTemplate" I use for my GridTemplateColumns:

public class ColumnTemplateForLabel : ITemplate
    {
        protected Label lblLabel;
        RenderableTabColumn Column;
        private Requirement cellParent = null;
        private ControlValueUtil<RenderableTabColumn, RenderableCellValue> controlValueUtil = new ControlValueUtil<RenderableTabColumn, RenderableCellValue>();
 
        public ColumnTemplateForLabel(RenderableTabColumn column)
        {
            this.Column = column;
        }
 
        public void InstantiateIn(Control container)
        {
            lblLabel = new Label();
            lblLabel.ID = Column.Code;
            lblLabel.DataBinding += new EventHandler(lblLabel_DataBinding);
 
            container.Controls.Add(lblLabel);
        }
 
 
        void lblLabel_DataBinding(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            GridDataItem container = (GridDataItem)lbl.NamingContainer;
 
            cellParent = (Requirement)container.DataItem;

Or would it be better to override my GridColumnTemplate as demonstrated in the following link:
http://www.telerik.com/community/forums/aspnet-ajax/grid/how-to-add-gridboundcolum-with-custom-filtertemplate-all-programmatically.aspx 

Thanks!!!
0
Marin
Telerik team
answered on 02 Feb 2012, 03:24 PM
Hello Nathan,

 It depends on how exactly you want to perform the filtering. Note that by default the built-in filtering functionality works only for one filter value. So if you need to filter by multiple selected values from the combobox you will need to use an approach similar to the code library that Princy referenced -  fire a command (or an ajax request) from the client and handle it on the server where you need to construct the proper filter query and perform the filtering. This way you will override the default filtering functionality of the column. Building a custom filter template as in the code that you have pasted is appropriate in this case.  
 Inheriting from GridTemplateColumn can be used when you perform filtering by a single value - the methods that are overridden in this case add controls to the filter template and take care to preserve the entered filter value after a postback - e.g. if you have selected a certain item from the combobox and perform filtering the override of GetCurrentFilterValueFromControl will return the proper selected filter value so that is again set to the combobox after postback. This method however returns a single string value so in the case of filtering by multiple values this will not work correctly. That's why you need to manually perform the preserving and resetting of the filter values to the controls in the filter template after a postback has occurred. Otherwise the combo will lose its selected values when you recreate the filter template on postback.

All the best,
Marin
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Nathan
Top achievements
Rank 2
answered on 03 Feb 2012, 12:08 AM
Thanks for your help!

You are correct, I need to filter by multiple selections and preserve each selection. I'm currently having trouble setting up the FilterTemplate like the example Princy provided since my Column is created dynamically. I currently have a class setup for both the ItemTemplate and FilterTemplate of my GridTemplateColumn.

Do you have any suggestions for setting this up dynamically? Princy's example is static, mine is setup dynamic using ITemplate.

Below you can see I have my FilterTemplate which also contains another "ItemTemplate" required for the checkbox - "Nested". I'm not sure how to plug in the "onCheckBoxClick" event due to the nesting. I currently have this javascript function on my calling page, but I'm not sure how to pass the values for "Combo" (Since your example uses Container)



GridColumnTemplate <FilterTemplate>
public class FilterTemplateForMultiSelectCombo : ITemplate
{
 
    protected RadScriptBlock script;
    protected RadComboBox comboBox;
    protected ListValueCollection listOptions;
    RenderableTabColumn Column;
 
 
    public FilterTemplateForMultiSelectCombo(RenderableTabColumn column)
    {
        this.Column = column;
    }
 
 
    public void InstantiateIn(Control container)
    {
        comboBox = new RadComboBox();
        comboBox.ID = string.Format("cmb_{0}", Column.Code);
 
        comboBox.AutoPostBack = false;      // Will be changed to false
        comboBox.DataBinding += new EventHandler(comboBox_DataBinding);
 
        comboBox.ItemTemplate = new ColumnTemplateForMultiSelectCombo(Column.Code, comboBox.ID);
 
        container.Controls.Add(comboBox);
    }
 
 
    void comboBox_DataBinding(object sender, EventArgs e)
    {
        RadComboBox combo = (RadComboBox)sender;
 
        combo.Items.Add(new RadComboBoxItem(string.Empty, string.Empty));
        foreach (FilteredListValue item in Column.GetChildren<FilteredListValue>().Where(p => p.IsActive).OrderBy(p => p.ValueOrder))
        {
            combo.Items.Add(new RadComboBoxItem(item.Value, item.Uid));
        }
 
 
        //ListValue defaultOption = listOptions.GetChildren<ListValue>().FirstOrDefault(p => p.IsDefault);
        //if (defaultOption != null)
        //{
        //    // Check the checkbox for the default list item
        //    combo.SelectedItem.Value = defaultOption.Value;     // Change this...
        //}
    }
}


ComboBox <TemplateColumn>
public class ColumnTemplateForMultiSelectCombo : ITemplate
{
    protected Label lblLabel;
    protected CheckBox chkBox;
    string Column = string.Empty;
    string ComboBox = string.Empty;
 
    public ColumnTemplateForMultiSelectCombo(string column, string comboId)
    {
        this.Column = column;
        this.ComboBox = comboId;
    }
 
 
    public void InstantiateIn(Control container)
    {
        chkBox = new CheckBox();
        chkBox.ID = string.Format("msChk_{0}", Column);
        chkBox.Attributes.Add("onclick", "onCheckBoxClick(this, '" + comboBox + "');");
 
        container.Controls.Add(chkBox);
    }
 
}

Test Script to check if the Checkbox selection is working (This throws an error because combo is null)
function onCheckBoxClick(chk, combo) {
 
    alert('Test');
 
    var text = "", values = "";
    var combo = $find(combo);
 
    var items = combo.get_items();
 
    for (var i = 0; i < items.get_count(); i++) {
        var item = items.getItem(i);
        alert('Check Item: ' + item.get_text());
 
    }
 
}

Thanks for your help!
0
Nathan
Top achievements
Rank 2
answered on 03 Feb 2012, 09:45 PM
Hello,

I got the dropdown setup. It's loading all checkboxes as it should and the "CheckBox" onclick event is firing as expected. The problem is when the ajax request is triggered, it displays an error. Please let me know if you have any suggestions.

Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Details: Error parsing near '
<!DOCTYPE html PUB'.

Thanks!
0
Nathan
Top achievements
Rank 2
answered on 04 Feb 2012, 10:11 PM
Hello,

If I comment out the line below which sets the FilterTemplate, the error doesnt occur. In my code below you can see i'm dynamically creating the column and attempting to set the ItemTemplate and Filtertemplate using a class that inherits from ITemplate. Any ideas on why I would be recieving this error message when an ajax request is made (all ajax requests on the page)?

myColumn.FilterTemplate = new FilterTemplateForMultiSelectCombo("combo"); 

Error:
Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Details: Error parsing near '
<!DOCTYPE html PUB' 


Creating the column dynamically - setting both TemplateColumn & FilterColumn
GridTemplateColumn myColumn = new GridTemplateColumn();
myColumn.UniqueName = "Workflow";
myColumn.HeaderText = "<nobr>Workflow</nobr>";
myColumn.AllowFiltering = true;
myColumn.FilterTemplate = new FilterTemplateForMultiSelectCombo("combo");
myColumn.ItemTemplate = new ColumnTemplateForDetail("lblWorkflow");
 
this.grdSummary.MasterTableView.Columns.Add(myColumn);

Class used to add combo box to FilterTemplate (the checkbox has been removed while attempting to debug this error). This is a very simple version
public class FilterTemplateForMultiSelectCombo : ITemplate
{
    protected RadComboBox comboBox;
    string Column;
 
    public FilterTemplateForMultiSelectCombo(string column)
    {
        this.Column = column;
    }
 
    public void InstantiateIn(Control container)
    {
        comboBox = new RadComboBox();
        comboBox.ID = string.Format("fil_{0}", Column);
 
        comboBox.AutoPostBack = false;    
        container.Controls.Add(comboBox);
    }
0
Marin
Telerik team
answered on 06 Feb 2012, 01:04 PM
Hello,

 This is a general error indicating that there is something wrong with the ajax request that is sent to the server. The code for the filter template looks okay. Can you also post any code related to the ajaxifying of the controls. Do you use RadAjaxManager and how do you add the ajax settings. Also how exactly do you trigger the ajax request in the case of the error. Also you can try to replace the RadComboBox with a standard asp.net DropDown control to see if this prevents the error.
If the problem persists I will appreciate if you can send a sample page that replicates the issue so we can investigate it on our side.

Regards,
Marin
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Nathan
Top achievements
Rank 2
answered on 06 Feb 2012, 04:57 PM
I found the error is being caused by the RadComboBox, when I use a label in my "FilterTemplateForMultiSelectCombo" it works fine, if I use "RadComboBox" it breaks. 

This means it must be related to the script generated by the Combo Box. Any suggestions on how to fix this??


FilterTemplateForMultiSelectCombo with RadComboBox:
public void InstantiateIn(Control container)
{
    comboBox = new RadComboBox();
    comboBox.ID = "cmb" + Column.Code;
 
    container.Controls.Add(comboBox);
}

FilterTemplateForMultiSelectCombo with LABEL: 
public void InstantiateIn(Control container)
{
    lblLabel = new Label();
    lblLabel.ID = "lblTest" + Column.Code;
 
    container.Controls.Add(lblLabel);
}


** You can see in my previous post, I'm setting my grid column FilterTemplate to this class which implements ITemplate. My code is very complex and would be very difficult to break into an example. Since I've narrowed it down to the RadCombobox I'm hoping this is sufficient, please let me know what you think. Although, if you must have an example, I'll work on getting it to you.

Thanks!!
0
Marin
Telerik team
answered on 09 Feb 2012, 10:44 AM
Hi Nathan,

 I tried to reproduce the error using the filter template with RadComboBox and adding dynamically a template column to the grid but to no avail. The error is most likely related to the way you add ajax settings to the grid and the controls inside it. The problem is not in the filter templates themselves but in the fact that you have script controls (e.g. RadComboBox) in this template. For some reason after an ajax request the control is not recreated properly. Which might be caused by wrong ajax settings. That's why I will appreciate if you can specify how exactly you add the ajax settings in the grid and possibly provide a full runnable page that replicates the problem so that we can investigate it on our side.
Thank you for your cooperation.

All the best,
Marin
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
Grid
Asked by
Nathan
Top achievements
Rank 2
Answers by
Princy
Top achievements
Rank 2
Nathan
Top achievements
Rank 2
Marin
Telerik team
Share this question
or