Tuesday, July 26, 2011

Adding Telerik RAD ToolTips to Your SharePoint Search Results

We have heavily customized Search results in MOSS 2007. We wanted to present a tooltip pop-up when the users hover over each result. We have XSLT search result templates for various types of results including clients and people. For example purposes, I will explain using the people results.


Each result on the search results page has an ID that contains CoreResultListItem. This is set in the search results XSLT. The first thing that needs to be done is to insure that the search results template has a  <div> running at the server.
<div runat="server" class="people" id="{concat('CoreResultListItem',id)}" accountname="{accountname}" >

Since I am dealing with multiple types of results together, I set the class="people" so I know its a person. Next I use an identifying field so I know which person to display the information about. Here I am using {accountname} which is one of the managed properties for people results.

Once that is in place, I created a non visual web part that will sit on the search results page and handle the "tooltipification". The main method I created was AddControls loops through the search results and adds the tooltip to each result using an ASCX User Control. This user control displays information about the person as the accountname will be passed into the control. This control runs separate from the web part (see examples on the Telerik RAD Controls site if you need more info).

A condensed version is shown here:

 private void AddControls(ControlCollection page)
{
   foreach (Control c in page)
    {
     if (c.ClientID != null)
      {
        if (c.ClientID.Contains("CoreResultListItem"))
        {
           RadToolTip tooltip = new RadToolTip();
           tooltip.ShowEvent = ToolTipShowEvent.OnMouseOver;
           tooltip.TargetControlID = c.ClientID;
           tooltip.IsClientID = true;
           tooltip.ID = "RadToolTip" + c.ID;
           tooltip.HideEvent = ToolTipHideEvent.LeaveToolTip;
 
           switch ((c as HtmlGenericControl).Attributes["Class"])
          {
                case "people": //Person

                 Control ctrlPerson = Page.LoadControl("~\\UserControls\\PublicContactCardSearch.ascx");
                PublicContactCardSearch.PublicContactCardSearch detailsPerson =
                             (PublicContactCardSearch.PublicContactCardSearch)ctrlPerson;
                if ((c as HtmlGenericControl).Attributes["accountname"] != null)
               {
                    if ((c as HtmlGenericControl).Attributes["accountname"] != string.Empty)
                   {
                         detailsPerson.ADAccount = (c as HtmlGenericControl).Attributes["accountname"];
                         tooltip.Controls.Add(ctrlPerson);
                        c.NamingContainer.Controls.Add(tooltip);
                    }
               }
               break;
     
         case "client": //Client           
                     .... SIMILIAR CODE FOR EACH TYPE OF RESULT

          }
       }
     }
     if (c.HasControls())
     {
           AddControls(c.Controls);
     }
    }
}

I then call this in the CreateChildControls method:

AddControls(Page.FindControl("ctl00").Controls);

The "ctl00" is the master page so I pass in the controls collection of the master page. The AddControls method is recursive which isn't favorable but was the only way I could get to the search result items.

When switching search results pages using the paging, I noticed the tooltips were showing from the orignal page. Therefore I needed to make sure that the control states were clear:

ClearChildControlState();
ViewState.Clear();

I used both of these in the Page_Load and the ClearChildControlState() in the Render method as well.

The results (although my picture looks goofy):






If you found this useful, please help support my SharePoint and .NET user group (Philly SNUG) by clicking on the logo below.