Thursday, November 8, 2012

Triggering AJAX UpdatePanel from a Button Click or DropDownList Selection Change in Code-Behind


Introduction

This is one of those problems that isn't technically difficult, like writing a word processing program, but rather is just a matter of finding the right code sequence to make it work. Much of the AJAX documentation shows how to use the controls placed in HTML markup. However, there are some situations where the programmer would prefer to add controls to a page dynamically from the code-behind (see my article Building ASP.NET Web Pages Dynamically in the Code-Behind). Using AJAX controls in this manner is not well documented. In looking for the answer, I found that other developers were posting to AJAX message boards with the same problem - particularly for the DropDownList. So here I present the solution. If you are having the same problem, I hope this is the first place you looked.

DropDownList Selection Change Sample Code

This simple example shows how to trigger an UpdatePanel update when a DropDownList selection changes. The HTML markup is just as it appears by default in Visual Studio, but with the addition of a PlaceHoldercontrol to hold the UpdatePanel and the link to the ScriptManager required for AJAX.
<%@ Page Language="C#" AutoEventWireup="true" 
    CodeFile="DropDown.aspx.cs" Inherits="AjaxTest_DropDown" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
    <asp:PlaceHolder id="LocalPlaceHolder" runat="server"></asp:PlaceHolder>

    </div>
    </form>
</body>
</html>
Below, you see the code-behind file for the page. I create the UpdatePanel and add it to the placeholder. I add a Label control to the UpdatePanel. When the DropDownList selection changes, the Label displays the current time. Some important points to consider:
  1. Note that both the Label and the DropDownList are added to the UpdatePanel - not to thePlaceHolder.
  2. Be sure to set the DropDownList.AutoPostback to true.
  3. Be sure to create a trigger for the event and add it to the UpdatePanel with the control ID of theDropDownList.
  4. Pay attention to the names of the event and controls. Mistyping a name will mean the page won't work. This code is easy, but it is not forgiving. Even a minor mistake will mean that the panel does not update.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class AjaxTest_DropDown : System.Web.UI.Page
{
    protected Label m_TimeLabel;

    protected void Page_Load(object sender, EventArgs e)
    {
        // create an update panel
        UpdatePanel updatepanel = new UpdatePanel();

        // add the update panel to the placeholder
        LocalPlaceHolder.Controls.Add(updatepanel);

        // create a label to show time
        m_TimeLabel = new Label();
        m_TimeLabel.Text = DateTime.Now.ToString();

        // add the label to the update panel
        updatepanel.ContentTemplateContainer.Controls.Add(m_TimeLabel);

        // create a drop down list
        DropDownList dropdown = new DropDownList();
        dropdown.ID = "Dropdown1";
        dropdown.AutoPostBack = true; // this is absolutely required
        dropdown.Items.Add("Item 1");
        dropdown.Items.Add("Item 2");
        dropdown.Items.Add("Item 3");
        dropdown.Items.Add("Item 4");

        // add the drop down list to the update panel
        updatepanel.ContentTemplateContainer.Controls.Add(dropdown);

        // create a trigger
        AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();

        // associate the trigger with the drop down
        trigger.ControlID = "Dropdown1";
        trigger.EventName = "SelectedIndexChanged";

        // add the trigger to the update panel
        updatepanel.Triggers.Add(trigger);
    }

    protected void Dropdown1_SelectedIndexChanged(object sender, EventArgs e)
    {
        // event to handle drop down change
        m_TimeLabel.Text = DateTime.Now.ToString();
    }

}
Below, you see a screen shot of this simple Web page.

Triggering the Update from a Button

You can also trigger the update from a Button control. This code shows how. While the markup for the page would be the same, pay attention to the differences from the DropDownList. Note how specifying the event handler for the Button is different than for the DropDownList.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class AjaxTest_ButtonUpdate : System.Web.UI.Page
{
    protected Label m_TimeLabel;

    protected void Page_Load(object sender, EventArgs e)
    {
        // create an update panel
        UpdatePanel updatepanel = new UpdatePanel();

        // add the update panel to the placeholder
        LocalPlaceHolder.Controls.Add(updatepanel);

        // create a label to show time
        m_TimeLabel = new Label();
        m_TimeLabel.Text = "Initial Text";

        // add the label to the update panel
        updatepanel.ContentTemplateContainer.Controls.Add(m_TimeLabel);

        // create a drop down list
        Button button = new Button();
        button.ID = "Button1";
        button.Text = "Update";
        button.Click += new EventHandler(Button1_Click);

        // add the button to the update panel
        updatepanel.ContentTemplateContainer.Controls.Add(button);

        // create a trigger
        AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();

        // associate the trigger with the drop down
        trigger.ControlID = "Button1";
        trigger.EventName = "Click";

        // add the trigger to the update panel
        updatepanel.Triggers.Add(trigger);
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        // event to handle drop down change
        m_TimeLabel.Text = DateTime.Now.ToString();
    }
}

Conclusion

That is all there is to it. Although a bit difficult to figure out initially, it is simple to implement once you know what to do.

No comments:

Post a Comment