Introduction
Pop-ups are helpful items in the UI development toolbox. They allow the display and entry of additional information without changing the context and access to what's displayed in the main window. In this way, they can help to reduce the number of user actions required and the number of post-backs needed. Hence, the load on the server can also be reduced. In other words, they potentially improve the performance of the user, as well as that of the server.
In web applications, support for pop-ups is limited. One can open a new browser window using JavaScript, but it is hard to manage the pop-up. For instance, when the page is left, the pop-up should close. Also, pop-up blockers may disrupt web applications that use window.open()
, causing numerous helpdesk calls. For simple error messages, one can use the JavaScript alert()
function, but that one does not allow formatting of text.
With ASP.NET AJAX comes support for better user interfaces. DragPanelExtender
and ResizableControlExtender
support creating a pop-up that meets the needs of ASP.NET web application developers. The PopupPanel control takes this approach.
Requirements
The PopupPanel control meets the following requirements:
- It has an optional header and an optional footer.
- The header text or pop-up title can be configured.
- The header can be used to drag the pop-up. If there is no header, the whole pop-up becomes draggable.
- The header has an image button to close the pop-up.
- The pop-up can be resized, with minimum and maximum width and height. Resizing happens via dragging the resizing image by the lower right corner.
- The footer optionally has one to three buttons. The button text, as well as the client and server callback functions of these buttons, can be configured.
- If there is more than one pop-up on the page, it must be possible in client script to open and close each of them or to put any one of them on top, preferably in a single statement.
- Its HTML content must be configurable both on the client and on the server. It should have no restrictions whatsoever.
- If the content does not fit, the control must add a horizontal and/or vertical scrollbar to support the display. The display of these scrollbars also depends on the size of the pop-up during resizing.
- It comes as a single unit: all JavaScript, CSS and images are embedded resources to simplify installation.
- It runs on both IE7 and Firefox 2.0.
- If there are multiple pop-ups on a page, one can be given focus by clicking it. The pop-up that has focus is on top and has a different header color.
Implementation
The PopupPanel control is a composite control. Each PopupPanel control inserts JavaScript that creates an object to represent the pop-up. If the ID of the PopupPanel control is MyPopup
, say, the corresponding JavaScript object has ID MyPopupObj
. The prototype of this object contains functions for open, close, focus and resize, as well as functions that yield the ID of the popup itself, its header, its body content and its footer:
Ktmd.Popup.prototype =
{
getId: Ktmd$Popup$getId,
getBodyId: Ktmd$Popup$getBodyId,
getHeaderId: Ktmd$Popup$getHeaderId,
getFooterId: Ktmd$Popup$getFooterId,
open: Ktmd$Popup$open,
close: Ktmd$Popup$close,
focus: Ktmd$Popup$focus,
resize: Ktmd$Popup$resize
}
This way, the opening of a pop-up becomes as simple as calling eval('MyPopupObj').open()
. The PopupPanel control uses both DragPanelExtender
and ResizableControlExtender
. The latter has a property to configure the JavaScript function to resize it. Unfortunately, this property does not allow a parameter for that function. Hence, a different function has to be defined for each pop-up, which would be called resize_MyPopup
for a pop-up with ID MyPopup
.
Bringing a pop-up to the front is implemented by setting its z-index upon clicking the pop-up. It is set to the maximum z-index of any pop-up plus one. There is a global variable that maintains the maximum, which is initially set to 100.
Browser specifics
Most of the browser specifics are hidden in DragPanelExtender
and ResizableControlExtender
. The bottom right DragHandle
does not automatically appear on top of the footer in IE. Therefore the footer is 16 pixels smaller than it would otherwise be. IE gives a better 3D effect for border outset. In Firefox, the top left becomes white, blurring the boundary of the pop-up. This can be alleviated by means of the following script at the start of the HTML body:
<script type="text/javascript">
if (!document.all)
{
document.write("<style type='text/css'>");
document.write(" .popupContainer{");
document.write(" border: outset #B4B0A8 2px;");
document.write(" }");
document.write("</style>");
}
</script>
The control does not look good in IE6. The resize function probably needs to be different.
Use
To use the control on a page:
- Register the control on the page.
<%@ Register Assembly="KtmdServerControls"
Namespace="Kronos.Tmd.ServerControls" TagPrefix="Ktmd" %>
- Add the control to the page, as in:
<Ktmd:PopupPanel ID="somePopup"
OffsetX="200px" OffSetY="200px"
ShowButtonOne="True"
ButtonOneText="OK"
ButtonOneOnClick="eval('somePopupObj').close(); return false;"
Width="225"
Height="150"
HeaderText="Title Text"
MaximumWidth="300"
MaximumHeight="300"
runat="server">
<ContentTemplate>
<DM:UploadFile id="ucUploadFile" runat="server" />
</ContentTemplate>
</Ktmd:PopupPanel>
- To make the embedded CSS effective, add an HTML link to the page's head element.
<link rel="Stylesheet" id="htmlStyleSheetLink" runat="server" />
- Set the
href
property upon page load. Give access to the embedded JavaScript in a similar way.
if (!IsPostBack)
{
htmlStyleSheetLink.Href = PopupPanel.GetCssWebResourceUrl(Page);
}
ScriptManager.GetCurrent(Page).Scripts.Add(
PopupPanel.GetJavaScriptReference());
To access the content of the control on the server, use the Content
property.
IUploadFile uploadFile =
somePopup.Content.FindControl("ucUploadFile") as IUploadFile;
string fileContent = uploadFile.GetUploadedDataUtf8Decoded();
To create a PopupPanel on the server that has one OK button and displays a div
element saying "Hello World," code something like this:
PopupPanel popup = new PopupPanel();
HtmlGenericControl div = new HtmlGenericControl("div");
div.Style.Add("padding", "5px");
div.InnerHtml = "Hello World";
popup.Content.Controls.Add(div);
Page.Form.Controls.Add(popup);
popup.ShowButtonOne = true;
popup.ButtonOneText = "OK";
popup.ButtonOneOnClick = popup.ClientID + "Obj.close(); return false;";
The code comes with an example static MessageBox
class that shows this use of the PopupPanel.
Resources
[1] | "Developing Microsoft ASP.NET Server Controls and Components" by Nikhil Kothari and Vandana Datye, Microsoft Press |
[2] | "Create Advanced Web Applications With Object-Oriented Techniques" by Ray Djajadinata, MSDN Magazine May 2007 |
[3] | ASP.NET Ajax website |
Feedback
It would be great to get feedback on the following:
- Are there other ways to provide button functionality in the footer that are not limited to three buttons?
- What would the resize function be in IE6 or other browsers?
History
- 31 July, 2007 -- Original version posted
- 2 August, 2007 -- Source download updated
- 22 September, 2008 -- demo updated