Oct
27
2008

How To Create AJAX-enabled SharePoint Web Part with UpdatePanel and UpdateProgress in 10 minutes

In this post I am going to show you how you can setup your SharePoint site to support Microsoft ASP.NET AJAX framework and create a basic AJAX-enabled SharePoint Web Part. You can find many great articles on MSDN on how to do these and they explained in more details, but if you are looking for a way to get it up and running in 10 minutes, this is it.

James Tsai .NET SharePoint Blog - AJAX enabled webpart 

James Tsai .Net SharePoint Blog - AJAX enabled webpart updating

An AJAX-enabled web part with update button and display current time every time when button is clicked. Loading image and text displayed during the update.

Goal

  • Enabling SharePoint site with ASP.NET AJAX framework support
  • Create AJAX-enabled SharePoint web part
    • with UpdateProgress control for visual feedback in browser when web part is updating
    • with AJAX request event script to hide UpdatePanel while web part is updating
  • Add AJAX-enabled web part to page and see it in action

Solution

Enabling ASP.NET AJAX framework support for SharePoint site

1. Go download and install - Microsoft .Net Framework 3.5 (if you haven't already)

Service Pack 1 for .NET Framework 3.5 is not required here, but it is recommended to install it for future capabilities

2. Register ASP.NET AJAX server controls as safe controls. You can either:

If you like the text-editing challenges - Go spend an hour follow the steps in this article and hope you don't get any errors :p (It is still recommended to read and understand how/what to change web.config to make AJAX working)

Or if you are lazy and really want to get it working in 10 minutes - Go download this SharePoint Feature (Change web.config for ASP.NET 3.5 AJAX support). This project is created by [MVP] Steven Van de Craen. After you deploy this feature, you need to activate it from SharePoint Central Administration > Application Management > Manage Web Application Features. And it will register those server controls for you in web.config

 

Create AJAX-enabled SharePoint web part

Jame Tsai .NET SharePoint Blog - Web Part structure diagram

Above diagram shows the basic structure of AJAX-enabled web part created in this example. 

The orange and purple blocks are the classes you'll need to implement in this example. Both blue squares are the ASP.NET AJAX server controls and other blue round squares are the common ASP.NET server controls.

Their purpose will be explained in the following steps.

 

1. Create progress template class for UpdateProgress control (Purple block in the diagram)

Why?

ASP.NET AJAX UpdateProgress control is used in web part for displaying visual feedback in browser when web part is updating. And UpdateProgress control is created dynamically.

MSDN - "If you are creating UpdateProgress controls dynamically, you can create a custom template that inherits from the ITemplate control. You specify markup in the InstantiateIn method, and then set the ProgressTemplate property of the dynamically created UpdateProgress control to a new instance of the custom template."

public class ProgressTemplate : ITemplate
{
        public string ImagePath { get; set; }
        public string DisplayText { get; set; }

        public ProgressTemplate(string imagePath, string displayText)
        {
            ImagePath = imagePath;
            DisplayText = displayText;
        }

        public void InstantiateIn(Control container)
        {
            Image img = new Image();
            img.ImageUrl = SPContext.Current.Site.Url+ "/" + ImagePath;

            Label lbl = new Label();
            lbl.Text = DisplayText;

            container.Controls.Add(img);
            container.Controls.Add(lbl);
        }
}

You can see this custom template takes two string parameters in its constructor for image source URL and the text that you want to display. And for the markup in InstantiateIn method, Image and Label controls are created (use the values assigned from constructor) and added to container control.

 

2. Create AJAX-enabled web part class (Orange block in the diagram)

[XmlRoot(Namespace = "MossSimpleAJAXWebPart")]
    public class SampleAJAXWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {

        [DefaultValue(""), WebBrowsable(true), Category("ProgressTemplate"), Personalizable(PersonalizationScope.Shared)]
        public string ImagePath { get; set; }
        [DefaultValue(""), WebBrowsable(true), Category("ProgressTemplate"), Personalizable(PersonalizationScope.Shared)]
        public string DisplayText { get; set; }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            UpdatePanel updatePanel1 = new UpdatePanel();
            updatePanel1.ID = "udpItemListingWebPart";
            updatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional;

            UpdateProgress updateProgress1 = new UpdateProgress();
            updateProgress1.AssociatedUpdatePanelID = "udpItemListingWebPart";
            updateProgress1.ProgressTemplate = new ProgressTemplate(ImagePath, DisplayText);

            Button button1 = new Button();
            button1.ID = "btnClick";
            button1.Text = "Update";
            button1.Click += new EventHandler(button1_Click);

            Label label1 = new Label();
            label1.ID = "lblShowTime";
            label1.Text = string.Format("Updated at: {0} ", DateTime.Now.ToLongTimeString());

            updatePanel1.ContentTemplateContainer.Controls.Add(label1);
            updatePanel1.ContentTemplateContainer.Controls.Add(button1);

            this.Controls.Add(updateProgress1);
            this.Controls.Add(updatePanel1);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
            if (!ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack)
            {
                string script = "";
                script = @"
                        var ITEMLISTINGBUTTONID;
                        with(Sys.WebForms.PageRequestManager.getInstance()){
                            add_beginRequest(onBeginRequest);
                            add_endRequest(onEndRequest);
                        }
                        function onBeginRequest(sender, args){
                            ITEMLISTINGBUTTONID = args.get_postBackElement().id;
                            $get(ITEMLISTINGBUTTONID).parentElement.style.display = 'none';
                        }
                        function onEndRequest(sender, args){                          
                           $get(ITEMLISTINGBUTTONID).parentElement.style.display = '';
                        }
                        ";
                this.Page.ClientScript.RegisterStartupScript(this.GetType(), "HideSimpleAJAXWebPartUDP", script, true);
            }
        }

        void button1_Click(object sender, EventArgs e)
        {
            this.label1.Text = string.Format("Updated at: {0} ", DateTime.Now.ToLongTimeString());
        }
    }

This web part class has two public string properties for user to set values from UI. These values are used for creating an instance of ProgressTemplate described in step 1.

CreateChildControls() method

From the diagram you can see two ASP.NET AJAX controls are created in CreateChildControls() method (Blue squares)

UpdatePanel control - To perform partial-page updates. In order for partial-page updates to occur, you'll need content, which is our Button and Label controls.

It is important to set UpdateMode of UpdatePanel to "Conditional". (By default, this property is set to "Always"). Set it to "Conditional" prevents unwanted update occurring on every postback that originates from anywhere or any other web parts on the page.

UpdateProgress control - To display progress template with markup when associated UpdatePanel is updating.

Render() method

Adding event handlers for events raised by the PageRequestManager (From book ASP.NET AJAX in Action - JavaScript object for managing the UpdatePanel controls on the page and fires off a series of events before, during and after an asynchronous postback, it becomes available when partial rendering is enabled on a page)

Two event handlers are registered for both beginRequest and endRequest events. And their purpose is to hide and show update panel div (generated by UpdatePanel control in web part) respectively during the update.

Note:

you cannot separate the JavaScript code to .js file and register it as web resource. Because web resource will be referenced before ASP.NET AJAX client side component on page. That means Sys.WebForms.PageRequestManager will not be available for you to register event handlers.

The script here will only register once on the page even if multiple instances of the same web part were added to the page. Because startup script is uniquely identified by its key and its type. Scripts with the same key and type are considered duplicates. Only one script with a given type and key pair can be registered with the page. Attempting to register a script that is already registered does not create a duplicate of the script.

button1_click()

To update current time dynamically and display it in Label lable1 control

 

3. Create SharePoint feature to deploy AJAX-enabled web part

You can skip this section if you already know how to create SharePoint feature for deploying custom web part

feature.xml


<?xml version="1.0" encoding="utf-8"?>

<Feature Id="B67C2989-580E-490c-86CF-86F0FA849373"

          Title="SimpleAJAXWebPart"

          Description="Moss Simple AJAX Item Listing Web Part"

          Version="1.0.0.0"

          Hidden="FALSE"

          Scope="Site"

          DefaultResourceFile="core"

          xmlns="http://schemas.microsoft.com/sharepoint/">

  <ElementManifests>

    <ElementManifest Location="elements.xml"/>

    <ElementFile Location="SimpleAJAXWebPart.dwp" />

  </ElementManifests>

</Feature>

elements.xml

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="WebPartPopulation" Url="_catalogs/wp" RootWebOnly="TRUE">

    <File Url="SimpleAJAXWebPart.dwp" Type="GhostableInLibrary">

    </File>

  </Module>

</Elements>

SimpleAJAXWebPart.dwp


<?xml version="1.0" encoding="utf-8"?>

<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">

  <Assembly>YOUR_ASSEMBLY_INFO_HERE</Assembly>

  <TypeName>NAMESPACE.YOUR_WEB_PART_CLASSNAME_HERE</TypeName>

  <Title>Moss Simple AJAX Web Part</Title>

  <Description>Simple AJAX Item Listing Web Part</Description>

</WebPart>

Add AJAX-enabled web part to Page and see it in action

Before you add this AJAX-enabled web part to web part page, you have to add ASP.NET AJAX ScriptManager control to your master page (default.master if you are using default master page).


<asp:ScriptManager ID="ScriptManager1" runat="server"/>

Now you can add your AJAX-enabled web part to any web part page and see it in action. Remember to set web part image path and display text properties for ProgressTemplate to run properly.

James Tsai .NET SharePoint Blog - AJAX enabled webpart configuration

blog comments powered by Disqus