Introduction to the PopupControl Extender

Published: 08 Dec 2006
By: Brian Mains

The PopupControl extender is a way to render a server control popup to the user, so that the user can perform some action (say click on a textbox), the user selects a value in a control that dynamically appears, and that value is posted back to the originating server control.

Introduction

Within the AJAX Control Toolkit, there is a PopupControl extender that allows you to popup a control when clicking inside another control. To explain this concept, imagine a reservation system like orbitz.com or cheaptickets.com. When you click the from date textbox, a calendar control appears over it, allowing you to select a date graphically. Once selected the data appears inside the form textbox. I will show you this example, plus an additional one to illustrate the concept. I will also briefly discuss what doesn't work with this extender.

An extender control has these following properties that handle certain functionality:

  • TargetControlID - The ID of the control that will have its value edited. In my reservation system example, this would be the ID of the textbox control.
  • PopupControlID - The ID of the control that will appear, and whose selected value will be transferred to the target control.
  • Position - The position of the popup control, or where it will pop up in relation to the target control.
  • CommitProperty - The client-side property of the Target Control. This is the property that will have its value updated whenever the popup control is clicked. For the textbox control as the target control, it will be the 'value' property.
  • CommitScript - The client-side script to run whenever the value is committed; this is usually done to alter the value that is committed.

Example 1: A Calendar Popup Example

Imagine you navigate to an airline reservation system. You click to begin your destination date, and a calendar control appears. Upon selecting a value, the date is entered into the textbox, creating a rich UI. This is a common feature, used by many websites. You can easily achieve the same effect using the AJAX Control Toolkit with the following code:

<asp:TextBox ID="txtCalendarDate" runat="server"></asp:TextBox>
<asp:Panel ID="pnlCalendarDate" runat="server" style="display:none">
  <asp:UpdatePanel ID="upCalendarDate" runat="server" UpdateMode="Always">
    <ContentTemplate>
    <asp:Calendar 
        ID="calSelection" runat="server" 
        SelectedDate="<%# DateTime.Today %>" 
        VisibleDate="<%# DateTime.Today %>"
        OnSelectionChanged="calSelection_SelectionChanged" 
        DayNameFormat="Shortest" ShowGridLines="True">
    </asp:Calendar>
  </ContentTemplate>
 </asp:UpdatePanel>
</asp:Panel>

<ajaxtoolkit:PopupControlExtender 
    ID="extCalendarDate" 
    runat="server" 
    TargetControlID="txtCalendarDate" 
    PopupControlID="pnlCalendarDate" 
    Position="Right" 
    CommitProperty="value">
</ajaxtoolkit:PopupControlExtender>

The txtCalendarDate textbox is the target control for the PopupControlExtender. Notice that it doesn't have any additional attributes. The popup control is a panel; the reason for using the panel is so I can wrap the control with other controls/text information, such as an explanation of the control. The update panel allows the calendar to post back the value through a callback approach, only posting back the relevant portion of the page. The calendar control can be navigated forward and backward by month, and upon selecting a date, the value is injected into the textbox. How does this happen? The code-behind is the answer. The following is the SelectionChanged event definition:

protected void calSelection_SelectionChanged(object sender, EventArgs e)
{
    this.extCalendarDate.Commit(calSelection.SelectedDate.ToShortDateString());
}

By calling the commit method, the value is passed to the txtCalendarDate textbox. In the above code, the short date version of the selected date is passed.

Example 2: A Database Popup Example

You can also use a gridview to pull back certain results. For instance, look at the following code:

<asp:TextBox ID="txtDatabaseEntry" runat="server"></asp:TextBox>
<asp:Panel ID="pnlDatabaseEntry" runat="server" style="display:none">
  <asp:UpdatePanel ID="upDatabaseEntry" runat="server" UpdateMode="Always">
    <ContentTemplate>
      <asp:GridView 
         ID="gvwDatabaseEntry" runat="server" 
         AutoGenerateSelectButton="True" 
         DataSourceID="sqlDatabaseEntry"
         GridLines="None" 
         OnSelectedIndexChanged="gvwDatabaseEntry_SelectedIndexChanged">
      </asp:GridView>
      <asp:SqlDataSource ID="sqlDatabaseEntry" runat="server" 
           ConnectionString="<%$ ConnectionStrings:AW %>" 
           SelectCommand="SELECT top 10 [Title], [FirstName], 
                          [MiddleName], [LastName], [Suffix], 
                          [EmailAddress], [Phone] FROM [Person].[Contact]">
      </asp:SqlDataSource>
    </ContentTemplate>
  </asp:UpdatePanel>
</asp:Panel>

<ajaxtoolkit:PopupControlExtender 
    ID="extDatabaseEntry" runat="server" 
    TargetControlID="txtDatabaseEntry" 
    PopupControlID="pnlDatabaseEntry" 
    Position="right" 
    CommitProperty="value">
</ajaxtoolkit:PopupControlExtender>

The gridview pulls back sample data of contacts and upon selecting the SelectedIndexChanged event fires.

protected void gvwDatabaseEntry_SelectedIndexChanged(object sender, EventArgs e)
{
  GridViewRow row = this.gvwDatabaseEntry.SelectedRow;
  string firstName = row.Cells[2].Text;
  string initial = row.Cells[3].Text;
  string lastName = row.Cells[4].Text;

  string format;
  if (!string.IsNullOrEmpty(initial) && initial != "&nbsp;")
    format = "{0} {1} {2}";
  else
    format = "{0} {2}";
  this.extDatabaseEntry.Commit(string.Format(format, firstName, initial, 

lastName));
}

When the row is selected, the code gets the first name, middle initial, and last name, and creates a format based on whether the middle initial exists. Then this value is committed to the extender, which passes the result to the value property of the textbox (on the client side).

Example 3: A Failed File Upload Example

The following is a failed attempt at processing the text of a file upload:

<asp:TextBox ID="txtDescription" 
    runat="server" Columns="30" Rows="5" 
    TextMode="MultiLine"></asp:TextBox><br />

<asp:Panel ID="pnlDescription" runat="server" style="display:none">
  <asp:UpdatePanel ID="upDescription" runat="server" UpdateMode="Always">
    <ContentTemplate>
      Enter the file to upload:  <asp:FileUpload ID="fupUpload" runat="server" />
      <asp:LinkButton ID="lnkUpload" 
           runat="server" 
           OnClick="lnkUpload_Click">Upload</asp:LinkButton>
    </ContentTemplate>
  </asp:UpdatePanel>
</asp:Panel>

<ajaxtoolkit:PopupControlExtender 
    ID="extDescription" 
    runat="server" 
    TargetControlID="txtDescription" 
    PopupControlID="pnlDescription" 
    Position="Right" 
    CommitProperty="value">
</ajaxtoolkit:PopupControlExtender>

The upload link posts back the value of the file upload, which should seemingly work as below:

protected void lnkUpload_Click(object sender, EventArgs e)
{
  if (this.fupUpload.HasFile)
    this.extDescription.Commit("This is some dummy data imported from the file");
  else
    this.extDescription.Cancel();
}

However, it doesn't work; the result isn't assigned to the textbox like as in the other examples. The reason is there isn't a postback event for the file upload box and in the code above, hasfile is false. I wanted to put in an example where there could be a problem, and to show you that you have to be careful how you plan to approach the inner popup controls.

Summary

This article explains the PopupControl extender and how you can create functional popups in your applications.

References

To see the popup control in action, check out the demo on the AJAX Control Toolkit site. The toolkit is available on Code Plex. You can get the new AJAX.NET extensions off of the ASP.NET web site. Currently, the extensions are installed in the GAC; but there is the possibility of Microsoft deploying one that can be copied to the bin directory as well.

About Brian Mains

Brian Mains is an application developer consultant with Computer Aid Inc. He formerly worked with the Department of Public Welfare. In both places of business, he developed both windows and web applications, small and large, using the latest .NET technologies. In addition, he had spent many hou...

View complete profile

Top Articles in this category

The UpdatePanel opened: what happens behind the scenes?
The UpdatePanel is one of the coolest features of Microsoft's ASP.NET AJAX. It magically lets you enhance your web sites with AJAX goodness, with very little cost to you as a developer. If you are like me though, you'll be feeling just a little bit uncomfortable simply dragging the UpdatePanel onto your web form, and then letting it do its stuff. We want to understand what it is doing on our behalf.

Xml-script tutorial Part 1
ASP.NET AJAX provides a way to instantiate client side types using a declarative programming model ala ASP.NET.

Xml-script tutorial Part 3
In the first and second part of this tutorial on xml-script we introduced the declarative programming model and illustrated how to handle events raised by the client Microsoft Ajax objects. Events can be handled by invoking a global JavaScript function or by using actions; in this third part we'll talk about the InvokeMethod action, which allows calling a method declaratively.

Xml-script tutorial Part 2
In the first part of this tutorial on xml-script we introduced type descriptors and learned how to read them. In this second part we'll see how to declaratively handle events raised by client side controls.

How to invoke a web service method declaratively with MS AJAX
In the following snippet we'll see how is it possible to invoke a web service method asynchronously and processing the results using only declarative code.

Top
 
 
 

Please login to rate or to leave a comment.

Product Spotlight