Working with the ECMAScript Client Object Model (JSOM) in SharePoint 2010

Summary: The JavaScript client object model is a great addition to the SharePoint 2010 development kit. This article teaches you how simple it can be to use.

Applies to: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

Published:   August 2011

Provided by:   Nikhil Sachdeva, Microsoft Global Services

Contents

  • About the ECMA Script Object Model (JSOM)

  • Making your Code Ready for JSOM

  • Preparing JSOM

  • Retrieving Data from Lists and Libraries

  • Manipulating Data in Lists and Libraries

  • Conclusion

About the ECMA Script Object Model (JSOM)

SharePoint developers have been limited to coding on the server-side since SharePoint’s inception. SharePoint 2007 gives developers a robust server-side API that allows for the manipulation of almost any object in the platform. However, support for accessing SharePoint data from the client is limited to the use of various Web services. The Web services do provide access to the object model but their scope is limited and developers have to either constrain their goals or rely on external API’s, such as JQuery, when dealing with scenarios such as the manipulation of SharePoint data after a page has been loaded.

Microsoft SharePoint 2010 improves this scenario by providing a subset of the familiar server-side object model to the client by using the SharePoint 2010 Client Object Model. The client object model is targeted towards building client-side applications by using WPF/Windows or Microsoft Silverlight and for hosting client side code by using JavaScript.

Note

For information regarding other client object model approaches, see the posts written by Steve Peschka here.

This article explains one of the types of client object model support in SharePoint 2010 – the JavaScript client object model, also known as JSOM. It explain its architecture, the execution model, and some common operations you can perform by using JSOM.

JSOM is intended for accessing and manipulating SharePoint objects by using JavaScript (JavaScript) in an asynchronous fashion. It is very useful in situations where you want to access SharePoint data or make manipulations to the data after the page has been loaded on the client. JSOM is made up from a set of JavaScript files and can be easily used in any page or Web Part by simply referring to JSOM scripts. In some cases, you may not need to provide any references such as in the case of a page referencing the standard SharePoint 2010 master pages.

As an example, you can use an editor such as a content editor Web Part to access and manipulate SharePoint objects by using JSOM. For instance, SharePoint 2010 uses JSOM extensively for its own usage; an example of this is the new modal dialog introduced in SharePoint 2010. This modal dialog is actually a part of the client-side SP.UI namespace and leverages JSOM to perform common operations.

JSOM provides a comprehensive set of APIs that can be used to perform operations on most SharePoint objects such as Site, Web, List, ContentTypes, User Permission and so forth. The API is simple to use and allows the developer to focus on the business scenario with a minimum amount of infrastructure required. JSOM fully supports JQuery and both can be used in conjunction with the other.

  • Microsoft Internet Explorer 7.0 or greater

  • Firefox 3.5 or greater

  • Safari 4.0 and greater

Developing with JSOM is similar to using any other object model with some minor syntactical differences. However, before getting into writing code by using JSOM, it is important to understand how it actually works.

The following is a graphical representation of what happens when a page is accessed in a client browser.

Figure 1. Accessing a page in a client browser

The client browser initiates an HttpRequest to the server. The server tries to load the page and starts preparing the master page. If the master page is the standard SharePoint Foundation master page, it already contains references to the required JSOM scripts; if a custom master page is used then you must add the relevant JSOM references before the pages and controls can use the JSOM. SharePoint then identifies the files that need to be sent to the client from the {SharePointRoot}\TEMPLATE\LAYOUTS directory and returns a response that downloads all the files to the host computer.

  • SP.js

  • SP.Core.js

  • SP.Runtime.js

These files are smaller versions of the JavaScript files and depending on the working environment; you might have the debug versions of these files downloaded to your client

This is similar to what happens in SharePoint 2007 with some differences. When a request is made to access a page, only the files required to render the page are downloaded to the client. For example, if your programs use only the SP.CORE.js script, you can specify that only this script is downloaded to the client. This is a huge performance boost from earlier version of SharePoint which downloaded the complete set of core JavaScript files when a page was accessed. If the script has references to any other files, they are also automatically downloaded to the client.

How does SharePoint ensure that only the required files are downloaded to the client machine? What about identifying and downloading the dependencies between files? The answer is the SharePoint 2010 Script on Demand (SOD) framework. SOD ensures that only the required files are downloaded to the client and provides options to load them in the background after the page has completed loading. SOD is a class defined in the init.js file and contains methods for loading scripts, registering script dependencies, executing methods within a loaded page, and event notification. You use SOD to load the OOB SharePoint js files and your own JavaScript files.

SharePoint provides multiple ways to enable on-demand loading of scripts:

  • The easiest way to enable on-demand loading is to set the OnDemand="true" attribute for the SharePoint:ScriptLinkserver tag when referencing a required JavaScript file.

    Setting the OnDemand attribute to true, instructs the framework to register the script for on demand loading by rendering something such as this:

    <script type="text/javascript">
       SP.SOD.RegisterSod("SP.js", "\_layouts\SP.js");
    </script>
    
  • You can also directly call the SP.SOD.registerSod method defined in the SP.SOD class of the init.js file from your custom JavaScript files; this will register the script to be loaded on demand. You can then call the SP.SOD.execute(key, functionName, args) method or the SP.SOD.executeOrDelayUntilScriptLoaded(func, depScriptFileName) method to load the script and execute its methods.

    Note

    Dallas Tester has a blog post that describes more about the API in SP.SOD.

  • If you want to register a script from within a Web Part, you can call the ScriptLink.RegisterOnDemand(page, strFile, localizable)method from the OnPreRender () event of your code to register the custom script.

After the object model is downloaded, you can make calls to perform operations in SharePoint. Any JSOM operation results in an Xml request and SharePoint returns a JSON response to it as shown in the following figure.

Figure 2. JSOM request and response actions

The following example can help you to understand the request/response model. The following code snippet uses JSOM to retrieve an item based on its ID. It returns the current client context and then calls the executeQueryASync method, specifying the callback methods for success and failure of the operation.

var item;
Function getItemById(itemId)
{
   var clientContext = new SP.ClientContext.get_current();
   var web = clientContext.get_web();
   var list = web.get_lists().getByTitle('mycustomList');
   This.item = list.getItemById(itemId);
   clientContext.load(item);
   clientContext.executeQueryASync(Function.createDelegate(this, this.onSuccess), Function.createDelegate(this, this.onFailure);
}
Function onSuccess()
{
   Alert('Success');
}
Function onFailure()
{
   Alert('Failure!');
}

When the getItemById method is executed, an XmlRequest object is created and sent to SharePoint for processing. The client object model acts as a proxy to connect to a WCF service (Client.svc) for the processing of the request. The Client.svc service is the protocol server responsible for performing all of the operations requested by the client object model. The service is located at /_vti_bin/client.svc on the server. The protocol server endpoint appends /_vti_bin/client.svc/ProcessQuery to process a request and requires a formatted Xml Request message based on the client protocol specifications.

Note

The client protocol specifications are two protocols defined under the SharePoint Open Specification standards that allow the execution of a client side operation:

  • SharePoint Client side object modal Protocol [MS-CSOMSPT]

  • SharePoint Client Query Protocol [MS-CSOM]

These protocols define the types, relationships, message formats, exceptions, transport channels, security considerations required by any request/response when accessing the client object model. The following is a stack of protocol client and industry standards defined in the SharePoint CSOM Open Specifications used to execute any operation using the client object model.

Figure 3. Stack of protocol client and industry standards

A typical XmlRequest message might look like this:

<Request 
AddExpandoFieldTypeSuffix="true" 
SchemaVersion="14.0.0.0" 
LibraryVersion="14.0.4006.3001" 
ApplicationName=".NET Library" 
xmlns="https://schemas.microsoft.com/sharepoint/clientquery/2009"> 
   <Actions> 
      <ObjectPath Id="2" ObjectPathId="1" /> 
      <ObjectPath Id="4" ObjectPathId="3" /> 
      <ObjectPath Id="6" ObjectPathId="5" /> 
      <Query Id="7" ObjectPathId="5"> 
         <Query SelectAllProperties="true"> 
            <Properties /> 
         </Query> 
      </Query> 
      <ObjectPath Id="9" ObjectPathId="8" /> 
      <Query Id="10" ObjectPathId="8"> 
         <Query SelectAllProperties="false"> 
            <Properties> 
               <Property Name="Author" ScalarProperty="true" /> 
               <Property Name="Status" ScalarProperty="true" /> 
            </Properties> 
         </Query> 
      </Query> 
   </Actions> 
   <ObjectPaths> 
      <StaticProperty Id="1" TypeId="{acc57e47-24b0-4400-b1c7-aa1cf3c9542d}" 
Name="Catalog" /> 
      <Property Id="3" ParentId="1" Name="Books" /> 
      <Method Id="5" ParentId="3" Name="GetById"> 
         <Parameters> 
            <Parameter Type="Guid">{3387ac63-e73d-421f-bff7-359a4aa2bc38} 
            </Parameter> 
         </Parameters> 
      </Method> 
      <Method Id="8" ParentId="3" Name="GetById"> 
         <Parameters> 
           <Parameter Type="Guid">{704655a3-c136-469c-a578-f79652a93f9b} 
</Parameter> 
         </Parameters> 
      </Method> 
   </ObjectPaths> 
</Request>

Client.svc is an internal WCF service; it is reserved for SharePoint usage and is not intended to be used directly in client code. If you attempt to add a service reference to this service, no proxy will be generated. Internally, the Client.svc leverages the server-side object model to handle all client requests and return a JSON response.

A typical JSON response might look similar to the following:

[ 
{ 
   "SchemaVersion" : "14.0.0.0", 
   "LibraryVersion" : "14.0.4006.3001", 
   "ErrorInfo" : null 
}, 
2, 
{ 
   "IsNull" : false 
}, 
4, 
{ 
   105 / 134 
   [MS-CSOM] — v20110315 
   SharePoint Client Query Protocol Specification 
   Copyright © 2011 Microsoft Corporation. 
   Release: Tuesday, March 15, 2011 
   "IsNull" : false 
}, 
6, 
{ 
   "IsNull" : false 
}, 
7, 
{ 
   "_ObjectType_" : "SampleCode.Book", 
   "Id" : "\/Guid(3387ac63-e73d-421f-bff7-359a4aa2bc38)\/", 
   "Author" : "John Arthur", 
   "Title" : "How to Cook Chinese Food", 
   "Status" : 0, 
   "PublishDate" : "\/Date(2008,2,1,0,0,0,0)\/" 
}, 
9, 
{ 
   "IsNull" : false 
}, 
10, 
{ 
   "_ObjectType_" : "SampleCode.Book", 
   "Author" : "Jim Bates", 
   "Status" : 0 
} 
]

Making your Code Ready for JSOM

The previous section described how the JSOM model works. This section discusses how to prepare Microsoft Visual Studio to provide support for JSOM and how to load the JSOM scripts before accessing the object model.

Preparing your Environment for JSOM

If you are using Visual Studio 2010 as the environment for developing with JSOM, you can use the following procedures to improve your development experience.

You can enable Intellisense for JSOM to load the object model properties in the VS IDE.

  • If you want to use JSOM as inline in an application page, you can enable Intellisense by adding the following references to the PageHead content placeholder of your page.

    <% #if SOME_UNDEFINED_CONSTANT %> 
    <script type="text/ecmascript" src="/_layouts/SP.core.debug.js" /> 
    <script type="text/ecmascript" src="/_layouts/SP.runtime.debug.js" /> 
    <script type="text/ecmascript" src="/_layouts/SP.debug.js" /> 
    <% #endif %>
    

    Notice the pre-processor directive and use of the constant. This ensures that the above <script> tags will be omitted from the actual page rendering. If you do not use this directive, you might get an error when the page gets rendered.

    When these references are added, you can now write your code in the following <script> tags. This makes all of the methods available to the object model.

    <script type="text/javascript">
       //Leverage the JSOM API here
    </script>
    
  • To enable Intellisense inside a visual Web Part, add the following references to the .ascx file.

    <% #if SOME_UNDEFINED_CONSTANT %> 
    <script type="text/javascript" src="/_layouts/MicrosoftAjax.js" /> 
    <script type="text/javascript" src="/_layouts/SP.debug.js" />
    <% #endif %>
    <script type="text/javascript">
    //Leverage the JSOM API here
    </script>
    
  • Similarly, if you have a custom .js file where you want to enable Intellisense for JSOM, you can add references to all of the required JSOM debug script files that are available in the {SharePointRoot}\TEMPLATE\LAYOUTS folder by using the reference comment.

    /// <reference name="MicrosoftAjax.js" />
    /// <reference name="~/TEMPLATE/LAYOUTS/SP.core.debug.js" />
    /// <reference name="~/TEMPLATE/LAYOUTS/SP.debug.js" />
    

As a best practice, add references for only the required JSOM script files and remove all references before your code goes into production.

Preparing JSOM

Earlier in this article, it was stated that JSOM requires a set of files to be downloaded on the client machine to perform any request or response operations. The files need be referenced to ensure that the scripts are downloaded before any call is made for a JSOM operation.

Using JSOM with SharePoint Out-of-the-Box Containers

The good news is that when you create a page or Web Part which uses the SharePoint default master page, you do not need to do anything before using JSOM.

The following is an example of using JSOM in an application page. It simply updates the value of a label control on the click of a button with the current site title. Notice that no ScriptLink tags are mentioned here simply because the default master page (v4.master) already holds references to the required JSOM scripts that need to be downloaded to the client.

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LoadECMAScript.aspx.cs" Inherits="ECMAScriptSample.Layouts.ECMAScriptSample.LoadECMAScript" DynamicMasterPageFile="~masterurl/default.master" %>
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<% #if SOME_UNDEFINED_CONSTANT %> 
<script type="text/ecmascript" src="/_layouts/SP.core.debug.js" /> 
<script type="text/ecmascript" src="/_layouts/SP.runtime.debug.js" /> 
<script type="text/ecmascript" src="/_layouts/SP.debug.js" /> 
<% #endif %>
<script type="text/javascript"> 
var web; 
function getWebTitle() {
   var context = new SP.ClientContext.get_current();
   this.web = context.get_web();
   // Load the web object 
   context.load(this.web,'Title');
   //Make a query call to execute the above statements
   context.executeQueryAsync(Function.createDelegate(this, this.onSuccess), Function.createDelegate(this, this.onFailure)); 
}
function onSuccess() { 
   var control = document.getElementById('ctl00_PlaceHolderMain_lblWebName')
   if (control != null) {
      // Get the title of the site
      // Update the label control with the value of the site Title
      control.innerText = this.web.get_title();
   } 
}
function onFailure() {
   alert("Could not retrieve title for the web");
}
</script> 
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<asp:Label ID="lblWebName" runat="server" Text="Label"></asp:Label>
<asp:Button ID="btnShowWebName" runat="server" Text="Button" onClick="javascript:getWebTitle()" />
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Application Page
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
My Application Page
</asp:Content>

Using JSOM with Custom Containers

In a case where you have customized or utilized a new master page for your sites, you can very easily ensure that JSOM is loaded before you start accessing it.

When referencing JSOM in your custom container that does not refer to the default SharePoint master page, you have two options:

  • Use the server side ScriptLink class to declaratively register a script. The class provides properties and methods for registering scripts so that they can be requested when the page is being rendered.

    <SharePoint:ScriptLink ID="registerSP" runat="server" OnDemand="true" LoadAfterUI="true" Name="SP.js">
    
  • You can alternatively use the ScriptLink.RegisterOnDemand(page, strFile, localizable) method to register the script for loading on the OnPrerender method of the container (this is the preferred way of loading up the scripts in your custom web parts).

One implication of using the ScriptLink class with the OnDemand attribute set to true is that the loading of the JavaScript files becomes non deterministic. This may sometimes lead to unpredictable results and unwanted errors on the client. For example, a client JavaScript method is called before the JSOM has been loaded in the page load event. In this situation, you may generate a JavaScript runtime object expected error.

To facilitate such scenarios, the SOD framework provides methods to ensure that the client scripts are loaded before any execution takes place on the dependent methods. One such method is SP.SOD.executeOrDelayUntilScriptLoaded(func, depScriptFileName). Calling this method before the executing method ensures that the function provided in the first parameter is not executed until the script file name mentioned is not loaded or has not been loaded.

The following is the definition for this method in the init.js file:

function ExecuteOrDelayUntilScriptLoaded(func, depScriptFileName)
{
   ULSxSy:;
   depScriptFileName=depScriptFileName.toLowerCase();
   var eventName="sp.scriptloaded-"+depScriptFileName;
   return ExecuteOrDelayUntilEventNotified(func, eventName);
}

Internally the ExecuteOrDelayUntilScriptLoaded method maintains a global array of eventsInfo objects. Each eventInfo object contains a property named notified and an array of jobs that represents the functions that need to executed when the event (fileName) occurs. The event is fired by each file by making a call to the NotifyScriptLoadedAndExecuteWaitingJobs("filename") method. This method sets the notified property of the corresponding eventinfo object to true. Unless this property is true, the SOD framework ensures that the associated function is not executed.

If you intend to perform update operations on the SharePoint object, there is one last thing you need to add to your page before you can use the object model for any update operation. You need to add an entry for the FormDigest tag to generate a Security Token based on current user, date and time.

<SharePoint:FormDigest runat="server" />

This generates a security validation when the page is requested and the security token is returned to the user. When the form is submitted to the server, SharePoint verifies that the security validation has not changed. The security validation is specific to a user, site, and time period and expires after a configurable amount of time.

Retrieving Data from Lists and Libraries

The SharePoint team did a great job in ensuring that there is significant similarity in the server and client object models with regards to their syntax and behavior. If you have developed in SharePoint by using the server object model, you likely noticed that most operations in the client object model are similar to the operations you perform when using the server object model.

The following discussion demonstrates some common list operations that can be performed using JSOM. You may want to display the monthly sales of an employee and track them against the annual target sales. The sales target is defined based on their role in the organization. You want to provide a Sales Target View where management can view the current sales achieved by an employee and compare it against its sales target. You select an employee from a list that displays the sales achieved by the employee. Finally, you want to show whether the employee is an "Achieved", "Lagging Behind" or "Super Performer" by comparing the total of the sales achieved with the configured sales target for the employee role.

For this purpose, a simple Web Part and some custom lists has been created that allows the users to select an employee and then display their sales information. First, create a custom list called Employee which stores general information about the employee (no AD sync for now). The following diagram shows how the Employee list looks.

Figure 4. Employee list

The sales target is based on a role and stored in another list named SalesTarget.

Figure 5. SalesTarget list

To track the monthly sales for each employee, another list named Sales is created which stores details about each sale associated with the employee.

Figure 6. Sales list

The UI looks similar to the following.

Figure 7. User interface

Retrieving All Items in a List

To begin, you want to display all the employees in the Employee list so that management can choose which employee data to view. For this purpose, you add a button named GetEmployees and bind the Click event of this button to call a JavaScript method. The method leverages JSOM to populate a radio list with all employees in the organization. The following is a sample of the get_employees method.

function get_Employees(control) {
   try {
      this.baseControl = control;
      this.controlToLoad = control + "_chkEmployeeList";
      var context = new SP.ClientContext.get_current();
      // Load the web object 
this.web = context.get_web();
      //Get the list
      var list = this.web.get_lists().getByTitle('Employee');
      // Get all the items in the list
      employees = list.getItems(''); 
      // Load the web in the context and retrieve only selected columns to improve performance 
      context.load(this.employees, 'Include(ID,EmployeeName,Role)');
      //Make a query call to execute the above statements
      context.executeQueryAsync(Function.createDelegate(this, this.get_Employees_onSuccess), Function.createDelegate(this, this.get_Employees_onFailure)); 
} 
   catch (e)
{ 
   alert("An error occurred while fetching data. Please contact your system administrator.");

To analyze what is happening in the get_Employees method, consider the following:

  1. First, you retrieve the current context by calling SP.ClientContext.get_Current. Remember that because the JSOM is running under the current site context, you do not need to specify any Url to connect to.

  2. When you have the context, a call is made to get the current web this.web = context.get_web.

  3. The get_lists method of the current web object returns all of the lists in the current web and the getByTitle method filters it down to the Employee list.

  4. Now, you simply call the getItems method on the list. Notice that, in this case, you pass an empty string to specify that all items are returned. You must pass an empty string here; if you simply pass nothing as a parameter, you will generate an exception.

  5. The context type provides a load method which is responsible for loading objects and collections from the server. The SP.Context type provides two variants of load which serve different purposes:

    • Load: This is also called as an In-Place load. This load variant should be used when you want to load objects and collection and maintain their state through multiple requests. Essentially, whatever object that you pass into the load method is populated and can be used as-is in subsequent requests.

    • LoadQuery: The LoadQuery variant returns a new instance or collection every time it is called. This is beneficial when you want to return an enumerator to the object which you want to maintain yourself.

      Both of the variants can take a parameter that defines which columns to return. For loading a singular object, you simple pass the names of the columns separated by commas as follows:

      context.load(<object>,'<Field1>','<Field2>','<Field3>');
      

      In case the object is a collection, you can still specify the columns to include in the load operation by using the following format Include(<Column1>, <Column2>,<Column3>, …) format.

      context.load(<objectCollection>,'Include(<Field1>,<Field2>,<Field3>');
      

      Note that if you want to access the child properties of an object, you must load the object (by calling the ExecuteQueryAsync method) before you can access it; otherwise, you will generate an exception such as the following:

      The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

    • The client object model provides you with the flexibility of executing statements in batches. This is a major performance boost because you do not have to go back and forth to the server to access each object. Considering the previous example, you are making calls on the context, web, and list objects but do not have instances of these objects available as of yet. Only when you make a call to the ExecuteQueryAsync method is a request generated and then sent to the server for processing.

      JSOM only supports the asynchronous version of ExecuteQuery and so you need to provide two callback methods whenever you make a call to ExecuteQueryAsync; these methods specify the success and failure callback methods to call on the client when the request has been processed.

    • When the query has been executed, a call is made to the success or failure callback method depending on the response returned. You can then access properties and method for the loaded object. For example, the following code snippet uses the getEnumerator method to retrieve the returned employee collection and then access the FieldValues of each item by using the get_item ('<FieldName>') methods.

      function get_Employees_onSuccess() {
         // Get the collection
         var employeeCollection = this.employees.getEnumerator();
         // get the control
         var chkBoxList = document.getElementById(this.controlToLoad);
         // get the checkbox group
         while (employeeCollection.moveNext()) {
            var employee = employeeCollection.get_current();
            addRowForEmployeeList(this.controlToLoad, employee.get_item('ID'), employee.get_item('EmployeeName'), employee.get_item('Role'));
         } 
      }
      function get_Employees_onFailure() {
         alert("An error occurred while fetching data. Please contact your system administrator.");
      }
      

Retrieving Specific Items by Id

JSOM supports properties and methods similar to the server object model to retrieve specific items. The following code snippet retrieves an object based on it ListItem ID.

function get_EmployeeById(employeeId) { 
    try { 
        var context = new SP.ClientContext.get_current(); 
        this.web = context.get_web(); 
        var list = this.web.get_lists().getByTitle('Employee'); 
        this.employee = list.getItemById(employeeId); 
        context.load(this.employee, 'EmployeeName', 'Role'); 
        context.executeQueryAsync(Function.createDelegate(this,  this.get_Employee_onSuccess), Function.createDelegate(this, this.get_Employee_onFailure)); 
    } 
    catch (e) {

alert("An error occurred while fetching data. Please contact your system administrator."); 
}

}

Retrieving Specific Items by Using CAML

You can also use the SharePoint CAML query language to filter data when loading objects. The client object model provides a SP.CamlQuery type that is used to pass a CAML query when the object is loaded. Simply assign your CAML query string to the set_viewXml method of CamlQuery object and pass it to the object that supports it (for example, getItems(CamlQuery).

In the following code, you use a CAML query to retrieve the sales data for an employee:

function get_EmployeeSales(employeeName) {
   try {
      this.controlToLoad = this.baseControl + "_" + "tblEmployeeSales";
      var context = new SP.ClientContext.get_current();
      // Load the web object 
this.web = context.get_web();
      //Get the list
      var list = this.web.get_lists().getByTitle('Sales');
      // Get all items based on query
      var query = '<View Scope=\'RecursiveAll\'>' +
'<Query>' +
'<Where>' +
'<Eq>' +
'<FieldRef Name=\'EmployeeName\' />' +
'<Value Type=\'LookUp\'>' + employeeName + '</Value>' +
'</Eq>' +
'</Where>' +
'</Query>' +
'</View>';
      var camlQuery = new SP.CamlQuery();
      camlQuery.set_viewXml(query);
      this.salesDetails = list.getItems(camlQuery); 
      // Load the web in the context and retrieve only selected columns to improve performance 
      context.load(this.salesDetails, 'Include(ID,EmployeeName,SalesAchieved,SaleDate,Customer,Title)');
      //Make a query call to execute the above statements
      context.executeQueryAsync(Function.createDelegate(this, this.get_EmployeeSales_onSuccess), Function.createDelegate(this, this.get_EmployeeSales_onFailure)); 
   }
catch (e) {
   alert("error occurred" + e.toString());
}
}

Property Getters and Setters in JSOM

If you look closely at the type signatures, you will notice that the JSOM properties are different in their naming conventions as compared to CSOM or the server object model. Basically, JSOM provides a getter and setter model for most properties of SharePoint objects. Any value that needs to be accessed can be obtained by using the get_<PropertyName> methods for the corresponding object; similarly any property assignments can be performed by using the set_<PropertyName> methods for the objects. You can find information about the various methods available in the SP namespace.

Manipulating Data in Lists and Libraries

In this part of the series, you perform item manipulation operations on a list.

In a previous section, it was stated that for any manipulation operation, it is a requirement that a FormDigest tag be referenced before you can perform these operations. The following code adds a control to your container.

<SharePoint:FormDigest runat="server" />

Add a New Item to the List

Adding a new item to a list is fairly simple. The SP namespaceof the client object model provides <Object>CreationInformation classes for various objects such as Web, List, ListItem, ContentType, FieldLink, Groups, User, Role Definition, and View to name a few. You can use these creation classes to construct the object definition and then use the native methods to create the object in SharePoint.

The following code snippet adds a new sales entry for an employee to the Sales list created in the previous section. In this case, the ListItemCreationInformation object creates the new item in the root of the list.

function addNewSale(employeeId, salesachieved, customer, description) {
   // Get the current context
   var context = new SP.ClientContext.get_current();
   // Get the web
   var web = context.get_web();
   // Get the Sales list
   var list = web.get_lists().getByTitle('Sales');
   // create the ListItemInformational object
   var listItemInfo = new SP.ListItemCreationInformation();
   // add the item to the list
   var listItem = list.addItem(listItemInfo);
   // Assign Values for fields
   listItem.set_item('SalesAchieved', salesachieved);
   listItem.set_item('Customer', customer);
   listItem.set_item('Title', description);
   //Lookup field need to be catered using FieldLookUp value
   var employeeNameValue = new SP.FieldLookupValue();
   employeeNameValue.set_lookupId(employeeId);
   listItem.set_item('EmployeeName', employeeNameValue);
   // Adding value for a Date Field
   var currDate = new Date();
   listItem.set_item('SaleDate', currDate);
   listItem.update();
   //Make a query call to execute the above statements
   context.executeQueryAsync(Function.createDelegate(this, this.on_addSales_Success), Function.createDelegate(this, this.on_addSales_Failure));
}
function on_addSales_Success() {
   alert("Sale successfully created.");
}
function on_addSales_Failure() {
   alert("Error while creating new Sales.");
}

If you want to create an item inside a specific folder, you use the folderUrl property of the ListItemCreationInformation type. When dealing with document libraries, you need to provide the name of the file when uploading the document. You can then use the leafName property to specify the name of the list Item.

The set_Item (<fieldName>, <fieldValue>) method assigns values for all the fields in the list. Finally, the Update method is called along with the ExecuteQueryAsync method to submit the changes.

Updating an Existing Item

To update an item, you need to create a get operation and then call the Update method on the item.

function updateSales(salesId, salesAchieved) { 
   var context = new SP.ClientContext.get_current();
   var web = context.get_web();
   var list = web.get_lists().getByTitle('Sales');
   var salesItem = list.getItemById(salesId);
   salesItem.set_item('SalesAchieved', salesAchieved);
   salesItem.update();
   context.executeQueryAsync(Function.createDelegate(this, this.on_UpdateSales_Success), Function.createDelegate(this, this.on_UpdateSales_Failure));
}
function on_UpdateSales_Success() {
   alert("Sale Item updated successfully.");
}
function on_UpdateSales_Failure() {
   alert("Error while updating Sales.");
}

Deleting an Item from a List

Deletion from a list is relatively straightforward as shown in the following.

function deleteSaleItem(saleId) { 
   var context = new SP.ClientContext.get_current(); 
   var web = context.get_web(); 
   var list = web.get_lists().getByTitle('Sales'); 
   var itemToDelete = list.getItemById(saleId); 
   itemToDelete.deleteObject(); 
   context.executeQueryAsync(Function.createDelegate(this, this.on_DeleteSales_Success), Function.createDelegate(this, this.on_DeleteSales_Failure)); 
}
function on_DeleteSales_Success() {
   alert("Sale Item updated successfully.");
}
function on_DeleteSales_Failure() {
   alert("Error while updating Sales.");
}

Conclusion

In this article, you have gained a basic understanding of the JavaScript client object model known as JSOM. The JavaScript client object model is a great addition to the SharePoint 2010 development kit and is useful in scenarios where data needs to access and manipulated after the page has been loaded. The object model provides an asynchronous way of displaying data on your Web Parts and Web Pages. It is simple to use and can be loaded even from within an editor similar to the content editor Web Part.