In this post I would like to share implementation of advanced SPGridView control which has more features comparing with OTB SPGridView. As you probably now SPGridView control can be used in Sharepoint in order to display list-like data. I.e. with its header you can sort item, filter them – and it will work with OTB look and feel. However there is a lack of important features in OTB SPGridView: it supports filtering only by single column. Also if you use SPGridView for displaying some multi values field (e.g. TaxonomyFieldMulti or LookupMulti) – you will need to concatenate all values for single field into one string using some separator (e.g. string.Join(“,”, values)). The disadvantage of this approach is that from SPGridView point of view it will be single string value. As result in filter menu it will be displayed as single string.
Lets consider example: suppose that we have Language taxonomy field which allows multiple values (TaxonomyFieldMulti). It allows you to specify several languages: English, Finnish, Russian, Sweden. Suppose that we selected all of these 4 values for some list item. In our data source we concatenate these values into one string. Now lets see how it will be displayed in OTB SPGridView filter menu:
See that all values are shown as one filtering option. It means that when you will select this option you will get only those items which have absolutely the same value in Language field. Event if Language field of another item has the same set of Language but in different order (e.g. Finnish, English, Russian, Sweden) – it will be treat as different value and another filtering option will appear in menu. Now lets see how it looks like in OTB XsltListViewWebPart:
See that all options are presented as separate filtering option. That is our goal – to add this functionality in OTB SPGridView control.
But lets start with another problem: multi column filter. As I said above OTB SPGridView control supports filtering only by one column. I.e. you can apply filter on several columns simultaneously. This problem was solved by Erik Burger in his great blog post: Building A SPGridView Control – Part 4: Filtering Multiple Columns. Thanks to Erik for sharing his solution. It works successfully both for Sharepoint 2007 and 2010. However it has own problems: currently selected filter value is not shown in the filtering menu like it is shown in OTB SPGridView:
Well we are going to solve this problem as well.
So here is the code of changed SPGridViewProxy:
I will describe only differences from the Erik’s post. First of all I added MultiValuesFields property (line 19) – using this property you can tell to custom SPGridViewProxy control what values are really multi values and should be split into tokens. For our case we will specify MultiValuesFields=”Language”. However you can specify as many fields as you need here separated by comma.
Next check the line 84:
Another change is lines 120-130. Here we make actual trick for multiple values fields. We check whether or not current field name corresponds to a field with multiple values (using MultiValuesFields property mentioned above). If yes – then instead of simple equal expression (“=”) we will use LIKE expression. E.g. if we select Finnish language then filter expression will be: [Language] LIKE ‘%Finnish%’. So our list item with Language = “English,Finnish,Russian,Sweden” will match this filter.
Next change on lines 138-150. Here I added functionality which restricts number of selected filtering values for single column by one value. This is how OTB SPGridView and XsltListViewWebForms work. However it is not very hard to expand it to several values per column and if you will need it – you can implement it by yourself.
The last change is isMultipleValues() function (lines 162-181). It just check whether or not specified field name exists in MultiValuesFields property of the control.
Now lets check client side of the solution:
Lets also check changes comparing with Erik’s solution. I added 3 helper functions: Array_Contains(), ASPGridView_IsNullOrEmpty() and ASPGridView_IsValueInFilter() (see lines 41-58). I didn’t want to use jquery here in order to avoid introducing dependencies on external libraries and in order to keep things as much easier to use as possible. Check line 86:
In lines 98-112 we split all multi values fields into single array of unique values. These values will be used for filter menu in lines 115-124. Note that on the line 121 we use ASPGridView_IsValueInFilter() in order to check selected filter values in the menu.