Using the MatchPoint AJAX Framework within a SharePoint WebPart
Date: 23.11.2011
In my last blog post "How to implement a Custom SharePoint Web Part using the MatchPoint Configuration FrameWork" I demonstrated how to use the MatchPoint Configuration Framework by means of a sample web part (DateWebPart). This DateWebPart simply displays the current date and time.
Let's stick to this DateWebPart and use it to have a look to another feature of the MatchPoint API. In this blog post I will introduce the AJAX capabilities of the MatchPoint API by using them within this web part. The MatchPoint API provides a full featured AJAX framework, which can be used to implement custom AJAX enabled components.
How It Works
A web part or control using the Ajax Framework consist of a C# class and a JavaScript code behind file.
The C# class is a ASP.Net control and defines the HTML structure and the AJAX callback methods. During the load event it registers itself at the AJAX framework in order to behave as AJAX enabled control on the client side.
The JavaScript code behind file defines a JavaScript class, which defines the methods calling the AJAX callback methods or acting as event handlers for the HTML controls. The AJAX framework creates an instance of this class and an additional proxy class during the loading of the page.
The Goal
The DateTimeWebPart will be extended by adding the possibility for the user to select the time zone, in which the current date and time is displayed. The available time zones are presented in drop-down menu. When a user switches between the time zones the refresh of the displayed date and time is done via an AJAX callback. The configuration of the web part remains the same as of the DateWebPart presented in my last blog post, that's why we will reuse it and simply reference it.
The WebPart
The web part class has to extend the Colygon.MatchPoint.Core.WebParts.BaseWebPart<> class in order to gain all benefits from the MatchPoint Application Framework like the simplified configuration etc.
public class AjaxDateWebPart : BaseWebPart<DateWebPartConfiguration>
The first step to make a web part or a control using the Ajax Framework is to register it at Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorManager by calling the RegisterBehavior method, which is usually done in the OnLoad event.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
JavaScriptBehaviorManager.RegisterBehavior(this, typeof(AjaxDateWebPart));
}
This registration causes referencing the JavaScript code behind file and the generation of a JavaScript proxy class in the page containing this web part when it is rendered.
The next step is to create the content of the web part by adding some controls to it.
protected override void CreateChildControls()
{
base.CreateChildControls();
try
{
SPTimeZone currentZone = SPHelper.GetCurrentWeb().RegionalSettings.TimeZone;
TimeZoneSelect = new HtmlSelect();
Controls.Add(TimeZoneSelect);
foreach (SPTimeZone z in SPRegionalSettings.GlobalTimeZones)
{
TimeZoneSelect.Items.Add(new ListItem(z.Description, z.ID.ToString()));
}
TimeZoneSelect.SelectedIndex = TimeZoneSelect.Items.IndexOf(new ListItem(currentZone.Description, currentZone.ID.ToString()));
Label = new Label();
Label.Text = currentZone.UTCToLocalTime(DateTime.UtcNow).ToString(Configuration.FormatString);
Label.ForeColor = Color.FromKnownColor(Configuration.FontColor);
Label.Font.Size = new FontUnit(Unit.Point(Configuration.FontSize));
Panel p = new Panel();
p.Controls.Add(Label);
Controls.Add(p);
BackColor = Color.FromKnownColor(Configuration.BackgroundColor);
}
catch (Exception ex)
{
HandleError(ex);
}
}
Actually, two controls are added. A HTML select control, which gives the user the option to select a time zone. And the other control is a label, that renders the current time in the manner as specified in the configuration.
The two controls are defined as fields in the class, since they are accessed in the JavaScript code behind file as seen later. But simply defining a field doesn't make it available in the JavaScript code behind file. A field or a property has to be marked with the Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorVariableAttribute to make it work.
[JavaScriptBehaviorVariable]
protected Label Label;
[JavaScriptBehaviorVariable]
protected HtmlSelect TimeZoneSelect;
By doing so it can be accessed in the JavaScript code behind file by calling this.<MemberName>.
The Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorVariableAttribute can take one or more flags of the Colygon.MatchPoint.Core.Ajax.SyncMode enum. These flags specify when and how the values of the fields or properties marked with the Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorVariableAttribute are available:
- IncludeInCallback: The value is synchronized between callbacks, which means that it is available in a server side AJAX method call.
- IncludeInPostBack: The value is posted to the server when a post request is performed. For example if the value has been modified on the client side, the modified value is posted.
- Encrypt: The value is encrypted before it is sent to the client, which implies that it is not usable in the JavaScript code behind file.
- SerializeBinary: The value is serialized in the binary format to reduce the size of it. Same as for Encrypt it is not usable in the JavaScript code behind file.
- IncludeInSourceUrl: The value is appended as request parameter to the URL of the Source URL parameter value, when navigating away from the page.
One thing that is left is the callback method we wan't to use from within the JavaScript code behind file. The designated method has to be public and decorated with the Colygon.MatchPoint.Core.Ajax.AjaxMethodAttribute.
[AjaxMethod]
public string GetFormattedDateTime(int zoneId)
{
SPTimeZone zone = SPRegionalSettings.GlobalTimeZones.OfType<SPTimeZone>().FirstOrDefault(z => z.ID == zoneId);
if (zone == null)
{
throw new TimeZoneNotFoundException(zoneId);
}
return zone.UTCToLocalTime(DateTime.UtcNow).ToString(Configuration.FormatString);
}
This method gets the time zone ID selected by the user and returns the current time of the selected zone formatted by the configured format string.
As you can see, this callback method accesses the Configuration property defined by the base class Colygon.MatchPoint.Core.WebParts.BaseWebPart<>. This is is possible, since the Configuration property is synchronized for the callback because of the Colygon.MatchPoint.Core.Ajax.SyncMode.IncludeInCallback flag of an assigned Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorVariableAttribute.
The JavaScript Code Behind File
The code behind file of a web part or a control consists of a JavaScript class that specifies functions to execute AJAX callbacks and other functionality like event handlers of the controls used in the web part.
MP.Samples.AjaxDateWebPart = function()
{
this.Setup = function()
{
$(this.TimeZoneSelect).change($$.Delegate.Create(this, this.TimeZoneSelect_Change));
};
this.TimeZoneSelect_Change = function()
{
var zoneId = $(this.TimeZoneSelect).val();
this.Callback.GetFormattedDateTime(zoneId, $$.Delegate.Create(this, this.GetFormattedDateItem_Callback));
};
this.GetFormattedDateItem_Callback = function(res)
{
if (res.Exception)
{
alert(res.Exception.Message);
return;
}
$(this.Label).text(res.Value);
};
}
The JavaScript class must be named with a namespace prefix plus the name of the type passed when calling the Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorManager.RegisterBehavior method.
The namespace has to be defined in the AssemblyInfo.cs file of the assembly containing the C# class by the Colygon.MatchPoint.Core.Ajax.JavaScriptBaseAttribute. This attribute takes the namespace name and the URL of the location where code behind files are placed.
[assembly: JavaScriptBase("MP.Samples", "/_layouts/Colygon.MatchPoint.Samples/scripts")]
Additionally the class has to define a Setup function. This function is called during the page load by the MatchPoint AJAX Framework and is intended to implement initialization logic like registering event handler methods.
The MatchPoint AJAX Framework creates an instance of the class during the page load and defines some predefined instance variables on it, which can be accessed inside the class.
- Control: The DOM element of the control specified when calling Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorManager.RegisterBehavior in the C# class.
- Control.Behavior: The instance of this class.
- Callback: The proxy object containing all AJAX callback methods as defined in the C# class by the Colygon.MatchPoint.Core.Ajax.AjaxMethodAttribute.
Additionally all the properties and fields of the C# class decorated with a Colygon.MatchPoint.Core.Ajax.JavaScriptBehaviorVariableAttribute can be accessed by calling this.<MemberName>.
In our class the method TimeZoneSelect___Change calls the AJAX method defined in C# class by invoking this.Callback.GetFormattedDateTime. It passes the selected time zone ID and a delegate to this function. The delegate is executed asynchronously after the AJAX callback has been executed. The invoked delegate function gets as parameter the result object of the callback and updates the Label control with the value of it.
The Deployment
The deployment process of this web part is almost the same as for the web part described in my last blog post mentioned erlier. Additionally to the steps defined there, you must copy the JavaScript code behind file to location inside the TEMPLATE/LAYOUTS folder of the SharePoint root folder (14), that you have specified in Colygon.MatchPoint.Core.Ajax.JavaScriptBaseAttribute. In this example it is /Colygon.MatchPoint.Samples/scripts.
And that's it for the moment. I hope, that I could awake your interest and you got an impression of how to use the MatchPoint AJAX Framework.