Saturday, November 19, 2011

How to call server method with JavaScript and display the result in SharePoint 2010 application page

In this article will try to show you one way you can call server methods using JavaScript from SharePoint page or user control and show the result. For this demonstration I will use simple case: display details about the current logged user. We will load the details from SharePoint and display them in a pop-up (lightbox).

 
There few components we need to develop in order to make this works:
  • web part/layouts page/user control 
  • JavaScript file that will call some of the server side method
  • Update the page to implement ICallbackEventHandler
  • JSON serializer that will return the data to the page in JSON format 
  • custom user control deployed in ControlTemplates that will display the result
Even it looks a bit complicated, once you understand it and see it working you will ind out how easy is to customize it or extend it to fit your need. Lets start one by one..


Step 1: Create simple page (deployed to _layouts). This page will be simple enough and have only 2 elements:
  - JavaScript file that contain the javascript finctions
  - user control that will display the result


The page "ContractInfo.aspx" is simple and looks like this. Just 1 user control and 2 divs that will display the user profile or error message

Step 2: JavaScript file that will call some of the server side method

JS function looks absolutely normal - nothing special:

function ShowDialog(userId) {
    $('#profile-details').show();

    try {
        //load data
        CallServer(userId); 
    }
    catch (err) {
       $('#error-details-panel').show();
        return false;
    }


The important call is CallServer(userId). See step 3 for more details


 Step 3: Update our .aspx  page to inherit ICallbackEventHandler interface.
public partial class ContractDetails: ICallbackEventHandler{ .. }

There are 2 methods we need to implement:
string GetCallbackResult();
void RaiseCallbackEvent(string eventArgument);



Also we need to register the JavaScript function CallServer(userId) using the ClientScriptManager. For this demo I just put it in the PageLoad method.So the entire implementation of the ContractInfo.aspx.cs looks like this:

 Step 4: JSON serializer that will return the data to the page in JSON format
 Now, after we defined the GetCallbackResult() this method will actually take the user profile details using the provider developed by us. As it was just created for this demo, there is nothing fancy about it - just load the user data from the Active Directory. The important key here is the JSON serializer - see userInfo.ToJSON();

This method will looks like this:

   public string ToJSON()
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            string json = serializer.Serialize(this);
            return json;
        }
This will basically get the UserInfo object and turn it into JSON format, so the page can read it when we pass it back to the page. Of course it is possible to return some XML also or whatever is easier for you.

 Step 5: Create custom user control (deployed in ControlTemplates) that will display the results returned by using JSON. This user control is actually just a simple .ascx without any code behind. It will be used only to display the data returned by the server side code.
Here is shown how this ProfileDetails.ascx looks like:

If you look at the PageLoad of our initial ContactInfo.aspx you will note the callback event reference: 

String cbReference = clientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");


ReceiveServerData is actually JavaScript function that read the JSON response and show the data.

function ReceiveServerData(result) {

        var myProfileData = null;
        try { myProfileData = eval('(' + result + ')'); } catch (err) { }
      
    $('#firstName')[0].innerHTML = (myProfileData.FirstName == null) ? "" : myProfileData.FirstName;
        $('#lastName')[0].innerHTML = (myProfileData.LastName == null) ? "" : myProfileData.LastName;
        $('#jobTitle')[0].innerHTML = (myProfileData.JobTitle == null) ? "" : myProfileData.JobTitle;
        $('#businessPhone')[0].innerHTML = (myProfileData.BusinessPhone == null) ? "" : myProfileData.BusinessPhone;

      
        var picturePath = "/_layouts/YTT/Handlers/GetImage.ashx?acct=" + myProfileData.LoginName;
        $('#contactPhoto').attr("src", picturePath);
    }



To summarize it quickly e have the following scenario: aspx page that implement ICallbackEventHandler. This allows you to execute server code from JavaScript function, serialize the data to JSON and return it back to the page using another JavaScript function that load the data into custom user control.

No comments: