Create a SharePoint Contextual Search Box in a Content Editor Web Part

Update: I’ve posted a newer version of this solution that allows for multiple search boxes on the same page. The code is similar, but I highly recommend using the updated solution for better flexibility. View it here: http://joshmccarty.com/2011/05/sharepoint-contextual-search-updated/.

SharePoint provides a couple of ways to search on a web part page. First, the Master Page can include a search box which can be set to search within a specific context such as the entire site collection, the current site, or (if on a list view page) the current list or library. The other way to add a search box is to use the Search Box web part. This can also be set to search within a specific context by adjusting the web part settings.

However, in some cases this may not be a good option. For example one of my recent projects required adding a contextual search box on the home page of a site that would search a specific list within that site. The stakeholders wanted to have more control over the layout, so the search box could not be in a separate web part; it had to be included within some other content on the page. Fortunately this turns out to be fairly easy to do with a little JavaScript.

SharePoint uses a URL query string to deliver search results. For example, to search for the word “test” within the “projects” list on the current site, the URL would look like this:

http://server/site/_layouts/OSSSearchResults.aspx?k=test&cs=This%20List&u=http://server/site/lists/projects

The URL starts with the search results page (OSSSearchResults.aspx for MOSS 2007 and Standard/Enterprise 2010 or SearchResults.aspx for WSS 2003 and Foundation 2010 – update your code accordingly), which is in the “_layouts” virtual directory. The “k” parameter includes the search terms. Next the “cs” parameter specifies the context of the search (“This Site” or “This List”). Finally the “u” parameter specifies the location of the context (the site or list URL).

We can use JavaScript in combination with a text input field and a button to generate a URL query string for searching. First, create the text input field and button:

<input id="searchBox" type="text" name="searchBox" />
<input id="searchButton" type="button" name="searchButton" value="Search" />

Next, create a JavaScript function that will build the query string and navigate to the resulting search page. We also need to create a function to check for when the user presses the Enter key because our text input is not in its own web form (you can’t use <form> tags on SharePoint pages because the entire page is already a form). We’ll use three parameters for the search function:

  • type – specifies if the context is a site or a list
  • site – specifies the location of the current site
  • scope – specifies the location of the site or list that you wish to search
<script type="text/javascript">// <![CDATA[
	// Search for the terms when the Search button is clicked

	function customSearch(type,site,scope) {

		var searchUrl = site + "/_layouts/OSSSearchResults.aspx?" // Or "/_layouts/SearchResults.aspx?" if WSS 2003 or SP2010 Foundation
		var searchTerm = "&k=" + document.getElementById("searchBox").value;
		var listParams = "&cs=This%20" + type + "&u=" + scope;
		document.location.href = searchUrl + searchTerm + listParams;

	}

	// Initiate the customSearch function when the Enter key is pressed

	function searchKeyPress(e) {
		// look for window.event in case event isn't passed in
		if (window.event) { e = window.event; }
		if (e.keyCode == 13)
		{
			document.getElementById('searchButton').click();
		}
	}
// ]]></script>

Finally, add the appropriate functions to the onclick and onkeypress events, including the values for the search function:

<input id="searchBox" onkeypress="searchKeyPress(event);" type="text" name="searchBox" />
<input id="searchButton" onclick="customSearch( 'List', 'http://server/site', 'http://server/site/lists/projects' );" type="button" name="searchButton" value="Search" />

Now put it all together:

<script type="text/javascript">// <![CDATA[
	// Search for the terms when the Search button is clicked

	function customSearch(type,site,scope) {

		var searchUrl = site + "/_layouts/OSSSearchResults.aspx?"
		var searchTerm = "&k=" + document.getElementById("searchBox").value;
		var listParams = "&cs=This%20" + type + "&u=" + scope;
		document.location.href = searchUrl + searchTerm + listParams;

	}

	// Initiate the customSearch function when the Enter key is pressed

	function searchKeyPress(e) {
		// look for window.event in case event isn't passed in
		if (window.event) { e = window.event; }
		if (e.keyCode == 13)
		{
			document.getElementById('searchButton').click();
		}
	}
// ]]></script>

<input id="searchBox" onkeypress="javascript:searchKeyPress(event);" type="text" name="searchBox" />
<input id="searchButton" onclick="javascript:customSearch( 'List', 'http://server/site', 'http://server/site/lists/projects' );" type="button" name="searchButton" value="Search" />

The script can be reused on multiple pages/sites for multiple contexts. The only thing you need to change are the values passed to the function in the onclick event.

<input id="searchBox" onkeypress="searchKeyPress(event);" type="text" name="searchBox" />
<input id="searchButton" onclick="customSearch( '[Site or List]', '[URL of current site]', '[URL of list or site to search]' );" type="button" name="searchButton" value="Search" />

You can substitute your own values to customize the search for your site and/or list. Note that when providing the URLs for the site and scope parameters, don’t include a specific page or view; only include the root path to the site and/or list:

IncorrectCorrect
sitehttp://server/site/pages/default.aspxhttp://server/site
scopehttp://server/site/lists/projects/allitems.aspxhttp://server/site/lists/projects

Update: I’ve posted a newer version of this solution that allows for multiple search boxes on the same page. The code is similar, but I highly recommend using the updated solution for better flexibility. View it here: http://joshmccarty.com/2011/05/sharepoint-contextual-search-updated/.

25 thoughts on “Create a SharePoint Contextual Search Box in a Content Editor Web Part

  1. Thanks for this great post and simple solution, but I’m having an error when I try this: whenever I input text into the searchbox, and click the searchbutton, the SharePoint search returns an error message, and the input it searched for is always “undefined”. I’m assuming it’s not passing the text inputted into the searchbox, but I’m not sure how exactly.

    Any help would be much appreciated

  2. Alex, I just re-used this code on another site and it worked without any problems. Try manually entering the search query string (replace this with valid values on your environment): http://server/site/_layouts/OSSSearchResults.aspx?k=test&cs=This%20List&u=http://server/site/lists/projects
    That should work. Then double-check your code and make sure your id and name attributes on the input element match with the JavaScript.

  3. great explanations along with your solution! “See ya” in the USPJA jQuery class! I checked this out because of Matt’s reference!

  4. Looks like OSSSearchResults.aspx is probably not valid in Foundation, not sure if Search Server Express could resolve this, but I found that substituting searchresults.aspx worked for me.

    1. Thanks for the heads-up Michael! I confirmed this as well in SP2010 Foundation. I used this in a MOSS 2007 environment so I was unaware of the difference until I saw your comment. I’ll update the article accordingly.

  5. Hi Josh,

    I’m having the same problem as Alex. I think it has something to do with the web part thinking it’s still in Edit mode, not sure. Just wondering if you’ve encountered this issue and if so, how did you resolve it?

    cheers
    danielle

    1. Sorry guys… I managed to get it working… not sure what I was doing wrong.

      Alex, I don’t know if this comes too late for you, I think I know why it wouldn’t work for you. You need to make sure that the input box has an ID. Then to get the value of the Input box, you need to reference the javascript by using document.getElementById(“searchBox”).value

      cheers
      danielle

  6. Great tutorial, worked a treat. One thing though, would it be possible to modify this tool to only search within a specific view?

    1. Hi Andrew,

      There isn’t a way using this solution by itself because SharePoint doesn’t provide any parameters to limit the search results to a specific view. However, you could create a search results page with a Data View Web Part that has the same filters that your view has. Then you’d want to add a query string parameter to the DVWP and use XSLT to only show rows where a column contains the keywords from the query string paramter. Then you’d need to modify the JavaScript to point to the new search results page you created instead of the standard SharePoint search results page. It would require some fancy XSLT, but I think it would be possible. The solution would be a bit limited because it’s a filter, not a true search. If you added any columns to the list you’d need to manually update your DVWP to account for the new column (if you wanted to include the new column in your search, that is). That’s well beyond the scope of this solution, though.

  7. Hi Josh,
    I need some help:
    I have added two input lines to an aspx page; 1. to add text 2. to submit. The idea was to perform a search on a list using CAML query and a build I developed. The issue I am having is when I execute the javascript function it appears to postback to the beginning. I have placed alerts in the code and can see that it actually comes back with the correct value, but when I hit the last OK on the last alert it restarts the original div that I have displayed once submitted as none. This has been driving me crazy for two weeks – I hope you can help with this. Here is what I have used once the submit is applied:
    var LName = “”;
    var dirWindow = null
    function startSearch(){
    alert(‘1’);
    var searchbox = document.getElementById(‘SearchBox’);alert(searchbox.value);
    initECMA_getList1(searchbox.value);alert(‘Line 7’);
    if (searchbox.value==”){
    alert(‘Please enter one or more search words.’);
    }
    document.getElementById(‘search1’).style.display=”block”;
    document.location=document.location;alert(‘Line9’);
    document.getElementById(‘search3’).style.display=”block”;
    return false;
    }
    function initECMA_getList1(loc){
    LName = loc;
    alert(LName);
    var clientContext = null;
    var web = null;
    ExecuteOrDelayUntilScriptLoaded(getList1, “sp.js”);
    }
    //Delete item from projects list
    function getList1() {
    try {
    var clientContext = new SP.ClientContext.get_current();
    var web = clientContext .get_web();
    var list = web.get_lists().getByTitle(‘Contacts’);
    var query = ”+
    ”+
    ”+
    ”+
    ” +
    ”+ LName +”+
    ”+
    ”+
    ”+
    ”;
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(query);
    this.listItems = list.getItems(camlQuery);
    clientContext.load(listItems,’Include(Prefix,FirstName,LastName,Status1,Ophone,ipPhone,email,CompanyName)’);alert(‘3’);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.querysuccess1), Function.createDelegate(this, this.failList));
    }
    catch (e) {
    alert(e);
    }
    }
    function failList(){
    alert(‘You must restart this page to reset login’);
    }
    //This is the display function. It develops the code to display the drop down country list on the page.
    function querysuccess1()
    {
    var listItemInfo = ”;
    var listItemEnumerator1 = listItems.getEnumerator();
    var divHTML =’Contact ListTitleFirst NameLast NameOfficePhoneIPPhoneEmailCompany Name’;

    while (listItemEnumerator1.moveNext())
    {
    var oListItem = listItemEnumerator1.get_current();
    var Region = oListItem.get_item(‘Prefix’);
    var Region1 = oListItem.get_item(‘FirstName’);
    var Region2 = oListItem.get_item(‘LastName’);
    var Region3 = oListItem.get_item(’email’);
    var Region4 = oListItem.get_item(‘Ophone’);
    var Region5 = oListItem.get_item(‘ipPhone’);
    var Region6 = oListItem.get_item(‘CompanyName’);
    var Region7 = oListItem.get_item(‘Status1’);
    if (Region2 == LName){
    if (Region == null){
    var Region8 = ‘ ‘;
    }else {Region8 = Region;}
    if (Region6 == null){
    var Region9 = ‘ ‘;
    }else {Region9 = Region6;}
    if (Region4 == null){
    var Region10 = ‘ ‘;
    }else {Region10 = Region4;}
    if (Region5 == null){
    var Region11 = ‘ ‘;
    }else {Region11 = Region5;}
    if (Region2 == null){
    var Region12 = ‘ ‘;
    }else {Region12 = Region2;}
    if (Region1 == null){
    var Region13 = ‘ ‘;
    }else {Region13 = Region1;}alert(Region2);
    divHTML+=” +Region+ ” +Region13+ ” +Region12+ ” +Region10+ ” +Region11+ ” +Region3+ ” +Region9+ ”;
    }}
    divHTML+=”;

    document.getElementById(‘search1’).innerHTML=divHTML;
    document.getElementById(‘search1’).style.display=”none”;alert(‘4’);
    document.getElementById(‘search3’).style.display=”block”;alert(‘5’);
    }
    During the testing I watched as the the program stepped through and then went back to the startSearch() function and then back to the div without displaying the data from the list.

    1. Hi Mohammad,

      That should be possible; a Form Library is just another type of list/library. There’s really nothing special about this; you just have to generate the appropriate URL query string using the value of the text input. If you go to the Form Library and use the default search box to only search within that library, look at the URL query string on the search results page, then modify the JavaScript in this solution as-needed to match the parameters for the Form Library.

      1. Hey Josh! Thank You so much for your prompt response.. I guess the URL I used in the script is correct.. The could be with my form library. Coz if I try to search a entry already existing in library from library search option, its not returning any value.. Are you aware of this situation, could please help me on this?

        1. I avoid InfoPath forms as much as possible so I don’t work with Form Libraries very often. Is the search feature enabled for that library (in the Form Library settings) and for your site (in the Site settings)?

          1. I think it is something to do with Setting itself Josh.. you have been GREAT GREAT help for me.. Can i ask you one more favor? I m trying to put this contextual search as a web part on sharepoint home page… i was able to do it but, when i click the search button nothing happens… any suggestions on this would be greatly appreciated! Thanks again for you HELP!!

          2. It sounds like something isn’t quite right with the JavaScript. I’d make sure that SharePoint isn’t modifying or removing any of the code. If you are using SharePoint 2010 and a Content Editor Web Part, check out this link: http://sympmarc.com/2011/03/29/adding-script-into-a-content-editor-web-part-cewp-in-sharepoint-2010/. Double-check your code, maybe run the JavaScript through http://www.jshint.com/ to make sure nothing is missing. Use the F12 Developer Tools (if you are developing with Internet Explorer) and see if there are any errors in the console. Good luck!

  8. Hi mate,
    Thanks for the code, got the search up and running ok. Is there an easy way to change the format of the results that are returned? I.e. so that they show up in the same format as they are in as links in the list?

    Thanks

  9. The search results are formatted based on the built-in search results page layout in MOSS 2007, so I wouldn’t consider it “easy” to change the format. I’ve tried messing with the format a couple times and decided it wasn’t worth the effort in my environment given all of the other higher-priority projects I could be working on. It may be worth looking into for your situation, however, so don’t take my word for it 🙂

  10. I tried the code as is and it is returning nothing in my search results or I get an System.TypeInitializationException error. The querystring looks correct but no results. Any ideas why?

    1. There’s nothing special going on here. I’m just using JavaScript to build a standard SharePoint search URL with the appropriate query string. Perhaps your SharePoint environment is set up different? Try using the built-in SharePoint search and see what query string it generates (you may have to go to the list/library you want to search in order to use the built-in contextual search). Then modify the script as-needed to mimic that URL and query string.

Comments are closed.