C H A P T E R  7

The SharePoint 2010 Client Object Model

In previous versions of SharePoint, developers accessed content and performed operations via server side code called Server Object Model and/or used SharePoint Web Services. Now Microsoft has introduced a new way for developers to communicate with SharePoint Foundation 2010; this third way of writing code is known as Client Object Model. (SharePoint Server Object Model and SharePoint Web Services are still options). The Client Object Model (Client OM) API can be used in .NET based applications, Silverlight applications, and in ECMAScript (JavaScript) that executes in the browser. Although the Client OM API is not as rich as the Server Object Model, it has its own benefits, such as an object-oriented way of accessing SharePoint content without the complexities of Server Object Model and SharePoint Web Services, no packaging and deployment hassles, easy access to content stored in SharePoint list/libraries, quick and easy scripting, etc.

This chapter will focus on ECMAScript (JavaScript) to access the Client OM API. The concepts are same if you want to develop a Silverlight or a .NET application.

images Note Silverlight and .NET applications need reference to Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll to access the API. These two dlls can be downloaded from the server where SharePoint 2010 is installed.

How It Works

The SharePoint Client OM provides an object-oriented way of retrieving SharePoint data. Developers first need to get the client context object; through this context they can access the client objects of a site (any level in a site collection). The Client object's parent class is ClientObject and it can be used to get properties of a specific SharePoint object, etc.

Once the client application uses Client OM, the calls are converted into XML request and sent to the SharePoint server. On the server, the XML request is handled by a service called Client.svc where it translates the XML request into appropriate Object Model calls (SharePoint Server Object Model) and gets the results. After getting the results, Client.svc translates them into JavaScript Object Notation (JSON) and sends back to the Client Managed Object Model. On the client side, the JSON response is translated into ECMAScript objects for ECMAScript. This process is shown in Figure 7-1.

images

Figure 7-1. The SharePoint Client OM provides an object-oriented way of retrieving SharePoint data.

ECMAScript

ECMAScript is a JavaScript-based client-side scripting language for web pages developed by Ecma International and now supported in SharePoint 2010. The first version of ECMAScript was released in June 1997 and latest version (the fifth) was released in Dec 2009. From a developer's point of view, it's just another version of JavaScript and its SharePoint Class Library can be viewed at http://msdn.microsoft.com/en-us/library/ee538253.aspx. Commonly used JavaScript files for Client OM are CUI.js, SP.js, SP.Core.js, SP.Ribbon.js, etc. Table 7-1 lists the main classes of ECMAScript for the SharePoint Object Model.

images

images

Using Client Object Model

To create a list in SharePoint 2010 site, follow these steps:

  1. Go to the site by typing the URL in the address bar.
  2. Select Site Actions images More Options from the left top corner, as shown in Figure 7-2.
    images

    Figure 7-2. Select Site Actions images More Options

  3. On the Create form, select List from Filter By, then select Custom List and provide a name of the list, such as Product, and hit the Create button, as shown in Figure 7-3.
    images

    Figure 7-3. Select the Custom List option

  4. Select List Tools images List images Create Column, as shown in Figure 7-4.
    images

    Figure 7-4. Select List Tools images List images Create Column

  5. In the Create Column form, provide the column name as Price; Column Type as Currency; Min: as 0; and hit the OK button, as shown in Figure 7-5.
    images

    Figure 7-5. Fill out the Create Column options

images Note Now you have a list with column Title (Text) and Price (Currency).

Creating an Add Form

In this section you will create an ASPX page to add items into the product list using the Client Object Model in ECMAScript. Follow these steps to create an AddItemForm.aspx page.

  1. Open the Site in the SharePoint Designer.
  2. From the Navigation panel select All Files and then select Lists images Product, as shown in Figure 7-6.
    images

    Figure 7-6. The Product folder

  3. Right-click and point to New images ASPX. Rename the newly created page as AddItemForm.aspx, as shown in Figure 7-7.
    images

    Figure 7-7. Rename the file

  4. Click the AddItemForm.aspx and hit Yes on the warning message, as shown in Figure 7-8.
    images

    Figure 7-8. Open the page in advanced mode

  5. Select Split tab from the bottom, as shown in Figure 7-9.
    images

    Figure 7-9. The Split tab

  6. From the Style menu, select Attach images v4.master to apply the default MasterPage on your custom ASPX page.
  7. Click on PlaceHolderMain and select Create Custom Content, as shown in Figure 7-10. It will let you add your custom code into the ASPX page in the main place holder section.
    images

    Figure 7-10. Now you can create custom content

  8. Insert two HTML text boxes (txtTitle and txtPrice) and one HTML button (btnAdd, which will call the JavaScript function AddItem()) inside the PlaceHolderMain, as shown in the following code and in Figure 7-11:
    <table style="width: 100%">
            <tr>
                    <td>Title</td>
                    <td><input  id="txtTitle" name="txtTitle" type="text" /></td>
    </tr>
            <tr>
                    <td>Price</td>
                    <td><input id="txtPrice" name="txtPrice" type="text" /></td>
            </tr>
            <tr>
                    <td></td>
                    <td><input name="btnAdd" type="button" value="Add" onclick=images
    "javascript:AddItem();"/></td>

            </tr>
    </table>
    images

    Figure 7-11. HTML code and resulting text boxes

  9. Add the ECMAScript in Listing 7-1 right above the HTML table.

    Listing 7-1. ECMAScript to Add an Item

    <script type="text/javascript">

    ExecuteOrDelayUntilScriptLoaded(MainFunction, "sp.js");

    var objContext = null;
    var objWeb = null;
    var objList = null;
    var objItem = null;
    var objListItemCreationInfo = null;


    function MainFunction()
    {
    }


    function AddItem()
    {

            var strTitle = document.getElementById('txtTitle').value;
            var strPrice = document.getElementById('txtPrice').value;


            objContext = new SP.ClientContext.get_current();
            objWeb = objContext.get_web();
            objList = objWeb.get_lists().getByTitle("Product");

            objListItemCreationInfo = new SP.ListItemCreationInformation();

            objItem = objList.addItem(objListItemCreationInfo);
            objItem.set_item('Title', strTitle);
            objItem.set_item('Price', strPrice);
            objItem.update();

            objContext.load(objItem);

            objContext.executeQueryAsync(Function.createDelegate(this, this.AddItemSuccess),images
     Function.createDelegate(this, this.AddItemFail));

            document.getElementById('txtTitle').value = '';
            document.getElementById('txtPrice').value = '';
    }

    function AddItemSuccess(sender, args)
    {
            alert('Item added successfully.'),
    }

    function AddItemFail(sender, args)
    {
        alert('Item is not added.'),
    }
    </script>
  10. Save the code and stop editing the page from SharePoint Designer.
  11. Access the AddItemForm.aspx via a browser (e.g. http://sps2k10dev01:5000/NxGen/Lists/Product/AddItemForm.aspx). Provide the product title and price, and then press the Add button, as shown in Figure 7-12.
    images

    Figure 7-12. Product title and price

  12. Access the AllItems.aspx page (http://sps2k10dev01:5000/NxGen/Lists/Product/AllItems.aspx ) of the product list. You should see the newly added item displayed there, as shown in Figure 7-13.
images

Figure 7-13. The new item

Explanation of the Add Code

The first step to using the Client Object Model in ECMAScript is to load the SP.js file, which can be loaded by calling the ExecuteOrDelayUntilScriptLoaded(Func, "sp.js") method. Along with loading the sp.js file, this method also calls the MainFunction() which can be used as OnLoad or initialized the function on the page.

images Note SP.js is referred to in ECMAScript and Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll are referred to in .NET code to access the Client Object Model. The two dlls could be located at C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTSClientBin on the server.

Once the page is called, the MainFunction() executes (which, of course, isn't doing anything in your example). When the Add button is clicked, after filling the text fields, the AddItem() method is called. In the AddItem() method, the values from two text boxes are stored in the strTitle and strPrice variables, and then the current context of the site is loaded using SP.ClientContext.get_current(), which is used to load the current site using get_web() method. Once you have the current site, you can access the lists, document libraries, etc. The current site's lists will be called by the get_lists() method, and then the product list will be pointed to by calling getByTitle(strListName) method and will pass it the list name.

The objListItemCreationInfo object is created to store the information to create the list item and is passed to the List object by calling the addItem() method. The item object is then populated with the values by calling set_item(strColumnName, strValue) method, and the update() method is called to add the item to the product list. The current context's load item is called to only load the item object and to avoid the performance hit of loading all the objects.

The actual execution will take place when the executeQueryAsync() method of the current context is called. This method executes asynchronously on the server and takes two function names (AddItemSuccess and AddItemFail) as parameters to call them if the execution succeeds or fails respectively. One of the AddItemSuccess() and AddItemFail() functions will be called and will display the success or failure method to show how the execution of executeQueryAsync() went.

Creating an Edit Form

Creating an Edit form is much like creating the Add form, so I will skip some of the steps and jump directly into the main functionality.

  1. Open the Site in SharePoint Designer and go to your Product list.
  2. Create a new page called EditItemForm.aspx and add two HTML text boxes (txtTitle and txtPrice) and one HTML button (btnUpdate, which will call the JavaScript function UpdateItem()) inside PlaceHolderMain, as shown here and in Figure 7-14:
    <table style="width: 100%">
            <tr>
                    <td>Title</td>
                    <td><input  id="txtTitle" name="txtTitle" type="text" /></td>
    </tr>
            <tr>
                    <td>Price</td>
                    <td><input id="txtPrice" name="txtPrice" type="text" /></td>
            </tr>
            <tr>
                    <td></td>
                    <td><input name="btnUpdate" type="button" value="Update" onclick=images
    "javascript:UpdateItem();"/></td>
            </tr>
    </table>
    images

    Figure 7-14. Creating an Edit form

  3. Add the ECMAScript in Listing 7-2 right above the HTML table.

    Listing 7-2. ECMAScript for Updating Products

    <script type="text/javascript">

    ExecuteOrDelayUntilScriptLoaded(MainFunction, "sp.js");

    var strID = null;
    var objContext = null;
    var objWeb = null;
    var objList = null;
    var objItem = null;
    var objCollectionListItem = null;

    function MainFunction()
    {
            strID = QueryString("ID");

            objContext = new SP.ClientContext.get_current();

            objWeb = objContext.get_web();
            objList = objWeb.get_lists().getByTitle("Product");

            var objQuery = new SP.CamlQuery();
            objQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name="ID"/><Value Type=images
    "Number">'+ strID +'</Value></Eq></Where></Query><ViewFields><FieldRef Name="Title"/>images
    <FieldRef Name="Price"/></ViewFields></View>'),
            objCollectionListItem = objList.getItems(objQuery);

            objContext.load(objCollectionListItem);

            objContext.executeQueryAsync(Function.createDelegate(this, this.LoadItemSuccess),images
     Function.createDelegate(this, this.LoadItemFail));

    }

    function LoadItemSuccess(sender, args)
    {
            var listItemEnumerator = objCollectionListItem.getEnumerator();

        //This loop will run only once
        while (listItemEnumerator.moveNext())
        {
            var objTempItem = listItemEnumerator.get_current();

            document.getElementById('txtTitle').value = objTempItem.get_item('Title'),
            document.getElementById('txtPrice').value = objTempItem.get_item('Price'),
            }
    }

    function LoadItemFail(sender, args)
    {
            alert('Item loading failed.'),
    }

    function QueryString(parameter)
    {
            var loc = location.search.substring(1, location.search.length);
            var param_value = false;
            var params = loc.split("&");

            for (i=0; i<params.length;i++)
            {
                    param_name = params[i].substring(0,params[i].indexOf('='));
                    if (param_name == parameter)
                    {
                            param_value = params[i].substring(params[i].indexOf('=')+1)
                    }
            }

            if (param_value)

            {
                    return param_value;
            }
            else
            {
                    return false;
            }
    }


    function UpdateItem()
    {

            var strTitle = document.getElementById('txtTitle').value;
            var strPrice = document.getElementById('txtPrice').value;


            objContext = new SP.ClientContext.get_current();
            objWeb = objContext.get_web();
            objList = objWeb.get_lists().getByTitle("Product");

            objItem = objList.getItemById(strID);
            objItem.set_item('Title', strTitle);
            objItem.set_item('Price', strPrice);
            objItem.update();

            objContext.executeQueryAsync(Function.createDelegate(this, this.UpdateItemSuccess),images
     Function.createDelegate(this, this.UpdateItemFail));

            document.getElementById('txtTitle').value = '';
            document.getElementById('txtPrice').value = '';
    }

    function UpdateItemSuccess(sender, args)
    {
            alert('Item updated successfully.'),
    }

    function UpdateItemFail(sender, args)
    {
        alert('Item is not updated.'),
    }
    </script>
  4. Save the page.
  5. Access the EditItemForm.aspx via browser and pass it a valid ID of the item already existing in the Product list (e.g. http://sps2k10dev01:5000/NxGen/Lists/Product/EditItemForm.aspx?ID=9).
  6. Loading the page will display the title and price of the item whose ID is passed and hitting the Update button will update the item, as shown in Figure 7-15 and 7-16.
images

Figure 7-15. Update the item

images

Figure 7-16. The new Product info

Explanation of the Edit Code

As mentioned earlier, the first step to using the Client Object Model in the ECMAScript is to load the SP.js file, which can be loaded by calling the ExecuteOrDelayUntilScriptLoaded(Func, "sp.js") method. Along with loading the sp.js file, this method also calls the MainFunction(), which can be used as OnLoad or to initialize a function on the page.

Once the page is called, the MainFunction() executes, which will call QueryString() to get the value of the querystring ID. The Product list is called by getting the current context, then the current site and all the lists in the current site. objQuery will hold the CAML (Collaborative Application Markup Language) query XML to execute against the list to retrieve the list content. In the example, the following CAML is used:

<View>
   <Query>
      <Where>
         <Eq><FieldRef Name="ID"/><Value Type="Number">'+ strID+'</Value></Eq>
      </Where>
   </Query>
<ViewFields>
   <FieldRef Name="Title"/><FieldRef Name="Price"/>
</ViewFields>
</View>

This CAML query tells the API to get the items where the ID column value is provided by the strID variable. In <ViewFields/> tag, two columns have been mentioned that need to be returned for the selected items.

If the execution of the executeQueryAsync() method succeeds, then LoadItemSuccess() will iterate through all the returned items and will populate the text boxes for the user to update the values.

images Note In this example, the loop will run once as there will be only one item with the provided ID.

The Update button will call the UpdateItem() method, which will get the list item by ID by calling the getItemById(intID) method of the list object. It will set the new values for the columns and update the item by calling the update() method of the item object and then calling the executeQueryAsync() method.

Delete Functionality in the Edit Form

The Edit form (EditItemForm.aspx) can be upgraded with the delete functionality easily. The process is similar to updating a list item but you call a delete method instead of an update method.

  1. Edit the EditItemForm.aspx in SharePoint Designer.
  2. Update the HTML by adding a new HTML button, btnDelete, which will call the JavaScript function DeleteItem(), as shown in Figure 7-17.
    images

    Figure 7-17. The delete functionality

  3. Add the code in Listing 7-3 to the <script> tag.

    Listing 7-3. Code for <script> Tag

    function DeleteItem()
    {
            if(window.confirm('Are you sure you want to delete this item?'))
            {
                    objContext = new SP.ClientContext.get_current();
                    objWeb = objContext.get_web();
                    objList = objWeb.get_lists().getByTitle("Product");

                    objItem = objList.getItemById(strID);
                    objItem.deleteObject();

                objContext.executeQueryAsync(Function.createDelegate(this,images
     this.DeleteItemSuccess), Function.createDelegate(this, this.DeleteItemFail));
            }
    }

    function DeleteItemSuccess(sender, args)
    {
            window.location = "AllItems.aspx";
    }

    function DeleteItemFail(sender, args)
    {
        alert('Item is not updated.'),
    }

    images Note If you plan to use this code separately, don't forget to add the following line in the <script> tag:

    ExecuteOrDelayUntilScriptLoaded(MainFunction, "sp.js");

  4. Browse the EditItemForm.aspx page via browser and pass the ID of an existing item. (e.g. http://sps2k10dev01:5000/NxGen/Lists/Product/EditItemForm.aspx?ID=7) and press the Delete button, as shown in Figure 7-18.
images

Figure 7-18. Deleting an item

The item will be deleted and user will be redirected to the AllItems.aspx page where the deleted item does not exist, as shown in Figure 7-19.

images

Figure 7-19. The item no longer exists.

Explanation of the Delete Code

Once the Delete button is clicked, the item is loaded by calling the getItemById(intID) method of the list object and is deleted by calling the deleteObject() method of the item object. Once again, the actual execution will be taken placed when executeQueryAsync() is called.

Why executeQueryAsync()?

While using SharePoint Client OM in .NET or Silverlight application, both ExecuteQuery() and ExecuteQueryAsync() are available to developers. ExecuteQuery() is a synchronous call, which means the client application will wait for the server's response before jumping onto next line of code. ExecuteQueryAsync() is an asynchronous call, so code continues to execute; the client application doesn't wait for server's response and will execute the next line of code. Each function has its advantages and disadvantages. For example, if the next piece of code needs input from server, it's okay to use ExecuteQuery(); however, if the server's response gets delayed, the application will simply hang there. This problem is solved by ExecuteQueryAsync() where the client application(especially when using the Client OM API in the browser) doesn't wait for the server response so the application won't hang if there's a delay in the response from server. Server response delay can be caused by multiple things such as network traffic, huge calculation, slow servers, etc.

images Note While executing the code, developers should massage the code to use ExecuteQueryAsync() to avoid hanging the browser due to server response delay. If ExecuteQuery() has been used in the application and browser hangs while waiting for server response, there is a good chance that the whole browser instance will crash; that means any applications running in other tabs could lose data. In ECMAScript, only the executeQueryAsync() method available and that is being used in this chapter.

Summary

ECMAScript is a JavaScript-based client-side scripting language that is now supported in SharePoint 2010 and can be used to access Client Object Model. Users can write ECMAScript in an ASPX page for SharePoint 2010 sites and can manipulate the SharePoint content without the code compilation, Server Object model, or getting involved in the complexities of web services.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.80.34