Skip to main content

Weblog Ton Stegeman [MVP]

Go Search
Home
  

ODC 2008
If you have a question or suggestion, please contact me through Windows Live Messenger.
My status: .

If I am not online, please send me an e-mail.
Weblog Ton Stegeman [MVP] > Posts > SharePoint 2010 Client Object Models – The ECMAScript library
SharePoint 2010 Client Object Models – The ECMAScript library

Update 04-12-2009: In the Beta version, executeQuery is now called executeQueryAsync. Updated the code samples.

As you probably have seen/heard in the news on last week’s SharePoint Conference in Las Vegas, SharePoint 2010 will ship with 3 new object models:

  • a managed .NET API for building client applications using a SharePoint object model.
  • a managed Silverlight object model.
  • an object model to be used in Javascript, the ECMAScript library.

For developers this is an important step forward. Until now, developing SharePoint applications using an object model was limited to applications running on the server. For client applications we had to rely on web services and the RPC protocols. Using these 3 new models, it will be much easier to create client applications. And the reach of our applications will be bigger, because they are very likely to also run on the new SharePoint Online. The three object models are a limited sub set of the server object model. Most objects, properties and methods of the site collection (SPSite) and it’s underlying structures are available in the new models.

In this article I will show you an example of a custom ASPX page that will use the Javascript library. It is a page that runs in the LAYOUTS folder. It shows all users that have direct permissions on the current site. By clicking a user name, the page will show me more information about that user. By selecting a user and one of the available SharePoint groups, the page will add the user to that group. After doing that, the page will remove the permissions for the user. The screenshot below shows the page:

Client Object Models - Figuur 3

Showing the users and the user groups is done in server side code. Showing user information and moving the user’s permissions to the group is handled by javascript using the ECMAScript library.

Step 1 – Show the users and groups

The ASPX page loads the lists with users and groups in the OnLoad of the page. It creates a collection of custom objects and sets these collections as the datasource for the Repeater controls. The code snippet below shows how the users are loaded:

   1: SPWeb web = SPContext.Current.Web;
   2: List<SharePointUser> users = new List<SharePointUser>();
   3: foreach (SPRoleAssignment assignment in web.RoleAssignments)
   4: {
   5:     if (assignment.Member is SPUser)
   6:     {
   7:         SPUser user = (SPUser)assignment.Member;
   8:         SharePointUser usr = new SharePointUser(user.ID, user.Name);
   9:         users.Add(usr);
  10:     }
  11: }
  12: listUsers.DataSource = users;
  13: listUsers.DataBind();

The snippet below shows the ASPX code for the repeater that shows the users:

   1: <asp:Repeater ID="listUsers" runat="server">
   2:     <HeaderTemplate>
   3:     <h3>Users with direct permissions on this site</h3>
   4:     </HeaderTemplate>
   5:     <ItemTemplate>
   6:     <li style="list-style-type:none">
   7:         <input type="checkbox" id="selectUser<%# DataBinder.Eval(Container.DataItem, "ID") %>" name="selectUser" />
   8:         <a href="javascript:getUserInfo(<%# DataBinder.Eval(Container.DataItem, "ID") %>);">
   9:             < %# DataBinder.Eval(Container.DataItem, "Name") %>
  10:         </a>
  11:     </li>
  12:     </ItemTemplate>
  13: </asp:Repeater>

For every user in the collection, a hyperlink is rendered. When the link is clicked, javascript function “selectUser” is called. This function takes the ID of the user as parameter

Step 2 – Preparing the page for using the ECMAScript library

The ECMAScript library is available in a number of JS files in the LAYOUTS folder. The main file is SP.js. When you include this file in the APSX page using a ScriptLink control, all other required JS files are loaded automatically. This MSDN page shows all relevant files. By linking SP.js to your page, the SP namespace is registered. This is the SharePoint namespace that contains all objects. If you are going to build code using this library, you will very likely need this MSDN Page to reference what object, properties and methods are available. The SharePoint js files are minified (‘crunched’ in the SDK) versions. This makes them hard to read and use for debugging. Therefore every js file also has a ‘debug’ equivalent in the same folder. By opening sp.debug.js you will be able to see what is available in the SP namespace.

The snippet below show how to prepare the ASPX page:

   1: <SharePoint:ScriptLink 
   2:     Name="sp.js" LoadAfterUI="true" Localizable="false" 
   3:     runat="server" ID="ScriptLink1" />

Step 3 – Getting the user information

As we have seen in step 1, clicking a user’s name fires the javascript function ‘selectUser’. This function is shown in the snippet below.

   1: function getUserInfo(userID) {
   2:     var clientContext = new SP.ClientContext.get_current();
   3:     var web = clientContext.get_web();
   4:     var userInfoList = web.get_siteUserInfoList();
   5:     var camlQuery = new SP.CamlQuery();
   6:     camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'ID\'/>' +
   7:                           '<Value Type=\'Number\'>' + userID + '</Value></Eq>' +
   8:                           '</Where></Query><RowLimit>1</RowLimit></View>');
   9:     this.collListItem = userInfoList.getItems(camlQuery);
  10:     clientContext.load(collListItem);
  11:     clientContext.executeQueryAsync(
  12:         Function.createDelegate(this, this.onQuerySucceeded), 
  13:         Function.createDelegate(this, this.onQueryFailed));
  14: }

As in server side code, we first need to get the SharePoint context. Because our page is an ASPX page running in the LAYOUTS folder, it is always in context of the current SharePoint site. In all 3 new client object models, the SharePoint context is represented in a ClientContext object. In line 2 of the snippet above, we’re getting the current SharePoint context. The next few lines look pretty familiar if you are used to SharePoint server side programming. We are getting a reference to the User Information List of the current site. Next we create a CAML query to find the list item for the user that was selected, and we load the items based on that query from the list. The big difference with the server side object model, is that we did not yet have any contact with SharePoint. Although we have called the getItems method of the list, our collection is not yet loaded. This happens when we load the collection in line 10 and execute the query using clientContext.ExecuteQuery in line 11. This gives you the option to minimize the number of roundtrips to the server from your client code. This makes SharePoint client programming different from server side programming. You need to do more thinking about what objects and properties to use when. It makes sense to load as many objects you need, before calling ExecuteQuery once, to actually get the objects from the server.

In the sample above, you see another difference between client and server side programming. The ECMAScript library is, as the Silverlight API, asynchronous. The ExecuteQuery method takes 2 parameter, the functions that will be called in both a success and a failure scenario. The snippet below shows the ´success´ function of my sample page:

   1: function onQuerySucceeded(sender, args) {
   2:     var item = collListItem.itemAt(0);
   3:     var profile = item.get_item('Notes');
   4:     var pictureUrl = item.get_item('Picture').get_url();
   5:     
   6:     var userImage = document.getElementById('userImage');
   7:     userImage.src = pictureUrl;
   8:     var profileDiv = document.getElementById('userProfile');
   9:     profileDiv.innerHTML = profile;
  10: }

This code loads the first item from the collection, get the values of the Notes and Picture

Step 4 – Move the user to the group

Last part of this article show how to remove the user permissions and add the user to the selected group. When a groupname is clicked, the javascript function moveSelectedUsersToGroup is called and the ID of the group is passed as parameter. The snippet below shows this function:

   1: function moveSelectedUsersToGroup(groupID) {
   2:     var users = document.getElementsByName('selectUser');
   3:     this.clientContext = new SP.ClientContext.get_current();
   4:     this.web = clientContext.get_web();
   5:     var groups = web.get_siteGroups();
   6:     var group = groups.getById(groupID);
   7:     var groupUsers = group.get_users();
   8:     for (i = 0; i < users.length; i++) {
   9:         if (users[i].checked) {
  10:             var id = users[i].id.replace(/selectUser/, '');
  11:             var siteUsers = web.get_siteUsers();
  12:             var user = siteUsers.getById(id);
  13:             groupUsers.addUser(user);
  14:             var assignments = web.get_roleAssignments();
  15:             var assignment = assignments.getByPrincipalId(id);
  16:             assignment.deleteObject();
  17:             clientContext.executeQueryAsync(
  18:                 Function.createDelegate(this, this.addUsersSucceeded), 
  19:                 Function.createDelegate(this, this.onQueryFailed));
  20:         }
  21:     }
  22: }

What this does before the query is executed to SharePoint, is:

  • get a reference to the SharePoint group
  • find the selected user in the site users
  • add the user to the selected group
  • find the role assignment for the selected user
  • delete the role assignment for the selected user

By submitting the query to SharePoint, all these actions are all executed at once in 1 roundtrip to the server. If this action is successful, the javascript function addUsersSucceeded is called. This function has not specical function, it notifies the user about the outcome of the process.

In this article we have seen how to use one of the three new client object models, the ECMAScript library. Although programming client applications is now a lot easier, and is more like programming the server, the are some conceptual differences that are important to understand. The next few articles will show you some examples on how to get started using the other two client object models.

Comments

Re: SharePoint 2010 Client Object Models – The ECMAScript library

Nice work! Calling the executeQuery at the end of the function will need time to get used to indeed. I'm interested to find out in what cases clientContext.load() is used, but hopefully the SDK will provide enough additional info.

Sjoert
at 11/3/2009 1:21 PM

Cool

Hi Ton,
thank you for this great article!
Can't wait to get hold of a beta...

René
at 11/5/2009 11:34 PM

Can't get it to work

Hi Ton,

I have been trying to get this example to work but I can't seem to get it running.

I keep getting the following error: Object doesn't support this property or method. on the executeQuery method.

Maik
http://msftplayground.com
at 12/3/2009 1:05 PM

Early versions...

Going from Technical Preview to Beta, executeQuery was renamed to executeQueryAsync. Updated the code; thanks for notifying!
Ton Stegeman at 12/4/2009 8:04 AM

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Your city *


Type the name of the city you live in (making it easier to handle spam...)

CurrentDate *

Select the current date (see if this gives me fewer spam...)
Attachments

 Links

  SharePoint Object on CodePlex
  Screencast introducing SharePoint Objects
  Content by Type and Filter Web Parts on CodePlex
  Archive
  Archive (Calendar)

 My Latest Blog Posts

Scripting SharePoint 2007 setup: choices and conceptsUse SHIFT+ENTER to open the menu (new window).
Adventures in Visual Studio 2010: Migrate the Content By Type web part to SharePoint 2010Use SHIFT+ENTER to open the menu (new window).
Register SharePoint themes by using a featureUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010 development on Windows 2008 Server R2 – Getting StartedUse SHIFT+ENTER to open the menu (new window).
New release SharePoint Objects: features and groupsUse SHIFT+ENTER to open the menu (new window).
Constructing the url to the SharePoint Edit Permissions pageUse SHIFT+ENTER to open the menu (new window).
Screencast: introduction to SharePoint ObjectsUse SHIFT+ENTER to open the menu (new window).
SharePoint 2007 and Reporting ServicesUse SHIFT+ENTER to open the menu (new window).
SharePoint Objects – Insight in usage of your SharePoint artifactsUse SHIFT+ENTER to open the menu (new window).
SharePoint 2007 Custom list schema and the Content Query Web PartUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010 Silverlight Client Object Model – ExecuteQuery vs ExecuteQueryAsyncUse SHIFT+ENTER to open the menu (new window).
SharePoint 2010, the Client Object Models and Bing MapsUse SHIFT+ENTER to open the menu (new window).
Having fun with SharePoint 2010, Silverlight 3 and Bing MapsUse SHIFT+ENTER to open the menu (new window).
Connecting TFS 2010 projects to SharePoint sitesUse SHIFT+ENTER to open the menu (new window).
Adding a database to the SharePoint database Server using SPDatabaseUse SHIFT+ENTER to open the menu (new window).