Auto Suggestion/Auto Complete for SharePoint 2010 Search sites

Introduction:

It will be very useful for the users to have the search being suggested based on the past searches while they are typing in the search text box in a SharePoint search site. Yes I’m talking about the same concept that you find in the Google search but with a limited functionality.

This feature is available as an OOTB feature in SharePoint 2013 enterprise search. Look at this link to know more about this cool feature. The process is completely different though.

Description:

This is a simple JavaScript application which when added to a Content editor web part in home page and in the search results page of your SharePoint search site would display suggestions for the users as they type their search query in the search text box. The suggestion keywords are stored and retrieved from a SharePoint custom list called “Search Keywords”. Look at the below screenshot for a better understanding:

As you can see in the above image, as I type “I love s”, I get “I love SharePoint” and “I love Silverlight” as suggestions. These 2 are retrieved from a SharePoint list called “Search Keywords”.

So how and when are these suggestion keywords stored in the “Search Keywords” list? When a user is searching in the search site and the results page finished loading, the JS code added in the CEWP in the results page would add the search query in the “Search Keywords” list as new list item. Thus the matching suggestion keywords are retrieved from the list as the user is typing in the search text box later.

Limitations:

Since the suggestion keywords are added to a SharePoint list as a new list item every time a user searches, the performance may reduce when 1000’s of items get stored in the list. So it is advised to manually delete few keywords often from the list.

Code:

The code is developed using JavaScript, jQuery, Autocomplete jQuery ui widget, and SharePoint Client object model. There are 2 different JavaScript codes. One is for the search home page and the other is for the search results page.

I have explained the code in two parts in the below blog posts:

Part 1: How to give the Auto suggestion/complete functionality to the Search box with search terms retrieved from a SharePoint list.

Part 2: How to store the users’ searched queries to a SharePoint list dynamically and then show them as suggestions in the search box while searching.

Since it is purely a client side application, we can simply deploy it by just moving the files. I assume that you have worked with Content editor web part before. You need to create 2 CEWPs, one for search home page and the other for the search results page. I have explained the deployment process through the below steps:

Deployment process:

  1. Download the SPAutosuggestion.zip file and unzip it.
  2.  Create a folder called SPAutosuggestion under the layouts folder of your SharePoint server.
  3. Copy the files jquery-1.7.js, jquery.ui.autocomplete.js, jquery.ui.core.js, jquery.ui.complete.js, jquery.ui.widget.js, and jquery-ui.CSS from the unzipped folder in to the above create folder.
  4. Go to your SharePoint search site and create a list called “Search Keywords”
  5. Go the search home page and edit the page.
  6. Add a Content editor web part in to the page.
  7. Click on “Click here to add new content” as shown in the below image:  
  8. Now in the ribbon control click on HTML -> Edit HTML Source as shown below:  
  9. In the HTML source editor window copy the content of the AutoSuggectionLandPage.js which would be present in the folder unzipped in step 1.
  10. Click on “Save & Close” under the page tab in the top ribbon.
  11. Go to the search results page of you SharePoint site and edit it.
  12. Repeat step 6 to 10. But instead of copying the content of AutoSuggectionLandPage.js, copy the content of AutoSuggestionResultsPage.js.
  13. Search with different queries twice or thrice to see them getting suggested as you type in the search text box.

Auto Complete/Suggestion in SharePoint 2010 Search Text box with jQuery – Part 2

As I told, here is the second part of the Auto Complete/Suggestion functionality in SharePoint 2010 Search Text box using jQuery. The first post can be found here.

In this blog post I will explain how to attach the auto complete/suggestion functionality to the search text box in the results page of the Search site. Also, we will see how to add the search query into the Search Keywords list so that the suggestion terms need not be added manually by the users. The code implemented here would be used in the search results page.

UPDATE: I have published this application here in CodePlex as well blogged about it briefly over here about the functionality as well as the deployment steps. Check it out if you do not want to get in to the coding side.

I’m going to explain only the modifications that I have done to the code in the previous post.

1. Modify the onQuerySucceeded function as shown below. I have described the code in comments


function onQuerySucceeded(sender, args) {
   listItemEnumerator = collListItem.getEnumerator();
   // declare a bool variable which we will use later
   termPresent = false;
   // get the query string value of key 'k' which has the search query and store in a variable
   // after decoding it
   srchTerm = decodeURI(JSRequest.QueryString["k"]);
   while (listItemEnumerator.moveNext()) {
       oListItem = listItemEnumerator.get_current();

   // check if the value in the Title columns in equal to search query
   // by converting them in to lowercase
   if( oListItem.get_item('Title').toLowerCase() == srchTerm.toLowerCase())
   {
      // if they are equal then change the value of the bool variable to true
      // which means the search query need not be added to the Search Keywords list
      termPresent = true;
   }
   listItemInfo += ',' + oListItem.get_item('Title');
 }

   $(".ms-sbplain").autocomplete({
   source: listItemInfo.split(",")
   });

   // check the value of the bool variable, if it is false then call the createListItem function
   // which will add the list item to the Search Keywords list
  if(termPresent == false)
  {
    createListItem(srchTerm);
  }
 }

2. Create the createListItem function with the below code.

function createListItem(srchTerm)
 {
   // create a new list item to be added in the Search Keywords list
   itemCreateInfo = new SP.ListItemCreationInformation();
   // add the item to the oList which is the Search Keywords list
   this.oListItem = oList.addItem(itemCreateInfo);
   // set the value of the title column of the list item to the search query
   oListItem.set_item('Title', srchTerm);
   // update the the list item
   oListItem.update();
   // load the list item
   clientContext.load(oListItem);
   // declare the delegates to be executed on success and on failure
   clientContext.executeQueryAsync(Function.createDelegate(this, this.onCreateSucceeded), Function.createDelegate(this, this.onQueryFailed));
 }

3. Create an empty onCreateSucceeded function.

function onCreateSucceeded() {
 // just an empty function
 }

Here is the complete code without comments.

<script type="text/javascript" src="/_layouts/SPAutoSuggestion/jquery-1.7.js"></script>
<script type="text/javascript" src="/_layouts/SPAutoSuggestion/jquery.ui.core.js"></script>
<script type="text/javascript" src="/_layouts/SPAutoSuggestion/jquery.ui.widget.js"></script>
<script type="text/javascript" src="/_layouts/SPAutoSuggestion/jquery.ui.position.js"></script>
<script type="text/javascript" src="/_layouts/SPAutoSuggestion/jquery.ui.autocomplete.js"></script>
<link href="/_layouts/SPAutoSuggestion/jquery-ui.CSS" rel="stylesheet" type="text/css" />

<script type="text/javascript">
JSRequest.EnsureSetup();
var clientContext;
var oList;
var camlQuery;
var listItemInfo = '';
var listItemEnumerator;
var termPresent;
var srchTerm;
var oListItem;
var itemCreateInfo;

$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(Post_COM_Load, "sp.js");
});

function Post_COM_Load() {
clientContext = new SP.ClientContext.get_current();
oList = clientContext.get_web().get_lists().getByTitle('Search Keywords');

camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View/>');
this.collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem, 'Include(Title)');
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded(sender, args) {

listItemEnumerator = collListItem.getEnumerator();

termPresent = false;

srchTerm = decodeURI(JSRequest.QueryString["k"]);
while (listItemEnumerator.moveNext()) {
oListItem = listItemEnumerator.get_current();
if( oListItem.get_item('Title').toLowerCase() == srchTerm.toLowerCase())
{
termPresent = true;
}
listItemInfo +=
',' + oListItem.get_item('Title');
}

$(".ms-sbplain").autocomplete({
source: listItemInfo.split(",")
});

if(termPresent == false)
{
createListItem(srchTerm);
}
}

function createListItem(srchTerm)
{
itemCreateInfo = new SP.ListItemCreationInformation();
this.oListItem = oList.addItem(itemCreateInfo);
oListItem.set_item('Title', srchTerm);
oListItem.update();
clientContext.load(oListItem);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onCreateSucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onCreateSucceeded() {
}

function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
</script>

4. The above code has to be added to a Content Editor Web Part in the results page of your Search site.

5. After you do a search with a query text, for example “Microsoft SharePoint” in your search site.

you can see that the query text has been added in the Search Keywords list as shown below

which would also eventually appear in the suggestions list as you type in your search text boxes as shown below.

Auto Complete/Suggestion in SharePoint 2010 Search Text box with jQuery- Part 1

Can’t get myself out of exploring jQuery in SharePoint. Last week I was working on how to bring in the Google kind of auto suggestion/complete functionality in to SharePoint 2010 Search text box using jQuery. I will be explaining it in 2 parts on how to achieve this functionality.

UPDATE: I have published this application here in CodePlex as well  as blogged about it briefly over here about the functionality as well as the deployment steps. Check it out if you do not want to get in to the coding side.

Part 1: How to give the Auto suggestion/complete functionality to the Search box with search terms retrieved from a SharePoint list. (You shall use the code implemented here if you want to store the search suggestion content in the SharePoint list by yourself)

Part 2: How to store the users’ searched queries to a SharePoint list dynamically and then show them as suggestions in the search box while searching.

Let me cover the first part in this blog post:

I have used jQuery and the jQuery Autocomplete plug-in to show the suggestion in the search text box.

1. Download the jQuery plug-in form here

2. Download the  jQuery UI plug-in from here.

Note: We need only the Autocomplete functionality of the jQuery UI. So you need to have only the following options selected in the list of functionalities shown in the above URL before downloading:

  • Core
  • Widget
  • Mouse
  • Position
  • Autocomplete
  • Menu

3. Create a folder called SPAutoSuggestion in the Layouts folder.

4. Unzip the above download zip files. Copy all the JS files(not the folders) in to the above created folder.

5. Create a Custom list called “Search Keywords” in your SharePoint Enterprise Search centre site and add some list items in to the list with sample keywords that you would like to appear as suggestions in the Search text box.

4. Open the home page of your Search site. Go to Site Actions and click Edit page to edit the page.

5. Click on Add a Web Part above the Search box and add a Content Editor Web Part as shown below.

6. After adding the web part, click below the web part in order to edit the HTML source as shown in the below figure to open the content editor of the web part.

7. In the content editor add the below script tags referring the jQuery plugins:

<script type="text/javascript" src="/_layouts/SPAutoSuggestion /jquery-1.9.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.core.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.widget.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.position.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.autocomplete.js"></script>
<link href="/_layouts/SPAutoSuggestion/jquery-ui.CSS" rel="stylesheet" type="text/css"/>

Note: You may have to change the jQuery version number in the first line based on the jQuery version that you download also make sure the all the files referred are their in the correct path.

8. Now let us start writing the JavaScript code. This JS code will  retrieve the keywords to be suggested from the Search Keywords list through ECMA script Client Object Model and store it in an array.

<script type="text/javascript">
JSRequest.EnsureSetup();
//declare the variable that are going to be used though out the code

var clientContext;
var oList;
var camlQuery;
var listItemInfo=’‘;
var listItemEnumerator;

$(document).ready(function () //executes the function inside after the page finishes loading completely
{
// loads the sp.js file that contains the client object model script and then executes the Post_COM_Load function.
ExecuteOrDelayUntilScriptLoaded(Post_COM_Load, "sp.js");
});

9. Below function is the Post_COM_Load function which retrieves the keywords from the Search Keywords list.

function Post_COM_Load() {
//gets the context of the current site which is our Search center
clientContext = new SP.ClientContext.get_current();
//gets the list by title 'Search Keywords' where we have stored all the keywords
oList = clientContext.get_web().get_lists().getByTitle('Search Keywords');

//camlQuery variable will store the CAML query using which we would retrieve the keywords from the list.
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View/>');
//collListItem will store the list items retrieved form the Search Keywords list.
this.collListItem = oList.getItems(camlQuery);
//populate the collListItem with values from the Title column in the Search Keywords list.
clientContext.load(collListItem, 'Include(Title)');

//execute the onQuerySucceeded function if data gets loaded successfully and execute the onQueryFailed if it failed to load the data
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

10.  Add the below script for onQuerySucceeded.

function onQuerySucceeded(sender, args) {
listItemEnumerator = collListItem.getEnumerator();
//looping through collListItem list item collection and storing each value into an array called listItemInfo separated by a comma
while (listItemEnumerator.moveNext()) {
oListItem = listItemEnumerator.get_current();
listItemInfo +=
',' + oListItem.get_item('Title');
}

//bind the Autocomplete functionality to an search textbox whose class name is .ms-sbplain by passing the array as the parameter.
$(".ms-sbplain").autocomplete({
source: listItemInfo.split(",")
});
}
11. Add the below script for onQueryFailed function
function onQueryFailed(sender, args) {
//when the request to load the has failed the error message will be displayed in an alert.
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

12. Click OK in the content editor and click Save & Close in the top ribbon.

13. Now, when you start typing in the search text box, the suggestions would appear from the Search keywords list based on what you are typing as shown below.

Here is the complete code without any comments:

<script src="/_layouts/SPAutoSuggestion/jquery-1.7.js" type="text/javascript"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.core.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.widget.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.position.js"></script>
<script src="/_layouts/SPAutoSuggestion/jquery.ui.autocomplete.js"></script>
<link href="/_layouts/SPAutoSuggestion/jquery-ui.CSS" rel="stylesheet" type="text/css"/>
<script type="text/javascript">
JSRequest.EnsureSetup();

var clientContext;
var oList;
var camlQuery;
var listItemInfo='';
var listItemEnumerator;

$(document).ready(function()
{
ExecuteOrDelayUntilScriptLoaded(Post_COM_Load,"sp.js")
});

function Post_COM_Load(){
clientContext = new SP.ClientContext.get_current();
oList = clientContext.get_web().get_lists().getByTitle('Search Keywords');
camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View/>');
this.collListItem=oList.getItems(camlQuery);
clientContext.load(collListItem,'Include(Title)');
clientContext.executeQueryAsync(Function.createDelegate(this,this.onQuerySucceeded),
Function.createDelegate(this,this.onQueryFailed))
}

function onQuerySucceeded(sender,args){
var listItemEnumerator = collListItem.getEnumerator();
while(listItemEnumerator.moveNext()){
oListItem = listItemEnumerator.get_current();
listItemInfo+=','+oListItem.get_item('Title')}
$(".ms-sbplain").autocomplete({source:listItemInfo.split(",")})
}
function onQueryFailed(sender,args){
alert('Request failed. '+args.get_message()+'\n'+args.get_stackTrace())
}
</script>

Retrieving the Best Bets for SharePoint search programmatically based on a Search query

I have got a requirement to develop a Best Bets web part for SharePoint People Search as the default Search Best Bets does not work for People search. Well, will update on that later.

When I was looking for code on how to read the Best bets for a site programmatically I got it from this blog post. In this post I have enhanced that coding in order to filter the best bets collection by keywords term and synonyms term based on a search query using LINQ queries. Explanations are given in comments.

You need to have these 2 namespaces for LINQ query and IEnumerable collection that we are going to use.

using System.Linq;
using System.Collections.Generic;

Here is the complete code.

using (SPSite site = new SPSite("http://SharePointSite/"))
            {
                // get the proxy for the search service application
                    SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.
       GetProxy(SPServiceContext.GetContext(site));

                //get the Keywords collection for the site
                    Keywords keywords = new Keywords(proxy, new Uri(site.Url));

                //filter the keywords collection with Linq query and store it in an IEnumerable collection
                    IEnumerable<Keyword> Keywords = from Keyword keyword in keywords.AllKeywords
                                                    where keyword.Term.ToLower() == srchQuery.ToLower()  //checking for the terms equal to the search query
                                                    ||
                                                    (from Synonym c in keyword.Synonyms
                                                     where c.Term.ToLower() == srchQuery.ToLower()  // checking if synonyms are present for the search query
                                                     select c).Count() > 0

                                                    select keyword;

                    // loop through each keyword from the above collection
                    foreach (Keyword keyword in Keywords)
                    {
                        Console.WriteLine(keyword.Term);
                        foreach (BestBet bet in keyword.BestBets)
                        {
                            Console.WriteLine("\t{0} ({1})", bet.Title, bet.Url);
                        }
                    }
                }