Use UpdatePanel inside an EPiServer custom property

In order to use ASP.NET AJAX inside an EPiServer custom property you have to have a ScriptManager present. Here's an example of how to add one programmatically.

  • 6 August 2010
  • 0

The problem

If you add an UpdatePanel control to a custom property you may experience an exception saying: The control with ID 'panel' requires a ScriptManager on the page. The ScriptManager must appear before any controls that need it.

The control with ID 'panel' requires a ScriptManager on the page. The ScriptManager must appear before any controls that need it.

Prerequisites for using an UpdatePanel

In order to use an UpdatePanel the page requires a ScriptManager control within the form tag (note that it has to be the first control inside the form control, and the form element needs to have the runat=”server” attribute set).

In addition to a ScriptManager you also need an HTTP handler which serves the JavaScript required (to avoid those nasty ‘Sys’ is not defined errors):

<handlers>
  <clear />
  <!-- ASP.NET AJAX -->
  <add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <!-- End ASP.NET AJAX -->
  <!-- Additional handlers go here -->
</handlers>

Note that this should be the first handler in the list, so add it right after the <clear /> element.

Programmatically add a ScriptManager

We can solve this by programmatically adding a ScriptManager when loading the edit panel in EPiServer. That way we don’t have to modify the EPiServer master page, which is good since I’m strongly against modifying any core EPiServer files.

So, another way is to ensure a ScriptManager is always present when the edit panel is loaded inside EPiServer. We can do this by implementing a simple plugin like so:

using System.Web;
using System.Web.UI;
using EPiServer.PlugIn;
using EPiServer.UI.Edit;
 
namespace TemplateFoundation.Plugins
{
    [GuiPlugIn(Area=PlugInArea.EditPanel)]
    public class ScriptManagerPlugin : ICustomPlugInLoader
    {
        public PlugInDescriptor[] List()
        {
            // Get the edit panel
            var editPanel = HttpContext.Current.Handler as EditPanel;
 
            if (editPanel!=null)
            {
                // We add the ScriptManager control as part of the Page's Init event
                editPanel.Page.Init += delegate
                                    {
                                        // Check if a ScriptManager is already added
                                        var scriptManager = ScriptManager.GetCurrent(editPanel.Page);
 
                                        if (scriptManager == null) // No ScriptManager present
                                        {
                                            // Create the ScriptManager
                                            scriptManager = new ScriptManager
                                                            {
                                                                ID = "scriptManager",
                                                                EnablePartialRendering = true
                                                            };
 
                                            // Add the ScriptManager to the Form control
                                            editPanel.Page.Form.Controls.AddAt(0, scriptManager);
                                         }
                                    };
            }
 
            return new PlugInDescriptor[] { };
        }
    }
}

This plugin will ensure a ScriptManager is always added if one doesn’t already exist. That means you can easily use an UpdatePanel in your custom property control:

<asp:UpdatePanel UpdateMode="Conditional" ID="panel" runat="server">
    <ContentTemplate>
        <asp:TextBox ID="txtMyTextBox" runat="server" />
        <asp:Button Text="Update textbox" OnClick="btnSetTextBoxValue_Click" ID="btnSetTextBoxValue" runat="server" />
        <EPiServerScript:ScriptDisablePageLeaveEvent EventType="Click" EventTargetId="btnSetTextBoxValue" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

The Click event for the button is wired up to the following event handler:

protected void btnSetTextBoxValue_Click(object sender, EventArgs e)
{
    txtMyTextBox.Text = "Here is some text";
}

Although you can’t see it in a screenshot, you’ll have to trust me when I say the textbox’s value below is set without a full postback! :)

image

Note that I use the ScriptDisablePageLeaveEvent script to prevent validation when the Update textbox button is clicked (so we don’t get the alert asking us if we want to leave the page). In order to use it we need to add the EPiServerScript tag prefixes to web.config:

<add tagPrefix="EPiServerScript" namespace="EPiServer.ClientScript.WebControls" assembly="EPiServer" />
<add tagPrefix="EPiServerScript" namespace="EPiServer.UI.ClientScript.WebControls" assembly="EPiServer.UI" />