Wednesday, January 6, 2010

Project Server JS customization: SharePoint 2010 WebPart Callback Interface

SharePoint 2010 webpart client-server interoperation model provides new asynchronous callback interface which allows saving webpart’s data to server and retrieving back the operation result. New model enables users to control webpart’s view mode, perform webpart’s content validation and the asynchronous save operation with handling callbacks. The webpart save operation is tied to the global JavaScript command queue and can be triggered either by calling PDP JavaScript objects’ methods or directly by clicking the Save Ribbon button.

In this post we’ll focus on general requirements that the custom webpart should meet to support asynchronous client-server interoperation as it’s done in the Project Fields webpart.

Let’s consider client JavaScript code that is needed for the webpart having been placed on a PDP:

var WPDP_WebPartID = new object();
WPDP_WebPartID.IsDirty = false;

WPDP_WebPartID.EnablePart = function pfp_EnablePart(enabled) {
    // view mode logic
}

WPDP_WebPartID.Validate = function pfp_Validate() {
    // validation logic
    // possible return true;
}

WPDP_WebPartID.Save = function pfp_Save(ctx) {
    // server callback logic
    // possible calls of ctx.Completed() or WebForm_DoCallback() methods.
}

Let’s consider the code in detail:

WebPart JavaScript object contains at least four members: flag IsDirty and three functions: EnablePart, Validate and Save.

IsDirty flag. Signals that user has made changes to the webpart controls, e.g. entered text to input fields, selected new lookup field value etc.

EnablePart method. Accepts boolean argument “enabled” which tells webpart about current view mode. Ususally webpart set its inner controls to appropriate state according to the “enabled” agrument value. The method is called during the page loading.

Validate method. Is called right when the webpart is about to send the data back to server, usually after user clicked “Save” ribbon button. Should return a boolean value that indicates whether save method is going to be called or not. If the user entered inacceptable information into the fields, validation summary might be displayed on the page and Validate method should return “false” then. Returning “true” indicates about a successul data validation.

Save method. The most important part of the server-client webpart asynchronous interoperation. Basically, the method body should contain the WebForm_DoCallback method call that actually performs asynchronous data sending.

Among a set of the method arguments there is a couple of important ones:

  • arg holds the data collected from the webpart HTML controls.
  • ctx is a client script that is evaluated on the client prior to initiating the callback. The result of the script is passed back to the client event handler. Should be set to incoming ctx argument.

Exact WebForm_DoCallback method signature should be generated by calling ClientScriptManager.GetCallbackEventReference method (for more information check out at http://msdn.microsoft.com/en-us/library/ms153106.aspx).

E.g.:
string callBackScript = Page.ClientScript.GetCallbackEventReference(
    this,
    "arg",
    "[SaveCompletedCallback JavaScript method reference]",
    "ctx",
    "[SaveErrorCallback JavaScript method reference]",
    false);

The SaveCompletedCallback is the name of the client event handler that receives the result of the successful server event.

The SaveErrorCallback is the name of the client event handler that receives the result when an error occurs in the server event handler.

The SaveCompletedCallback and SaveErrorCallback methods examples are below.

function SaveCompletedCallback_WebPartClientID(result, ctx) {
    if (result != '') {
        SaveErrorCallback_WebPartClientID(result, ctx);
    }
    else {
        ctx.Completed();
    }
}

function SaveErrorCallback_WebPartClientID(result, ctx) {
    ctx.FailedShowInlineErrors(result);
}

The result argument is the result of the callback. The ctx.Completed() call informs about the successful callback operation, whereas the ctx.FailedShowInlineErrors(result) call shows the callback errors.

The server side webpart class should implement the ICallbackEventHandler interface:

  • The RaiseCallbackEvent method Processes the callback event, fires when the client data arrives to the server.
  • The GetCallbackResult method returns the results of the callback event.

Next time we will provide a complete webpart sample with a server-side C# webpart class, ICallbackEventHandler interface implementation and all needed JavaScript code generation.

3 comments: