In Part 2 of this series, we added filtering to our ASPGridView. Since then I’ve gotten a lot of questions about implementing multi-column filtering. Again the main reason seems to be “If SharePoint can do it, why can’t we?”. And that’s exactly the kind of question that gets me going 🙂 I love a good challenge. And remember, we set out to build a control that matches the built-in functionality of SharePoint as closely as possible. So multi-column filtering should definitely be in the list of features.

Multi-column filtering comes with it’s own set of unique challenges. For one, we cannot use the same techniques we used in single-column filtering. Part of the problem is that a lot of the filtering action in the SPGridView is client side, which means we’ll need to use some JavaScript to get things working. We’ll also need to dive a lot deeper into the inner working of the SPGridView.

In order to do that and at the same time retain all the work we’ve done so far, I opted to use the Proxy Pattern. This means we create a proxy object that routes most of the functionality directly to the SPGridView object but in the case of filtering it performs some work of it’s own and then routes to the original object. It’s really very close to standard inheritance but we computer people like our patterns, don’t we? 😉

The code for our proxy object (aptly named SPGridViewProxy) is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.WebControls;
using Menu = Microsoft.SharePoint.WebControls.Menu;
using System.Web.UI;
using System.Reflection;
using System.Web.UI.WebControls;
 
namespace ReverseAlchemy.BuildingASPGridViewControl.Controls
{
  public class SPGridViewProxy : SPGridView, IPostBackEventHandler
  {
    protected override void OnLoad( EventArgs args )
    {
      base.OnLoad( args );
      ScriptLink.Register( this.Page, "aspgridview.js", false );
    }
 
    protected override void Render( System.Web.UI.HtmlTextWriter writer )
    {
      base.Attributes["callbackEventReference"] =
        base.Attributes["callbackEventReference"].Replace( "SPGridView_FilterCallbackHandler", 
                                                           "ASPGridView_FilterCallbackHandler" );
 
      MenuItemTemplate t = this.FindControl( "SPGridViewFilterMenuTemplate" ).Controls[3] as MenuItemTemplate;
      t.ClientOnClickScript = t.ClientOnClickScript.Replace( "__ClearFilter__", "__ClearFilter__;%FIELDNAME%" );
 
      if ( this.HeaderRow != null )
      {
        foreach ( TableCell cell in this.HeaderRow.Cells )
        {
          Menu menu = (cell.Controls[0] as Menu);
          if ( menu != null )
          {
            menu.ClientOnClickPreMenuOpen = 
              menu.ClientOnClickPreMenuOpen.Replace( "SPGridView_FilterPreMenuOpen", 
                                                     "ASPGridView_FilterPreMenuOpen" );
          }
        }
      }
 
      base.Render( writer );
    }
 
    protected new void DoFilterPostBackEventProcessing( string filterData )
    {
      string filterExpression = String.Empty;
      if ( filterData.StartsWith( "__ClearFilter__" ) )
      {
        string[] data = filterData.Split( ';' );
        string fieldName = data[1];
 
        string oldFilterFieldName = base.Attributes["filterFieldName"];
        List<string> fieldNames = new List<string>( oldFilterFieldName.Split( ';' ) );
        fieldNames.Remove( fieldName );
        base.Attributes["filterFieldName"] = String.Join( ";", fieldNames.ToArray() );
 
        string oldFilterExpression = Convert.ToString( ViewState["FilterExpression"] );
        string[] filters = oldFilterExpression.Split( new string[] { " AND " }, StringSplitOptions.RemoveEmptyEntries );
        List<string> newFilters = new List<string>();
        foreach ( string filter in filters )
        {
          if ( !filter.Contains( String.Format( "[{0}]", fieldName ) ) )
          {
            newFilters.Add( filter );
          }
        }
        filterExpression = String.Join( " AND ", newFilters.ToArray() );
      }
      else
      {
        filterExpression = ExtractFilterExpression( filterData );
      }
 
      ViewState["FilterExpression"] = filterExpression;
 
      if ( filterExpression == null ) { return; }
 
      DataSourceControl control = this.NamingContainer.FindControl( this.DataSourceID ) as DataSourceControl;
      PropertyInfo pi = control.GetType().GetProperty( "FilterExpression" );
      pi.SetValue( control, filterExpression, null );
 
      base.RequiresDataBinding = true;
    }
 
    private string ExtractFilterExpression( string filterData )
    {
      string[] data = filterData.Split( ';' );
      string fieldName = data[0];
      if ( String.IsNullOrEmpty( fieldName ) )
      {
        return null;
      }
 
      string oldFilterFieldName = base.Attributes["filterFieldName"];
      if ( oldFilterFieldName != null )
      {
        if ( !oldFilterFieldName.Contains( fieldName ) )
        {
          base.Attributes["filterFieldName"] += ";" + fieldName;
        }
      }
      else
      {
        base.Attributes.Add( "filterFieldName", fieldName );
      }
 
      string fieldValue = data[1].Replace( "%3b", ";" ).Replace( "%25", "%" );
 
      string oldFilterExpression = Convert.ToString( ViewState["FilterExpression"] );
      string newFilterExpression = String.Format( "[{0}] = '{1}'", fieldName, fieldValue );
 
      if ( !String.IsNullOrEmpty( oldFilterExpression ) )
      {
        if ( oldFilterExpression.Contains( newFilterExpression ) )
        {
          newFilterExpression = oldFilterExpression;
        }
        else
        {
          newFilterExpression = String.Join( " AND ",
                                        new string[] { oldFilterExpression, newFilterExpression } );
        }
      }
 
      return newFilterExpression;
    }
 
    private string GetValueAfterPrefix( string value, string prefix )
    {
      if ( String.IsNullOrEmpty( value ) ||
           String.IsNullOrEmpty( prefix ) ||
           !value.StartsWith( prefix ) )
      {
        return null;
      }
 
      if ( prefix.Length < value.Length )
      {
        return value.Substring( prefix.Length );
      }
 
      return String.Empty;
    }
 
    #region IPostBackEventHandler Members
 
    void IPostBackEventHandler.RaisePostBackEvent( string eventArgument )
    {
      string valueAfterPrefix = GetValueAfterPrefix( eventArgument, "__SPGridView__;" );
      if ( valueAfterPrefix != null )
      {
        string filterData = GetValueAfterPrefix( valueAfterPrefix, "__Sort__;" );
        if ( filterData == null )
        {
          filterData = GetValueAfterPrefix( valueAfterPrefix, "__Filter__;" );
          if ( filterData != null )
          {
            DoFilterPostBackEventProcessing( filterData );
          }
        }
        else
        {
          DoSortPostBackEventProcessing( filterData );
        }
      }
      else
      {
        base.RaisePostBackEvent( eventArgument );
      }
    }
 
    #endregion
  }
}

That’s quite a bit of code to wade through so I added some line numbers to make it a bit easier. I mentioned that we needed to do some JavaScript to make things work. In the OnLoad method (line 14) we register our JavaScript file. This is basically the original spgridview.js file with a few modifications.

In the Render method on line 20 we modify the callbackEventReference and the template for the filtering menu (SPGridViewFilterMenuTemplate) to reroute their events to our new JavaScript file. The menu template works exactly the same as we discussed in Part 3 of this series.

Note this line:

27
t.ClientOnClickScript = t.ClientOnClickScript.Replace( "__ClearFilter__", "__ClearFilter__;%FIELDNAME%" );

The original SPGridView doesn’t specify which filter to clear if we click the ‘Clear Filter’ option in the menu. That makes sense, because there’s always only one column being filtered. To enable multi-column filtering we need to know which filter to clear. Note that %FIELDNAME% is a Menu token (again, see Part 3 for more details).

Before we go into the other methods, let’s see what we’ve changed in the JavaScript file. Fortunately, not much. In order to render the correct menu. the client-side script needs to know whether filtering is turned on for a specified column. This is handled in the SPGridView_FilterPreMenuOpen and the SPGridView_FilterCallbackHandler methods. Below is the original code snippet inside those methods that takes care of this:

1
2
3
4
5
6
7
var filterCurrentlyOn = false;
if ((filterFieldName != null) &&
    (filterFieldName.length > 0) &&
    (filterFieldName == dataFieldName)) 
{
    filterCurrentlyOn = true;
}

In order to support multiple columns, we simply change the condition in line 4 to:

4
(filterFieldName.match(dataFieldName) != null)

Other than that we changed the name of the methods so they don’t conflict with the existing ones and changed some of the error messages to refer to the ASPGridView instead of the SPGridView. The modified JavaScript file lives in the LAYOUT directory of the 12 hive.

Back to our proxy object. Our goal is to reroute the filtering to our proxy and then let the actual SPGridView object take care of the rest. The IPostBackEventHandler.RaisePostBackEvent method on line 149 is a 1-on-1 copy of the original method. Its sole purpose is to make sure the DoFilterPostBackEventProcessing method of our proxy is called instead of the original.

The DoFilterPostBackEventProcessing method is where all the magic happens. In lines 48 to 76 we take the provided filter expression and build a new one. Note lines 54 and 57 where we set the filterFieldName attribute of the SPGridView control. This is used by our JavaScript to turn filtering on and off.

Lines 80 to 82 override the FilterExpression property of our DataSource control to accommodate multiple columns. Finally line 84 causes the SPGridView to re-bind its data.

And that is all there is to it. All that is left for us to do is replace all the references to the SPGridView object by references to the SPGridViewProxy object in our ASPGridView class.

You can find the source of this instalment here.

Actually, I am not completely satisfied just yet. As you’ll notice, the list of values you can filter on does not reflect the fact that you are filtering on more than one column. I’ll address that issue in a next post 🙂

I hope you’ve found this post interesting and helpful. I look forward to hearing from you.

Erik

If you liked this post, please click on one of the advertisements below. Thanks!


60 Responses to “Building A SPGridView Control – Part 4: Filtering Multiple Columns”

  1. 1 Mark Parter

    Works a treat, thanks. Looking forward to the next installment which I presume is to fix the fact that the UI only presents to the user that one filter has been applied, when in reality it’s allowing multiple.

  2. 2 Erik Burger

    Hi Mark,

    I am glad you liked it (and that it worked 😉 ). I am going to address a problem with the UI showing the wrong information, but I am wondering if we are talking about the same thing. Are you talking about the icon not appearing on the columns that are filtered or the filter menu not showing the correct data? If the first, that should actually work so we might have to look into that a little more. If the second, that’s the one I’ll be talking about. To illustrate, you can find a screenshot of the ASPGridView in action here.

    Regards,

    Erik

  3. 3 Mark Parter

    Hi Erik,

    I was refering to the fact that the icon (for me anyway), only shows for the last column that was filtered, although the filter is still being applied to both columns.

    I had a look at your screenshot but vcan’t see what the issue is. Is it the fact that you’ve filtered and the item isn’t highlighted in the list of filter values?

    This part works for me although again, it’s only being applied to the last filtered column. So the filter appears to be applied, it’s just the UI aspects which are awry.

    Thanks,

    Mark

  4. 4 Erik Burger

    Hi Mark,

    What I meant was that the possible filter values in the “Total Sales H” column are not filtered to represent the already active filters on the other two columns. What I would want to happen is that the possible filter values only contain those values that match both “J. Smith” and “Asia” (as in “SELECT FROM [Total Sales H] WHERE [NameH] = ‘J.Smith” AND [RegionH] = ‘Asia’).

    As for the icons not showing correctly, I actually forgot to include the necessary changes to the grid_RowDataBound method of the ASPGridView class in my post. My apologies. I’ve updated the post.

    Thanks for pointing this out.

    Erik

  5. 5 Mark Parter

    Thanks for updating your post. At the risk of being cheecky, have you ever encountered this issue I’m experiencing?

    http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/a1a64a0d-4f4e-4168-8b7e-19926cc2a056

  6. 6 Erik Burger

    Hi Mark,

    No, I’m afraid your issue is completely new to me. The workaround provided seems way to hackish to me though so I wouldn’t bet my money on that being the solution. If you are using your own SPGridView control, maybe attaching the debugger might shed some light on the issue, or at least where it is occurring.
    Also, you could try to add the user you are logging into SP with to the authorized users in your SQL database. If I had to hazard a guess, it somehow seems that the SP user’s credentials are used to try and log in to SQL, but only after the connection to SQL is refreshed. Adding the SP user’s credentials to your SQL database would then solve the issue. It’s a VERY wild guess and it still sounds hackish to me but it’s more manageable than the offered solution. I think.

    Good luck,

    Erik

  7. 7 Mark Parter

    Hi Erik,

    Sorry to be a pest but I just can’t seem to get more than one filter icon showing at a time. I’ve recopied your proxy code above and checked the code in your grid_RowDataBound event of the ASPGridView class and it looks the same as what I’ve currently got.

  8. 8 Erik Burger

    Hi Mark,

    No problem whatsoever. I provided the code so I’d like to see it work for you too 😉 Would you be able to send me your code so I can have a look at it? I am sure the problem is something simple (as these problems tend to be) but without the code I can’t think of anything to point you in the right direction. My e-mail address is eburger at reversealchemy dot nl.

    If you can’t send me the code (for commercial reasons, for example) please let me know and I will try and flesh out exactly which parts of the code are involved in the setting of the icon. That might help. But having the code would be better 😉

    Erik

  9. 9 Rolf Schneider

    Small update:

    filtering didn’t “survive” when using paging. You just have to move (line 80-82)

    DataSourceControl control = this.NamingContainer.FindControl( this.DataSourceID ) as DataSourceControl;
    PropertyInfo pi = control.GetType().GetProperty( “FilterExpression” );
    pi.SetValue( control, filterExpression, null );
    into the very beginning of the render-method. Enculapsed by a check of viewState(“FilterExpression”).

    If (viewState(“FilterExpression”) != Null)
    {
    ‘ the three lines above
    }

    Greets
    Rolf

  10. 10 Erik Burger

    Hi Rolf,

    Well spotted, you are correct. I remember a similar issue with sorting not “surviving” in part 2 of this series. The solution is similar.

    Thanks,

    Erik

  11. 11 Forrest Towne

    Erik,

    In the Render method, where it iterates through the HeaderRow.Cells, the Cell.Controls(0) appears to be DataControlLinkButton rather than Menu. This appears to be the only control. Is this because I don’t enable filtering on all columns? So I added a Type check and only execute if the Type Is Menu. This appears to work.

    Now my problem is the Filter DropDown doesn’t open. Any idea on what to check?

  12. 12 Forrest Towne

    Erik,

    I located a couple of typos in the aspgridview.js, now the DropDownMenu opens and populates. The new problem occurs when I select a value. I get a PopUp Windows that states “The syntax of the callback value is not supported by SPGridView.” Any cluse as to where I should look?

  13. 13 Forrest Towne

    Erik,

    I located the problem, it was due to the way I converted the C# to VB. So I no longer am getting any errors, however, sny postback appears to disable the “Clear Filter” option. Examples include paging, sorting, or selecting. It also appears that the multiple Filter option doesn’t work. I only get the last Filter applied.

  14. 14 Erik Burger

    Hi,

    When I get home tonight I will send you the full solution I created for this. I think in your changes before you broke something vital. Seeing the full code (which “works on my machine” ;)) might help you get your solution to work, as well.

    Erik

  15. 15 Nikunj Bhanushali

    Hey,

    Gr8 solution.. I have used your given implementation for customizing spGridview & it works execlent. I have created a Web part for it. But when I add more then one of this webparts on the page, functionality starts to break. Selecting a filter in one web part results in reseting the other one.

    Havent been able to get a fix for the same..any ideas to share..?

  16. 16 Erik Burger

    Hi Nikunj,

    I am glad to hear you liked my solution.

    I recall a similar problem I encountered earlier in writing this series which was solved by using a NamingContainer.

    In your case, though, things might be more complicated since JavaScript is involved. If I am right, SharePoint is basically treating both controls as one which is why the filter event is raised to both controls. What I would suggest is to attach a debugger to both your web parts and see what is being submitted back the the grids when you change/set a filter.

    I am sorry for being so vague but I am currently at work and have no access to the actual code. When I get some time I will see if I can duplicate your issue and see whether I can come up with a better answer.

    Best,

    Erik

  17. 17 Forrest Towne

    Erik,

    I will download your code and try it.

    Where I am currently at is that the “filterFieldName” attribute is always returning null. I have step through it over and over. It looks like it is adding the new FieldName, but on the next cycle it returns null again.

    Forrest

  18. 18 Forrest Towne

    Erik,

    I added some logic to use SaveControlState/LoadControlState. I saved the FilterFieldNane, FilterFieldValue, and FilterExpression. By doing this I was able to make the multiple filter work and continue even if sorted or paged. I also got the Filter Icon I use to show up on the appropriate headers. I also have the “Clear Filter” staying enabled on all menus. What I was lacking was showing the FilterFieldValue that was currently in use. I thought it would be an easy change to the aspgridview.js.

    I thought I could use the .match like you did for the FilterFieldName. Ever since I made the edit I get an error when I click on the menu.

    The Error is a pop up and states that Object is expected! I tried changing the ScripLink.Register back to the original spgridview.js and I still get the same error. Any ideas on what might be happening?

    Forrest

  19. 19 Forrest Towne

    Erik,

    Thought I should update you on where I am know. I have the multiple filters now marking the proper value and keeping the “Clear Filter” enabled. I am able to clear one and have it properly disable the “Clear Filter” and unmark the value. My addition that shows the filter icon like it does in SharePoint also works. I had to do some Type checking as some columns may not have filtering enabled.

    The only problem I still see, which I believe you mentioned earlier is that the dropdownlist shows all values instead of just the filtered values. Don’t know if I’ll find time to research that as they want me to get my project finished ASAP.

    For the Clear Filter I find the index for the FieldName and remove the same from the FieldValues and FilterExpressions. Basically duplicating what you had already for the FieldNames.

    Thanks for your help, it was extremely valuable.

    Forrest

  20. 20 Erik Burger

    Hi Forrest,

    You are very welcome but you did most of the work yourself 🙂

    Thanks for the update, I really appreciate it. I am glad you got it working. I started looking into the dropdownlist issue but didn’t get to a satisfactory (i.e. non hack) solution yet. If I do -which involves finding some time somewhere- I’ll be sure to let you know. If you figure something out in the meantime I’d love to hear it.

    Erik

  21. 21 Nikunj Bhanushali

    Hello Erik,

    Thanks for the reply.

    I tried to debug the issue & found that the Filter menu event was getting wired to the very first Grid view on the page. So in the Proxy I had to overwrite the OnClientClickScript of menu in Render method to set the Target Control ID to the current grid views ID.

    Dont know what was causing such a behaviour but I managed to fix it that way.

    Thanks Again

    ~Nikunj~

  22. 22 Erik Burger

    Hi Nikunj,

    I hardly did anything but you are welcome anyway 😉

    Well done on fixing the issue. So instead of being tied to both GridViews as I suspected it was only being tied to the one. Makes sense in a weird kinda way 😉

    Thanks for posting your solution, I am sure other people will be helped by it as well.

    Erik

  23. 23 Nowshad

    Hi,

    Your posts looks great and mu request is can i get an working example of this code?

  24. 24 Erik Burger

    Hi,

    Thanks for the compliment. Drop me a line at the address specified in the Contact menu and I’ll send you the source asap.

    Erik

  25. 25 Nowshad

    Where to get the updated post which fixes the filter image for multiple columns and enable the clear links??????????/

  26. 26 Erik Burger

    Hi,

    I am hoping that the source I’ll send you will fix that for you..I am having an issue with WordPress not wanting me to edit posts so I cannot fix the errors in there at the moment. The issues you describe aren’t happening in my code so I am hoping that will be the same for you. If not, we’ll fix it. Also, take a look at the other comments.

    Erik

  27. 27 greg

    This is a great post. I couldn’t find the source codes for part 4. could you please send me the codes? Thank you!

    Greg

  28. 28 Erik Burger

    Hi Greg,

    Thanks for the compliment 🙂 I sent you an e-mail with the latest source.

    Erik

  29. 29 tzvi

    Thanks a million! Your code has been a big help!
    I’d like to get your updated source codes for part 4.
    As of the aspgridview.js file I can’t detect it on my computre, I’ll be greatfull to get a copy of it too.

    Tzvi

  30. 30 Niels

    Hi Erik,

    i love your series about the SPGridView. I’m currently using it for displaying data from an external SQL Server. After some modifications to “ExtractFilterExpression” the Filtering mechanism is working great. However as soon as i have filtered by more than one column, the “Clear Filter from XYZ” is disabled. In addition, the value by which the column is currently filtered isn’t lit up. Would you mind sending me your latest source so i can compare it to mine?

    Niels

  31. 31 Erik Burger

    Hi Niels, tzvi,

    I am glad you found my post useful. Since you are not the first (or hopefully the last) to ask about the source, I just edited the post to include a link to the latest source. Please let me know how you get on, I am always interested to hear it.

    @tvzi: the aspgridview.js file is actually one of my own, so that’s why you couldn’t find it. It’s included in the download, of course 🙂

    Cheers,

    Erik

  32. 32 abc

    Hi,

    Could you share how editing is done in the filtered rows???

  33. 33 Erik Burger

    Hi,

    Editing in the filtered rows should be exactly the same as editing without filtering. If you can do the one, you can do the other. Is your question about how to enable row editing in the grid? If so, perhaps this post can point you in the right direction. If not, let me know and I might whip up a short post on how to enable editing in the ASPGridView.

    Regards,

    Erik

  34. 34 AC

    Hi Erik,

    Thanks for the gr8 post. I have been following this for a long time but last week I had the misfortune of actually implementing this 🙁 ……..modified your code as per my requirements and it is working fine.

    Although, I have a couple of questions:

    – did you get time to sort out the filter values (i.e. when you select a filter value on one column, the other columns still show all the values to filter) and,

    – do you have any sample/ suggestions for grouping data on multiple columns?

    Regards,
    AC

  35. 35 Erik Burger

    Hi AC,

    Glad you found it useful. Unfortunately I haven’t yet found the time to spend on those two issues. What I do know is that turning ViewState off seems to work to get grouping working on single columns. As for multiple columns, I honestly don’t know. It’d be pretty interesting to try and find out though..let me know if you figure it out and I promise I will do the same! 🙂

    Erik

  36. 36 Arvind

    Hey Erik!

    Nice job. But am facing an issue if I disable the Viewstate of the gridview. The control doesn’t seem to work if “EnableViewState” of the grid is set to “False”. Is there any workaorund on this?

    This causes only single column filtering of the grid.

    – Arvind

  37. 37 Erik Burger

    Hi Arvind,

    I am afraid I haven’t had the time to further research these issues. The work-around to get grouping seems to be to turn the ViewState off but at the same time, as you point out, this breaks the multiple filtering. As soon as I find some time I will look into this.

    Erik

  38. 38 navish

    hi erik

    please tell me from where i can download aspgridview.js file
    Thanks

  39. 39 Erik Burger

    Hi Navish,

    There’s a link at the bottom of the post where you can download the source. The aspgridview.js file is part of it.

    Erik

  40. 40 PeterGa

    Hi Erik

    I do only want to know, If you have try this Example on Sharepoint 2010?

    Thanks

  41. 41 Erik Burger

    Hi,

    No, I haven’t had the chance to do so yet. Time permitting, I am planning to do so soon. My guess is it should work but Microsoft may have changed the spgridview.js file which would make it break. If I get a chance to check it out I will definately post about any issues I might find.

    Erik

  42. 42 PeterGa

    I already fixed the thing with all filtering options if multiple filtering is enabled on more columns.

    Just what you need is put this part of code to

    protected sealed override void CreateChildControls()
    {
    const string GRIDID = “grid”;
    const string DATASOURCEID = “gridDS”;

    gridDS = new ObjectDataSource();
    gridDS.ID = DATASOURCEID;
    gridDS.SelectMethod = “SelectData”;
    gridDS.TypeName = this.GetType().AssemblyQualifiedName;
    gridDS.ObjectCreating += new ObjectDataSourceObjectEventHandler(gridDS_ObjectCreating);
    this.Controls.Add(gridDS);

    if (Page.IsCallback & ViewState[“FilterExpression”]!=null)
    {
    gridDS.FilterExpression = ViewState[“FilterExpression”].ToString();
    }
    ….
    }

  43. 43 Erik Burger

    Hi,

    Great work! Seems a very clean and simple solution.

    Erik

  44. 44 Julian

    I have used you sample code and it works great!!. I have a issue that I hope you have an answer for. The selectdata() function is called about a 6 times when the page loads. Is there a work around for this????

    thanks

    Julian

  45. 45 Alex

    Hi Erik,
    Thanks for sharing this example! I used it with Sharepoint 2010 and it works well. I expanded its filtering features for using with multi values columns (like TaxonomyFieldMulti and LookupMulti). I posted implementation details here: http://sadomovalex.blogspot.com/2011/03/spgridview-with-filtering-by-multiple.html (my post contains links to this article). Thanks again.

    Alex

  46. 46 Erik Burger

    Hi Alex,

    And thank you for using this example 🙂 I read your post and it’s great, I really recommend anyone reading this to check it out.

    Keep up the good work!

    Erik

  47. 47 Paul

    First off….this is a great article and the code is extremely useful. I’d like to propose a fix though. If you put multiple instances of the webpart on the same page, the filter breaks. The reason is the Template Client ID for the FilterPreMenuOpen always gets set to the first webpart. Adding the following two lines of code for building the ClientOnClickPreMenuOpen solves the problem:

    menu.ClientOnClickPreMenuOpen = menu.ClientOnClickPreMenuOpen.Replace(“%TEMPLATECLIENTID%”, this.ClientID + “_SPGridViewFilterMenuTemplate”);
    menu.ClientOnClickPreMenuOpen = menu.ClientOnClickPreMenuOpen.Replace(“%MENUCLIENTID%”, this.ClientID + “_ctl01_” + menu.ID);

    Great work though!!

    Paul

  48. 48 Erik Burger

    Thanks very much Paul for sharing your fix and for the compliment 🙂

  49. 49 Manu

    Hello Erik. I am using version 2, but with datetime fields it does not short. Is it usefull version 4 for this?
    Thank you for sharing the code. If anyone is interested I am added some functionality for Sharepoint foundation and CAML.

  50. 50 Edijs

    Hi Erik,

    Thank you for publishing this blog series, it worked well for my solution.

  51. 51 Kilua

    Hi Erik,

    This is really cool 🙂 But one thing i noticed that there is a bug on sorting. Only the previous filtered information should be display when you sort the information. May i request the updated source code? Thank you. 🙂

    Kilua

  52. 52 Erik Burger

    Hello Kilua,

    Thank you for the compliment, I am glad you like it! Unfortunately there is no updated source code at this moment as I have not continued on this project for a while. Please feel free to adapt the source code to your wishes, let me know how you get on!

    Regards,

    Erik

  53. 53 Kuspakov Rustam

    Hello!

    When I use Paging, the filtration doesn’t work. I am add code;

    #region IPostBackEventHandler Members

    void IPostBackEventHandler.RaisePostBackEvent( string eventArgument )
    {
    ……..
    else
    {
    if (ViewState[“FilterExpression”] != null)
    {
    DataSourceControl control = this.NamingContainer.FindControl(this.DataSourceID) as DataSourceControl;
    PropertyInfo pi = control.GetType().GetProperty(“FilterExpression”);
    pi.SetValue(control, ViewState[“FilterExpression”].ToString(), null);

    base.RequiresDataBinding = true;

    }

    base.RaisePostBackEvent( eventArgument );
    }
    }

    #endregion
    }
    }

  54. 54 prabhash

    Hi Erik,

    Thanks for the gr8 post. I have been following this for a long time but last week I had the misfortune of actually implementing this ……..modified your code as per my requirements and it is working fine.

    Although, I have a couple of questions:

    – did you get time to sort out the filter values (i.e. when i select a column for soting previously used filter enabled automatically on the other cloumn and the clear filter option is disabled .

    may i request you to send me the updated code. its urgent.

    Regards,

    prabhash

  55. 55 Erik Burger

    I’m sorry Prabhash I didn’t as of yet have the time to look into this more.

  56. 56 drew johnston

    Hey bud,

    I’m using your code in a project I’m currently working on. I’m creating a ajax page which allows the user to select an item in one list, and load all related items in 3 separate lists below it (without postbacks, which gets around scrolling problems when you have post backs).

    To accomplish that I’m using SPGridviews set in ascx controls, then called from a webpart ascx page.

    I’ve been able to do everything (including altering your code to use an SP List as the data source). The problem I’m having is once I get to enabling multiple column functions. Currently I create my SPGridViews in the ascx code. When I switch from that to new SPGridViewProxy, my web part complains that the subsequent controls can’t find the first one to pass parameters from. I’m assuming this is some sort of lifecycle problem – that the SPGridviewProxy doesn’t exist early enough in the lifecycle for the webpart to grab the parameters.

    Do you have any advice for this situation? Is it possible to call SPGridView from the ascx side (sorry for the ignorance, I’m still getting used to asp.net).

    It is easy to use a list as the datasource for this btw – I can send you that code if helpful.

    Best,
    Drew

  57. 57 Erik Burger

    Hi Drew,

    Firstly, great that you are using my code in such an ambitious project and that you are finding it useful (and functional, which is a plus).

    You should be able to call SPGridView from the ascx side but if this is indeed a lifecycle issue then it would be an idea to try creating it from code-behind. I have a very simple approach when I suspect lifecycle issues; I simply override all lifecycle methods and put breakpoints in them. It’s a bit tedious but this way you can check the existence of every one of your controls at every stage of the lifecycle. I’d start there.

    It’d be extremely helpful if you could send the code for making ASPGridView work with an SPList. If it is not a huge chunk of code you can also post it as a comment, perhaps in the first article? I’ve gotten a lot of questions about this but don’t have the time to whip up a proper post..putting it in a comment will at least help out people who are trying to Google the answer 🙂

    Thanks and best regards,

    Erik

  58. 58 Aman

    Hi Erik,

    I am using an Item Template and making Name column as Hyperlink…..everything works fine but on Filtering filterimage is not getting displayed….could you please provide me some solution on it

    thanks,
    Aman

  59. 59 Erik Burger

    Hi Aman,

    I wish I could help but unfortunately I don’t know the answer to your problem. Could it be that the hyperlink is actually overriding the filterImage? If you go into the web page source, is the image at all there or is it not? These are things I would check out first, then use the debugger to see what’s happening in Visual Studio.

    Erik

  60. 60 Gary

    Dear Erik,

    I just came across this post today and i can say the solution is amazing. However i can see that when i apply filter the filter icon does not appear and also when i clear the filter, it clears it across all the columns. Please advise if you have an updated version of the proxy that solves these issues. Can you kindly share it with me?

    Cheers –
    Gary

Leave a Reply


*