How to Create a Dictionary in SharePoint

This tutorial will help you build a dictionary in SharePoint using an auto suggest feature that calls up terms from the centralized term store.
No server side web part development; everything in this article to create the dictionary was developed using JavaScript, SPServices, CSS and a custom list. Using the SharePoint Client Object Model would be a better choice for this type of project and has extensive capabilities of making your site more dynamic and functional.

Using SPServies
SPServices is a JQuery library abstract SharePoint web services and make them easy to use it. If you have not worked with SPServices,
check out the website for more detailed information about its functionality. It works entirely client side and requires no server install.

Download the jquery files from the site and upload them to your SharePoint server. For this project, I placed the files under the Site Assets directory so they could be accessed anywhere in the Site Collection.

Getting Started
Starting with HTML and some CSS, I created a web page similar to the image below. If a user clicks on a letter, all the terms and definitions starting with that letter will appear below inside a div element. Note that there are a few linked Javscript and external CSS files including the main jquery library, SPServices.js, and the autosuggest jquery files. Dictionary.js and dictionary_autosuggest.js are two Javascript files that contain the client side functionality of the search features. More details are explained later in this article.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">

<html xmlns="" xml:lang="en" lang="en">


<title>TS Dictionary</title>

<script type="text/javascript" src="/style%20library/services-plugin/js/jquery.js"></script>

<!-- autocomplete files -->

<link href="/Site Assets/jquery-ui-1.10.0.custom.css" rel="stylesheet"/>

<script src="/Site Assets/jquery-ui-1.10.3.custom.min.js"></script>

<script src="/Site Assets/jquery.SPServices-0.7.2.min.js" language="javascript" type="text/javascript"></script>

<script type="text/javascript" src="/site Assets/dictionary.js"></script>

<script type="text/javascript" src="/site Assets/dictionary_autoSuggest.js"></script>

<style type="text/css">

#author_alphabetic {
#author_alphabetic ul {

#author_alphabetic li {
margin:2px 2px 0 0;

#author_alphabetic a {
border:1px solid rgb(61, 127, 172);
font-family: "Verdana";

#author_alphabetic a span {

/* background:url(../image/alpha_br.png) no-repeat right bottom; */

#author_alphabetic a:hover {
background:rgb(61, 127, 172);

#author_alphabetic a:hover span.first {
background:rgb(119, 165, 197);
border:1px solid rgb(255, 255, 255);

#author_alphabetic a:hover span span {

.ui-autocomplete {
max-height: 400px;
overflow-y: auto;
/* prevent horizontal scrollbar */
overflow-x: hidden;

/* IE 6 doesn't support max-height * we use height instead, but this forces the menu to always be this tall */*
html .ui-autocomplete {
height: 100px;
.myInput {
height:42px ;
background: url("/style%20library/enetThemeimages/input6.png") 0 0 ;
background-repeat: no-repeat;
color: #8a8484;
padding-right: 5px;

background: no-repeat url("/style%20library/enetThemeimages/searchbutton.png") 0 0 ;

<h3 style="padding-left:105px;padding-top:-30px; position:relative;top:30px; width:470px; color:#787878">Click search or use the enter key to call up a dictionary term. </h3>
<div style="position:relative; top:-20px; left:4px; background-color:transparent; width:100px; height:80px">
<img src="/style%20library/enetThemeImages/glass.png" />
<div style="background-color:transparent; width:500px; height:100px;position:relative; left:110px;">
<table border=0><tr><td>
<input type="text" id="txtSearch" class="myInput" value="Search the dictionary..." onClick="clearMe()" onkeypress="searchKeyPress(event);" />
<input type="button" id="btnSearch" value="" onclick="getTerm();" class='myButton' /> </td>
<div id="author_alphabetic" style="position:relative; top:10px; left:-14px">
<li><a href="#" onclick="getVals('A')" title="A"><span class="first"><span>A</span></span></a></li>
<li><a href="#" onclick="getVals('B')" title="B"><span class="first"><span>B</span></span></a></li>
<li><a href="#" onclick="getVals('C')" title="C"><span class="first"><span>C</span></span></a></li>
<li><a href="#" onclick="getVals('D')" title="D"><span class="first"><span>D</span></span></a></li>
<li><a href="#" onclick="getVals('E')" title="E"><span class="first"><span>E</span></span></a></li>
<li><a href="#" onclick="getVals('F')" title="F"><span class="first"><span>F</span></span></a></li>
<li><a href="#" onclick="getVals('G')" title="G"><span class="first"><span>G</span></span></a></li>
<li><a href="#" onclick="getVals('H')" title="H"><span class="first"><span>H</span></span></a></li>
<li><a href="#" onclick="getVals('I')" title="I"><span class="first"><span>I</span></span></a></li>
<li><a href="#" onclick="getVals('J')" title="J"><span class="first"><span>J</span></span></a></li>
<li><a href="#" onclick="getVals('K')" title="K"><span class="first"><span>K</span></span></a></li>
<li><a href="#" onclick="getVals('L')" title="L"><span class="first"><span>L</span></span></a></li>
<li><a href="#" onclick="getVals('M')" title="M"><span class="first"><span>M</span></span></a></li>
<li><a href="#" onclick="getVals('N')" title="N"><span class="first"><span>N</span></span></a></li>
<li><a href="#" onclick="getVals('O')" title="O"><span class="first"><span>O</span></span></a></li>
<li><a href="#" onclick="getVals('P')" title="P"><span class="first"><span>P</span></span></a></li>
<li><a href="#" onclick="getVals('Q')" title="Q"><span class="first"><span>Q</span></span></a></li>
<li><a href="#" onclick="getVals('R')" title="R"><span class="first"><span>R</span></span></a></li>
<li><a href="#" onclick="getVals('S')" title="S"><span class="first"><span>S</span></span></a></li>
<li><a href="#" onclick="getVals('T')" title="T"><span class="first"><span>T</span></span></a></li>
<li><a href="#" onclick="getVals('U')" title="U"><span class="first"><span>U</span></span></a></li>
<li><a href="#" onclick="getVals('V')" title="V"><span class="first"><span>V</span></span></a></li>
<li><a href="#" onclick="getVals('W')" title="W"><span class="first"><span>W</span></span></a></li>
<li><a href="#" onclick="getVals('X')" title="X"><span class="first"><span>X</span></span></a></li>
<li><a href="#" onclick="getVals('Y')" title="Y"><span class="first"><span>Y</span></span></a></li>
<li><a href="#" onclick="getVals('Z')" title="Z"><span class="first"><span>Z</span></span></a></li>
<span style=" line-height:32px"> <a href="#" onclick="getAllVals()" title="Show All" align="absmiddle">Show All</a> </span>
<br /><br><br><br><br><br>
<div id="MainDiv" style="background-color:transparent; padding-left:40px; ">
<div id="ShowMeTerm" style="background-color:transparent; font-size:12px; color:blue; width:700px" valign="top"></div
<div id="ShowMeDef" ></div></div></body></html>

Create Dictionary List

After the htm file was uploaded to the WFE, I created a custom list named ‘Dictionary’ and added a column called ‘Definition’ with a type of multilines of text. I used the Title column as the term to define. Added a few list items so content could be available for testing.

Create Term-Set

On the top level site of the site collection, go to Site Actions > Site Settings and under Site Administration click on > Term store management. On the left pane in the Taxonomy term store create a new term-set called ‘Dictionary.’ Give it a description and allow the submission policy be checked as Open. Add the same terms as you did in the custom list. Save changes.

Go back to the Dictionary list settings to add a new metadata column called ‘MetaData.’ In the term-set settings tree-view, select the Dictionary term-set to link the metadata to the term-set.

Once this is completed, a new field in the form called ‘MetaData’ will be added. Create a new .aspx page on your site where you created the Dictionary custom list. Add the Dictionary custom list to the page and publish. When you click ‘Add new item’, you can manually add new terms and definitions to the list. At this point, you have a SharePoint page that displays an input field a search button and A-Z boxes. Notice a div entitled ‘ShowMeTerm. ’ This is where the definitions will be displayed dynamically on the page.

Binding the AutoSuggest Feature to the input field

In the Javscript below, it starts off with variable declarations. As the function getKeywords gets initiated, the script is calling SharePoint client object model and begins to load term-set from the metadata columns “TSDictionary” that you created earlier. If the term-set is correctly found, then the function OnLoadSuccess is processed followed by two more functions; GetTermsRecursive and getVals(‘A’).

GetTermsRecursive calls the SPServices Jquery script which then queries the term-set. GetData function gathers all the data in the term-set into an array (“mySortedArry”) and then becomes binded to the input field “txtSearch.”

mySortedArry = myListTerms.split(",");
var myListTerms2 = String(mySortedArry);
$("#txtSearch").autocomplete({ source: myListTerms2.split(",")

The getVals() function is initiated when a user clicks on any of the A-Z letters. This function uses a CAML to query the Dictionary custom list and select all the terms and definitions that start with the letter in the variable letter. For example, getVals(‘G’) will display all the terms beginning with G.

<View><Query><Where><BeginsWith><FieldRef Name=’Title’/>’ + ‘<Value Type=’Text’>’ + letter + ‘</Value></BeginsWith></Where><OrderBy><FieldRef Name="Title" Ascending="True" /></OrderBy></Query></View>

The function onQuerySucceeded() gets called to display the results of the CAML query inside the “ShowMeTerm” div by using innerHTML.

In a similar manner, the Show All link will call up the getAllVals() function and by using another CAML query, will

display every result returned from the Dictionary list.



    var myGlobalSearch ;
    var clientContext;
    var oList;
    var camlQuery;
    var listItemInfo = '';
    var listItemInfo2 = '';
    var listItemEnumerator;
    var termPresent;
    var srchTerm;
    var myListTerms= '';
    var TaxTerms = {
        termId: "",
        termName: "",
        child: null


    //---------init  begin taxonomy ----------------->

    var TaxConfiguration = {
        SspId: "",
        GroupId: "",
        TermSetId: "",
        Configuration: "",
        ParseConfiguration: function () {


            xmlDoc = $.parseXML(this.Configuration);
            xml = $(xmlDoc);
            var properties = xml.find("Property");

            for (i = 0; i < properties.length; i++) {
            propertyName = properties[i].firstChild.textContent == undefined ?
            properties[i].firstChild.text : properties[i].firstChild.textContent;
            propertyValue = properties[i].lastChild.textContent == undefined ?
            properties[i].lastChild.text : properties[i].lastChild.textContent;
               if (propertyName == propertyValue) {
                    propertyValue = "";


                switch (propertyName) {
                    case "SspId":
                        this.SspId = propertyValue;
                    case "GroupId":
                        this.GroupId = propertyValue;
                    case "TermSetId":
                        this.TermSetId = propertyValue;


    // goes to this function

    function GetTermsRecursive(sspId, termSetId, myListTerms) {   
        var terms = new Array();
        var returnValue;
            operation: "GetChildTermsInTermSet",
            sspId: sspId,
            termSetId: termSetId,
            lcid: 1033,
            completefunc: GetData

    function GetChildTermsRecursive(sspId, termSetId, roottermId) {
        var terms = new Array();
            operation: "GetChildTermsInTerm",
            sspId: sspId,
            termId: roottermId,
            termSetId: termSetId,
            lcid: 1033,
            completefunc: GetData
       return myListTerms;


    function GetData(xData, Status) {
        if (Status == "success") {
            terms = new Array();
            xmlData = xData;
            // Fix for different XML parsing in IE and Chrome
            termsContent = $.parseXML(xmlData.responseText).firstChild.textContent == undefined ?
            $.parseXML(xmlData.responseText).text :
            termsXML = $.parseXML(termsContent);
            $termsXML = $(termsXML);
            childTerms = $termsXML.find("T");
            parentTermId = null;
            filterOutput = "<ul>";
            for (i = 0; i < childTerms.length; i++) {
                termName = $(childTerms[i]).find("TL");

                hasChildTermsXml = $(childTerms[i]).find("TM");
                // request if child terms are avaliable

                hasChildTerms = $(hasChildTermsXml).attr("a69");
                var tsTerm = new Object();
                // Requesting actual term id
                tsTerm.termId = $(childTerms[i]).attr("a9");
                // Requesting term name

                tsTerm.termName = termName.attr("a32");

                // Setting Parent Term ID

                parentTermId = $(hasChildTermsXml).attr("a25");
                filterOutput += "<li id='" + tsTerm.termId + "'>" + tsTerm.termName;
                // try to put termName in doug comma delimited array - this works!!
                myListTerms+= ',' + tsTerm.termName;
                 // for debugging puroposes
                // If child terms are avaliable query child terms
                if (hasChildTerms != undefined && hasChildTerms == "true") {
                    // Request child Terms
                    tsTerm.child = GetChildTermsRecursive(taxconfig.SspId, taxconfig.TermSetId, tsTerm.termId);
                    tsTerm.hasChildTerms = true;
                } else {
                    tsTerm.child = null;
                    tsTerm.hasChildTerms = false;

                filterOutput += "</li>";
                terms[i] = tsTerm;
            filterOutput += "</ul>";
            // If parent element is specified query for parent element
            if (parentTermId != undefined || parentTermId != null) {
                $("#" + parentTermId).append(filterOutput);
            } else {
                currentFilter = $("#filter").html();
                $("#filter").html(currentFilter + filterOutput);

            //  sort comma delimited string
             mySortedArry = myListTerms.split(",");
             var myListTerms2 = String(mySortedArry);                                                    
              $("#txtSearch").autocomplete({ source: myListTerms2.split(",")

            //return dictionaryTerms;



    var fieldCollection;
    var termField = null;
    var termSetTerms = Array();
    var taxconfig = TaxConfiguration;

    function OnLoadFailed(sender, args) {
        alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());

    //------ end taxonomy code------------------------------//
    $(document).ready(function () {
                ExecuteOrDelayUntilScriptLoaded(getKeywords, "sp.js");
                clearFormData() ;    

    function getKeywords() {
        var clientContext = SP.ClientContext.get_current();
        if (clientContext != undefined && clientContext != null) {
            var webSite = clientContext.get_site().get_rootWeb();
            // Select 'Action' Field
            fieldCollection = webSite.get_fields();
            this.termField = fieldCollection.getByInternalNameOrTitle("TSDictionary");
            // Load Context
            clientContext.executeQueryAsync(Function.createDelegate(this, this.OnLoadSuccess), Function.createDelegate(this, this.OnLoadFailed)


    function OnLoadSuccess(myList) {
        var fieldInfo = '';
        var fieldschema = termField.get_schemaXml();
        taxconfig.Configuration = fieldschema;
        try {
            var taxsspId = taxconfig.SspId;
            var termSetId = taxconfig.TermSetId;
            var dictionaryTerms = '';
            GetTermsRecursive(taxconfig.SspId, taxconfig.TermSetId, dictionaryTerms);
        }   catch (e) {
       function onCreateSucceeded() {
        // just an empty function

function searchKeyPress(e)
        // look for window.event in case event isn't passed in
        if (typeof e == 'undefined' && window.event) { e = window.event; }
        if (e.keyCode == 13)

            var mySearchField = document.getElementById('txtSearch');
             myGlobalSearch  = mySearchField.value;

function getTerm() {
   var mySearchField = document.getElementById('txtSearch');
   myGlobalSearch = mySearchField.value;


function  clearMe() {
   var myfield2 = document.getElementById('txtSearch');
   myfield2.autocomplete = "off";
   myfield2.value = "";



function onFilterQueryFailed(sender, args) { alert ("Unable to retrieve terms. Please contact your administrator.") }

function getVals(letter) {
       var fieldDisplayName = "Title";
        var clientContext = new SP.ClientContext.get_current();     
       var spWebobj = clientContext.get_web();
        var spListobj = spWebobj.get_lists().getByTitle('Dictionary');
        var spCamlQuery = new SP.CamlQuery();
        spCamlQuery.set_viewXml ('<View><Query><Where><BeginsWith><FieldRef Name=\'Title\'/>' +   '<Value Type=\'Text\'>' + letter + '</Value></BeginsWith></Where><OrderBy><FieldRef Name="Title" Ascending="True" /></OrderBy></Query></View> ' );      
       this.collListItem = spListobj.getItems(spCamlQuery);
        clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onFilterQueryFailed));               


function getAllVals() {
var fieldDisplayName = "Title";
        var clientContext = new SP.ClientContext.get_current();     
        var spWebobj = clientContext.get_web();
        var spListobj = spWebobj.get_lists().getByTitle('Dictionary');
        var spCamlQuery = new SP.CamlQuery();
        spCamlQuery.set_viewXml ('<View><Query><Where><IsNotNull><FieldRef Name="Title" /></IsNotNull></Where><OrderBy><FieldRef Name="Title" Ascending="True" /></OrderBy></Query></View> ');

        this.collListItem = spListobj.getItems(spCamlQuery);
        clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onFilterQueryFailed));


function onQuerySucceeded(sender, args) {
    var listItemInfo = '';
    var listItemEnumerator = collListItem.getEnumerator();
    document.getElementById("ShowMeTerm").innerHTML ='';
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        listItemInfo += '\nID: ' + oListItem.get_id() +
            '\nTitle: ' + oListItem.get_item('Title') +
            '\nBody: ' + oListItem.get_item('Definition');
          myterm =   oListItem.get_item('Title');
     document.getElementById("ShowMeTerm").innerHTML += oListItem.get_item('Title') + ":<br />" +  "<div style=color:black; font-weight:normal;>" + oListItem.get_item('Definition') +  "</div> <br /><br />" ;

     if (listItemInfo.toString()== "") {
        document.getElementById("ShowMeTerm").innerHTML = "No matches found."

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: