Office 365/SharePoint Sandbox Service Pages in Action – Autocomplete Text Boxes

A couple weeks ago I wrote about an Unorthodox Architecture for Services in SharePoint Sandbox Solutions and Office 365. This post is about an application of this architecture to create an autocomplete text box using jQuery UI. An autocomplete field looks like this:

It is a great alternative to the stock lookup field UI when the source list of the lookup field has a large amount of data. With hundreds of items the standard dropdown list just isn’t a good experience. The jQuery Autocomplete widget makes it easy to build a field that displays a list as the user types. In this example the JavaScript is simple and the underlying field is "single line of text". If you need to ensure the entry matches a value from the lookup list you’ll need to do some extra work. That said, here is the JavaScript:

$("#client").autocomplete({
source: function(request, response) {
url = L_Menu_BaseUrl + "/ServicePages/AutoComplete.aspx?l=Clients&f=Title&v=" + request.term;
$.getJSON(url, function(data) {
response(data);
});
},
minLength: 1
});

 

The url in the above script is to a service page that contains a Web Part whose code is shown at the bottom of this post. The variable L_Menu_BaseUrl is declared and populated by SharePoint’s own JavaScript libraries and it contains the Web’s server relative URL. The Web Part reads the query string and runs a CAML query against the specified list to search for values that begin with the specified term. The result is written to the page as JSON by using the JavaScriptSerializer to serialize a List<string> of the specified field for each item in the result set.

Enjoy!
–Doug

//Inputs are
//l=List
//f=Field
//v=Value
//max=RowLimit
[ToolboxItemAttribute(false)]
public class AutoComplete : WebPart
{
protected override void Render(HtmlTextWriter writer)
{
var items = GetItems();
if (items.Count > 0)
{
JavaScriptSerializer js = new JavaScriptSerializer();
writer.Write(js.Serialize(items));
}
}

private List<string> GetItems()
{
var items = new List<string>();
string listName = Page.Request.Params["l"];
string field = Page.Request.Params["f"];
string val = Page.Request.Params["v"];
uint max = 10;

//Parse the query string parameters and return an empty list if there is a problem
if (Page.Request.Params["max"] != null)
{
try { max = uint.Parse(Page.Request.Params["max"]); }
catch { } //ignore the error and return 10 items
}

if (string.IsNullOrEmpty(listName) || string.IsNullOrEmpty(field) || string.IsNullOrEmpty(val))
{
return items;
}

//Build and execute the query
string queryXML = string.Format(@
"<OrderBy><FieldRef Name='{0}' /></OrderBy><Where><BeginsWith><FieldRef Name='{0}' />
<Value Type='Text'>{1}</Value></BeginsWith></Where>", field, val);

string viewFields = string.Format(@"<FieldRef Name='{0}'/>", field);

SPList list = SPContext.Current.Web.Lists.TryGetList(listName);

if (list == null) return items;

SPQuery query = new SPQuery();
query.Query = queryXML;
query.ViewFields = viewFields;
query.RowLimit = max;
var listItems = list.GetItems(query);

//Put the returned items into the list
foreach (SPListItem listItem in listItems)
{
items.Add(listItem[field].ToString());
}
return items;
}
}

Author: Doug Ware