Friday, June 27, 2008

SPGridView Filtering

SPGridView is an amazing control in WSS 3.0's Microsoft.SharePoint.WebControls namespace. It is feature-packed but unfortunately, there is little documentation on how to use it beyond the vanilla data-binding. The post at Bob's SharePoit Bananza is perhaps the most helpful work so far. And here's another one with a bit more code.

I want to talk about a couple of quirks that took me forever to figure out as I was trying to get the filtering working in my own web part:


  • It is important to assign the SPGridView object a ID value. This is often overlooked when you create and add the instance in the backend code
    SPGridView grid = new SPGridView();
    grid.ID = "gvw1"; //or any string

    If the ID is not assigned, ASP.NET would assign one like "ctl00" automatically as it renders the control. However, this would result in the filter dropdown on the column header not working. Upon clicking, it gives a generic javacript error "'null' is null or not an object". Here's the difference in the onClick attribute in the HTML table tag generated:

    ID property not assigned:
    onclick="SPGridView_FilterPreMenuOpen('ctl00_PlaceHolderMain_ctl00', 'ctl00_PlaceHolderMain_ctl00_SPGridViewFilterMenuTemplate', 'ctl00_PlaceHolderMain_ctl00_ctl01_SPGridViewMenu0', 'Title', event);

    ID property = "gvw1":
    onclick="SPGridView_FilterPreMenuOpen('ctl00_PlaceHolderMain_gvw1', 'ctl00_PlaceHolderMain_gvw1_SPGridViewFilterMenuTemplate', 'ctl00_PlaceHolderMain_gvw1_ctl01_SPGridViewMenu1', 'Title', event);

    There is really no difference other than the ctl100 vs gvw1. However, it costed me a lot of hairs to figure out that it DOES make a difference!

  • The columns with the filter one can not have spaces in the column name. This is typically not an issue as the internal name of any field in SharePoint has no space (concatenated by the underline if the display name has spaces). The problem could arise when the data comes from a different source or is manipulated with new columns added in the fly. For exmaple:
    this.grid.FilterDataFields = "Service Department";
    this.grid.FilteredDataSourcePropertyName = "FilterExpression"; this.grid.FilteredDataSourcePropertyFormat = "{1} = '{0}'";

    "Service Department" is a new column I added to the DataTable behind the ObjectDataSource, and it is the column that I want to filter on (It's the first column in the data source so no commas needed). However, it gives this error when dropping down the filter and clicking an item in the dropdown:
    Syntax error: Missing operand after 'Department' operator. at System.Data.ExpressionParser.Parse() at System.Data.DataExpression..ctor(DataTable table, String expression, Type type) at System.Data.DataView.set_RowFilter(String value) at System.Web.UI.WebControls.FilteredDataSetHelper.CreateFilteredDataView(DataTable table, String sortExpression, String filterExpression, IDictionary filterParameters) at System.Web.UI.WebControls.ObjectDataSourceView.CreateFilteredDataView(DataTable dataTable, String sortExpression, String filterExpression) at System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) at System.Web.UI.WebControls.DataBoundControl.PerformSelect() at System.Web.UI.WebControls.BaseDataBoundControl.DataBind() at System.Web.UI.WebControls.GridView.DataBind()

    Again not very indicative what the problem is. Well, the space in the column is the problem. Changing the column name to "Service_Department" or "ServiceDeparment" and the code above accordingly fixed the problem.

2 comments:

Unknown said...

Ran into the same issue with spaces in the column name. The fix is to wrap the column name with [], for example:

gridProjects.FilteredDataSourcePropertyFormat = "[{1}] LIKE '{0}'";

Anonymous said...

Thsnks about those [], it took me so many hours to figure it out!