Tuesday, December 25, 2012

Connect Text Filter to List View with Wildcard Support



In a recent project, we were trying to add search/filter funcationality to a page to support search/filter a list view (XsltListViewWebPart). This is different from the SharePoint "Search", which will search either the entire site or a list and return the results in a search result page.

What we need is a search or filter that will search certain text in a list and make the list to show only items that match. After the search, user should be able to select the items in the list and trigger some actions on them.

The easiest way to achieve this is to use SharePoint Text Filter web part and connect it to a column in the XsltListViewWebPart. However this filter can only do exact match which make it not very useful as a search tool.

To have a Text Filter that can do wild card match or partial string match manually through SharePoint Designer, you can reference this link

http://coolsharepoint.blogspot.com/2012/03/sharepoint-2010-configure-textfilter-to.html#!/2012/03/sharepoint-2010-configure-textfilter-to.html

Another limit of Text Filter is that it can only connect to one column in the list, to do a search on multiple columns you can reference this article

http://gustavogarciadotnet.blogspot.com/2011/01/sharepoint-list-filter-wildcard-search.html

What I am going to show here is how to do all these programmatically. I didn't find anyone else have done this before. I did all these by reverse engineering what the SharePoint Designer does.



public static void SetTextFilterAndXsltViewWebPartConnection(SPWeb web, string pageUrl, string filterWebPartName, string gridWebPartName)
{
    SPFile file = web.GetFile(pageUrl);
    if (file == null && !file.Exists)
        return;
 
    if (file.CheckOutType != SPFile.SPCheckOutType.None)
        file.CheckIn("");
 
    file.CheckOut();
 
    try
    {
        SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
        if (webPartManager == null)
            return;
 
 
        System.Web.UI.WebControls.WebParts.WebPart filterwp = null;
        XsltListViewWebPart xsltwp = null;
 
        foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartManager.WebParts)
        {
            if (!string.IsNullOrEmpty(wp.Title) && wp.Title.ToLower() == filterWebPartName.ToLower())
            {
                filterwp = wp;
                continue;
            }
 
            if (!string.IsNullOrEmpty(wp.Title) && wp.Title.ToLower() == gridWebPartName.ToLower())
            {
                xsltwp = wp as XsltListViewWebPart;
                continue;
            }
        }
 
        SPWebPartConnection connection = new SPWebPartConnection();
        connection.ID = "custodianFilterConnection";
 
        connection.ConsumerConnectionPointID = "DFWP Parameter Consumer ID";
        connection.ConsumerID = xsltwp.ID;
 
        connection.ProviderConnectionPointID = "ITransformableFilterValues";
        connection.ProviderID = filterwp.ID;
 
        TransformableFilterValuesToParametersTransformer searchTransformer = new TransformableFilterValuesToParametersTransformer();
        searchTransformer.ConsumerFieldNames = new string[] { "SearchQuery" };
        searchTransformer.ProviderFieldNames = new string[] { "Search" };
 
        connection.SPTransformers.Add(searchTransformer);
 
        webPartManager.SPWebPartConnections.Add(connection);
 
        webPartManager.SaveChanges(xsltwp);
        webPartManager.SaveChanges(filterwp);
 
    }
    catch (Exception expt)
    {
        Console.WriteLine(expt.Message + expt.StackTrace);
    }
}
To have this solution work, there is another hurdle to overcome. You need to create the a view in the XsltListViewWebPart as described in my previous bloghttp://ethandeng.blogspot.com/2012/12/define-list-view-for.html
 

public static void SetXsltListViewCustomterView(SPWeb web, SPView view)
{
    //Create view
    //http://sarangasl.blogspot.com/2009/12/create-sharepoint-list-view.html
    string viewQuery = "<OrderBy><FieldRef Name=\"fullname\" /></OrderBy><Where><Contains><FieldRef Name=\"SearchableText\"/><Value Type=\"Text\">{SearchQuery}</Value></Contains></And></Where>";
            
    view.Query = viewQuery;
    view.ViewFields.DeleteAll();
    view.ViewFields.Add("fullname");
    view.ViewFields.Add("company");
    view.ViewFields.Add("status");
    view.ViewFields.Add("noticeTitle");
 
    view.Paged = true;
    view.RowLimit = 3;
    view.DefaultView = true;
 
    view.Update();
}

Reference:
http://stackoverflow.com/questions/1048736/web-part-connections-in-site-definitions





No comments:

Post a Comment