Quantcast
Channel: SharePoint Config
Viewing all articles
Browse latest Browse all 18

SharePoint 2010 People Directory Part 3 – Sorting

$
0
0

I’ve had several requests to show how to implement sorting following my previous posts on creating a simple SharePoint 2010 people directory and using a table based layout for a SharePoint 2010 people directory. This post shows how to implement custom sorting for the people directory so you can sort by first name, last name or any other managed property.

sharepoint-people-directory-sort

Step 1: Extend the search core results web part to support sorting

There are two search core results web parts that are capable of displaying list of people:

  • Search Core Results – provides a generic way of displaying search results and supports sorting by relevance and modified date
  • People Search Core Results – provides additional people based information in search results and supports sorting by relevance, social distance and name (a-z only)

As both the web parts only allow a fixed set of sorting options we need to create a new web part if we want to provide sorting options such as by last name or by first name (z-a). The easiest way to do this is to inherit from an existing web part and as the people search core results is sealed we can only do this by inheriting from the search core results web part.

One benefit of using the search core results web part is that we are not limited to displaying lists of people. We can use this web part to display sortable lists of documents, list items, sites or any other information in the search index. This is a very useful technique for aggregating content from across several site collections or across a large number of sites where web parts such as the content query web part run into performance problems (in fact SharePoint 2013 introduces the content by search web part which is based on the same principals we use here).

In the class that extends the search core results web part we can add code that changes the order by clause of the search query. Bart-Jan Hoeijmakers has an excellent post on Creating a sortable CoreResultsWebPart in SharePoint 2010 that shows how to do this. I’ve extended his web part in the example below to changes the sort order based on query string parameters, or properties of the web part if there are no parameters passed in.

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.Office.Server.Search.WebControls;
using Query = Microsoft.Office.Server.Search.Query;

namespace Ari.SharePointSearch.WebParts
{
    [ToolboxItemAttribute(false)]
    public class SortableCoreResults : CoreResultsWebPart
    {
        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [WebDisplayName("Default managed property")]
        [WebDescription("Sort by this managed property by default")]
        [Category("Sorting Properties")]
        public string OrderByProperty { get; set; }

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [WebDisplayName("Default direction")]
        [WebDescription("Default sorting direction")]
        [Category("Sorting Properties")]
        public Microsoft.Office.Server.Search.Query.SortDirection SortDirection { get; set; }

        /// <summary>
        /// Runs the base configuration then adds a custom sort property
        /// </summary>
        protected override void ConfigureDataSourceProperties()
        {
            // only run when we are showing search results (e.g. not the search action links)
            if (this.ShowSearchResults)
            {
                try
                {
                    // run the base code
                    base.ConfigureDataSourceProperties();

                    // get the sorting parameters off the query string
                    string orderByProperty = this.Context.Request.QueryString["v1"];
                    string sortDir = this.Context.Request.QueryString["SortDir"];

                    // if none set use the defaults
                    if (string.IsNullOrEmpty(orderByProperty))
                        orderByProperty = OrderByProperty;

                    Query.SortDirection sortDirection = SortDirection;

                    if (!string.IsNullOrEmpty(sortDir) && sortDir.ToLower() == "desc")
                        sortDirection = Query.SortDirection.Descending;
                    else if (!string.IsNullOrEmpty(sortDir) && sortDir.ToLower() == "asc")
                        sortDirection = Query.SortDirection.Ascending;

                    CoreResultsDatasource dataSource = this.DataSource as CoreResultsDatasource;

                    // if we have an orderByProperty then modify the search query sort order
                    if (!string.IsNullOrEmpty(orderByProperty))
                    {
                        dataSource.SortOrder.Clear();
                        dataSource.SortOrder.Add(orderByProperty, sortDirection);
                    }
                }
                catch (Exception ex)
                {
                    // implement exception handling here
                }
            }
        }

        protected override void ModifyXsltArgumentList(Microsoft.SharePoint.WebPartPages.ArgumentClassWrapper argList)
        {
            base.ModifyXsltArgumentList(argList);

            // add a parameter with the current URL
            argList.AddParameter("CurrentUrl", string.Empty, HttpContext.Current.Request.Url.PathAndQuery);
        }
    }
}

This web part now lets us set a default sort option by passing in parameters on the query string. For example if we load the page the web part is on with parameters such as peopledirectory.aspx?v1=LastName&SortDir=asc the web part will sort the results by last name A-Z.

We can also set the default sorting option by using the sorting properties that are shown when editing the web part. This will be used to sort the results when the query string parameters are not present.

sharepoint-search-results-sorting-properties

Step 2: Extend the search results XSLT to render additional sorting options

sharepoint-people-directory-sort-dropdown The second step is to change the XSLT that renders the sort by drop down to include additional sorting options. When a different sort option is selected the property and the direction (i.e. ascending or descending) will be passed on the query string to the core results web part we created in step 1.

I’ve included an example of how to add first name and last name sorts both ascending (a-z) and descending (z-a) below:

        <xsl:if test="$ShowDropDown = 'true'">
          <xsl:value-of select="$SortBy" />
          <select id="dropdown" title="{$SortOptions}" onchange="PostToUrl(this.value)" class="srch-dropdown">
            <xsl:call-template name="AddSortOption">
              <xsl:with-param name="DisplayName">First name (A-Z)</xsl:with-param>
              <xsl:with-param name="ManagedProperty">FirstName</xsl:with-param>
              <xsl:with-param name="Direction">Asc</xsl:with-param>
            </xsl:call-template>
            <xsl:call-template name="AddSortOption">
              <xsl:with-param name="DisplayName">First name (Z-A)</xsl:with-param>
              <xsl:with-param name="ManagedProperty">FirstName</xsl:with-param>
              <xsl:with-param name="Direction">Desc</xsl:with-param>
            </xsl:call-template>
            <xsl:call-template name="AddSortOption">
              <xsl:with-param name="DisplayName">Last name (A-Z)</xsl:with-param>
              <xsl:with-param name="ManagedProperty">LastName</xsl:with-param>
              <xsl:with-param name="Direction">Asc</xsl:with-param>
            </xsl:call-template>
            <xsl:call-template name="AddSortOption">
              <xsl:with-param name="DisplayName">Last name (Z-A)</xsl:with-param>
              <xsl:with-param name="ManagedProperty">LastName</xsl:with-param>
              <xsl:with-param name="Direction">Desc</xsl:with-param>
            </xsl:call-template>
          </select>
        </xsl:if>

This relies on a couple of helper templates to create the hyperlink containing the relevant query string parameters. These templates are shown below:

  <xsl:template name="AddSortOption">
    <xsl:param name="DisplayName"/>
    <xsl:param name="ManagedProperty"/>
    <xsl:param name="Direction"/>

    <xsl:variable name="UrlWithSortProperty">
      <xsl:call-template name="ReplaceQsParameter">
        <xsl:with-param name="URL" select="$CurrentUrl"/>
        <xsl:with-param name="ParamName">v1=</xsl:with-param>
        <xsl:with-param name="ParamValue" select="$ManagedProperty"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="UrlWithSortAndOrderProperties">
      <xsl:call-template name="ReplaceQsParameter">
        <xsl:with-param name="URL" select="$UrlWithSortProperty"/>
        <xsl:with-param name="ParamName">SortDir=</xsl:with-param>
        <xsl:with-param name="ParamValue" select="$Direction"/>
      </xsl:call-template>
    </xsl:variable>

    <option value="{$UrlWithSortAndOrderProperties}">
      <xsl:if test="$UrlWithSortAndOrderProperties = $CurrentUrl">
        <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      <xsl:value-of select="$DisplayName"/>
    </option>

  </xsl:template>

  <xsl:template name="ReplaceQsParameter">
    <xsl:param name="URL"/>
    <xsl:param name="ParamName"/>
    <xsl:param name="ParamValue"/>
    <xsl:choose>
      <xsl:when test="contains($URL, $ParamName)">
        <xsl:variable name="Before" select="substring-before($URL, $ParamName)"/>
        <xsl:variable name="After" select="substring-after(substring-after($URL, $ParamName), '&amp;')"/>
        <xsl:choose>
          <xsl:when test="$After = ''">
            <xsl:value-of select="concat($Before, $ParamName, $ParamValue)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat($Before, $ParamName, $ParamValue, '&amp;', $After)"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:when test="contains($URL, '?')">
        <xsl:value-of select="concat($URL, '&amp;', $ParamName, $ParamValue)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat($URL, '?', $ParamName, $ParamValue)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

I’ve also modified the XSLT to display the results in a table based layout as per my previous post on creating a SharePoint 2010 people directory with a table based layout.

If you want the complete code packaged up you can download the solution package for the search core results web part. Note this is a farm solution as the search core results web part cannot be extended using a sandboxed solution.

Once you have deployed the solution the steps below can be used to add the sortable search results web part to a search results page:

  1. Assuming you have an enterprise search center set up the first step is to create a new search results page by selecting Site Actions > New Page.
  2. On the search results page delete the Search Core Results web part
  3. In the bottom web part zone click ‘Add a Web Part’ and select the ‘Sortable Core Results’ web part from the Search category
  4. Delete the Search Action Links web part
  5. In the middle lower right web part zone click ‘Add a Web Part’ and select the ‘Sortable Core Results’ web part
  6. Modify the sortable core results web part in the middle right zone and under the miscellaneous section deselect ‘show search results’ and select ‘show action links’sharepoint-search-show-action-links-property

You should now have a page that displays a list people with a drop down that allows users to sort by first name or last name A-Z or Z-A.

sharepoint-people-directory-sort

The example solution uses a table based layout but it is also possible to use a layout similar to the people search results by changing the XSLT file used to render the results.

Download the solution package for the search core results web part

Additional resources

SharePoint 2010 People Directory Part 3 – Sorting is a post from: SharePoint Config


Viewing all articles
Browse latest Browse all 18

Latest Images

Trending Articles





Latest Images