If you read this blog you probably know that besides the web user interface, SharePoint also exposes some interfaces which you can use from code: the SharePoint object model and the SharePoint web services. The object model of SharePoint can only be used by code/applications that are running on a SharePoint server in your Server Farm, so you can’t use the object model on client machines. The SharePoint web services can be used of course across a network boundary, that’s what they are built for! In this post I’m going to show you how you can access the out-of-the-box SharePoint web services by making use of the jQuery Javascript library. First let’s see what you can do with this technique: download this zip file that contains an ASPX page (a basic Site Page without any code behind), and the jQuery Javascript library (in case you don’t have it already). Upload the two individual files (not the zip file) in the root of a Document Library in any of your SharePoint sites. You can do this by making use of the web user interface; you don’t have to touch anything on the server itself. When done, just click on the link of the uploaded ASPX and you’ll see following page:
Probably you’re not really impressed but think about the fact that this page is just an ASPX file you’ve uploaded through the web user interface, there is absolutely no code behind involved (which would have been blocked by SharePoint’s default security settings). The details of the SharePoint lists are loaded by making use of Javascript code that calls the web SharePoint lists.asmx web service.
So how do you call a SharePoint web service in Javascript code; well you can use the XmlHttpRequest object and write lots of boring code, or you can make use of a Javascript library that wraps this XmlHttpRequest object and exposes a nice and easy interface. In this demo I’ll use the jQuery Javascript library, so the first thing that you’ll need to do is to make sure the page is loading that library:
<script type="text/javascript" src="jquery-1.3.2.min.js" mce_src="jquery-1.3.2.min.js"></script>
If you already configured your SharePoint site so the jQuery library is loaded (for example by making use of the SmartTools.jQuery component), you can skip this line of course.
When the page is loaded, the Lists web service (e.g. http://yoursite/_vti_bin/lists.asmx) of SharePoint needs to be called; this can be accomplished by making use of the jQuery’s ajax method. This method can post the necessary SOAP envelope message to the Lists web service. The XML of the SOAP envelope can easily be copied from the .NET web service test form of the desired web method (e.g. http://yoursite/_vti_bin/lists.asmx?op=GetListCollection). In the code below, a call to the GetListCollection web method is made when the page is loaded. The complete parameter of the ajax method is actually a pointer to another Javascript function (which we’ll implement later on) that will be called asynchronously when the web service call is done. Don’t forget to update the url parameter with your SharePoint site’s URL!
$(document).ready(function() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
</GetListCollection> \
</soapenv:Body> \
</soapenv:Envelope>";
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
</GetListCollection> \
</soapenv:Body> \
</soapenv:Envelope>";
$.ajax({
url: "http://yoursite/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
});
url: "http://yoursite/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
});
As I already mentioned, the processResult function is called when the response XML of the web service call is received. In this method a loop is created which will iterate over every List element of the response XML. For every List element a <li></li> element is added to the element with the ID attribute set to data.
function processResult(xData, status) {
$(xData.responseXML).find("List").each(function() {
$("#data").append("<li>" + $(this).attr("Title") + "</li>");
});
}
$(xData.responseXML).find("List").each(function() {
$("#data").append("<li>" + $(this).attr("Title") + "</li>");
});
}
This data element is the actual <ul></ul> list in HTML:
<ul id="data"></ul>
When you put everything together in a Site Page, this is the result:
In the zip file mentioned in the beginning of this post, you can find an extended version of the processResult function which will display some additional metadata for every list (like the ID, ItemCount etc). The entire contents of basic version of the Site Page built in this post goes as follows:
<%@ Page Language="C#" MasterPageFile="~masterurl/default.master" %>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderAdditionalPageHead">
<script type="text/javascript" src="jquery-1.3.2.min.js" mce_src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
</GetListCollection> \
</soapenv:Body> \
</soapenv:Envelope>";
$(document).ready(function() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
</GetListCollection> \
</soapenv:Body> \
</soapenv:Envelope>";
$.ajax({
url: "http://yoursite/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
url: "http://yoursite/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
});
function processResult(xData, status) {
$(xData.responseXML).find("List").each(function() {
$("#data").append("<li>" + $(this).attr("Title") + "</li>");
});
}
</script>
$(xData.responseXML).find("List").each(function() {
$("#data").append("<li>" + $(this).attr("Title") + "</li>");
});
}
</script>
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderMain">
<ul id="data"></ul>
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea">
List Details
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitle">
List Details
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderMain">
<ul id="data"></ul>
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea">
List Details
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitle">
List Details
</asp:Content>