SharePoint: Filter a List Dynamically

SharePoint: Filter a List Dynamically

How do you filter a list based on a parameter entered by the user?
For that we have the default “TextFilter” webpart, but this webpart has two flaws:

First you need the Enterprise version of SharePoint 2010, then this webpart only use the “equal to” and not the “contains” (when all the requests I have personally been asked a “contains”).

I’ll show you a code snippet to add used in a webpart to give your users the ability to filter your lists.

The idea is to load a “ListViewWebPart” of the targeted list.

 
string listUrl = "Lists/maliste" ; 
SPList list = web.GetList(SPUrlUtility.CombineUrl(web.Url, listUrl)); 
ListViewWebPart lvwp = new ListViewWebPart(); 
lvwp.ListName = list.ID.ToString("B").ToUpper(); 
lvwp.ViewGuid = list.Views[YourCustomViewName].ID.ToString("B").ToUpper(); 
this.Controls.Add(lvwp); 

With this code snippet, you will display the list on the url “listUrl” with the view whose name is equal to “YourCustomViewName”

If you want to display the default view, replace the line

 lvwp.ViewGuid = list.Views[YourCustomViewName].ID.ToString("B").ToUpper(); 

by

 lvwp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper(); 

For the filter, we will use two TextBox, one for the column “LinkTitle” and one for the column “FirstName” and a filter button. The trick will be to create a CAML Query and injecting it in the selected view.

Warning, if the selected view is already filtered, the existing filter will be replaced. In other words if you have a filtered list of column C, if you use the following code snippet, it will not be filtered on column C but on columns A and B.

Let’s start by creating our request.

 
string query = string.Empty; 
string tempAdding = string.Empty; 
if (!string.IsNullOrEmpty(tbA.Text)) 
{ 
query = <Contains><FieldRef Name='A' /><Value Type='Text'>" + tbA.Text + "</Value></Contains>; 
} 
if (!string.IsNullOrEmpty(tbB.Text)) 
{ 
tempAdding = <Contains><FieldRef Name='B' /><Value Type='Text'>" + tbB.Text + "</Value></Contains>; 
query = (query.Length > 0 ? "<And>" + query + tempAdding + "</And>" : tempAdding); 
} 

Now we will inject the query! For this we will go through the xml view to find the tag “Where” where we will replace the existing query with the new.

 
XmlDocument doc = new XmlDocument(); 
doc.LoadXml(lvwp.ListViewXml); 
XmlNode queryNode = doc.SelectSingleNode("//Query"); 
XmlNode whereNode = queryNode.SelectSingleNode("Where"); 
if (whereNode != null) queryNode.RemoveChild(whereNode); 
XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "Where", String.Empty); 
newNode.InnerXml = query.ToString(); 
queryNode.AppendChild(newNode); 
lvwp.ListViewXml = doc.OuterXml; 

We just have to put it all in one update panel and there you are with a custom filter webpart!

Feel free to go further and put the url of the list, the view and fields in the webpart’s parameters for a filter webpart as generic as possible!

Finally here is the complete code of my webpart.

 

 public class WebPart1 : System.Web.UI.WebControls.WebParts.WebPart
    {
        TextBox tbA;
        TextBox tbB;
        Button filterButton;
        UpdatePanel mainUpdatePanel;
        ListViewWebPart lvwp;
        SPList list;

        protected override void CreateChildControls()
        {

            mainUpdatePanel = new UpdatePanel();
            mainUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;

            tbA = new TextBox();
            tbB = new TextBox();

            list = SPContext.Current.Web.GetList(SPUrlUtility.CombineUrl(SPContext.Current.Web.Url, "Lists/FilterList"));
            lvwp = new ListViewWebPart();
            lvwp.ListName = list.ID.ToString("B").ToUpper();
            lvwp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();
            lvwp.ChromeType = PartChromeType.None;



            filterButton = new Button();
            filterButton.Text = "Filter";
            filterButton.Click += new EventHandler(filterButton_Click);



            Controls.Add(new LiteralControl(" Nom : "));
            Controls.Add(tbA);
            Controls.Add(new LiteralControl(" Prenom : "));
            Controls.Add(tbB);
            mainUpdatePanel.ContentTemplateContainer.Controls.Add(filterButton);
            mainUpdatePanel.ContentTemplateContainer.Controls.Add(lvwp);


            this.Controls.Add(mainUpdatePanel);
        }

        private void filterButton_Click(object sender, EventArgs e)
        {
            string query = string.Empty;
            string tempAdding = string.Empty;
            if (!string.IsNullOrEmpty(tbA.Text))
            {
                query = "<Contains><FieldRef Name='LinkTitle' /><Value Type='Text'>" + tbA.Text + "</Value></Contains>";
            }
            if (!string.IsNullOrEmpty(tbB.Text))
            {
                tempAdding = "<Contains><FieldRef Name='Prenom' /><Value Type='Text'>" + tbB.Text + "</Value></Contains>";
                query = (query.Length > 0 ? "<And>" + query + tempAdding + "</And>" : tempAdding);
            }

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(lvwp.ListViewXml);
            XmlNode queryNode = doc.SelectSingleNode("//Query");
            XmlNode whereNode = queryNode.SelectSingleNode("Where");

            if (whereNode != null) queryNode.RemoveChild(whereNode);
            XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "Where", String.Empty);
            newNode.InnerXml = query.ToString();
            queryNode.AppendChild(newNode);
            lvwp.ListViewXml = doc.OuterXml;

        }

With some modifications you can change this code to apply it for different scenarii as filter on current user, on current current user groups, on url parameter , etc...

For specific sample, you can check the msdn posts where this question was asked :

Initial post : http://christopherclementen.wordpress.com/2012/04/02/filter-a-list-dynamically/

Hope this helps!
Christopher.

See Also

An important place to find a huge amount of SharePoint related articles is the TechNet Wiki itself. The best entry point is
 SharePoint Resources on the TechNet Wiki


Sort by: Published Date | Most Recent | Most Useful
Comments
  • Hi Christopher.   As far as I have understood , we are supposed to link to solutions that we have provided as answers to a forum question, not articles from our blogs.

  • Hello Bjoern,

    Well, according to the topic social.technet.microsoft.com/.../17327.technet-guru-contributions-may.aspx ,  "The articles must be written in May 2013 and must be in English. However, the original blog or forum content can be from before May. " . Since I made this one in answer to a forum question, I think it's good. If not..let's take it as my first real wiki contribution :)

  • I've updated this with the From Forum tag as it originated from within them.

  • Christopher, that's right. We're including original content from blogs, because the truth is that we often post answers out on a blog and then link in the forum thread out to the blog. So it's similar community content in that way (which is why blog content is part of the TechNet Guru competition). Either way, the goal is to get a lot of this content onto the Wiki so that we can build on it and cross-link between these pages, making it easier for people to find these answers. Oh, I also removed the introduction that personalized it a bit, since that's part of the Wiki guidelines (the "voice" is more factual, like other Wikis). Thanks! This is exactly the kind of content that more people should read!

  • Thanks for the update Ed!

  • I was looking some sort of this, i will try implementing it

Page 1 of 1 (6 items)