Click here to Skip to main content
Click here to Skip to main content

ASP.NET AJAX pop-up

By , 22 Sep 2008
 

Screenshot - PopupPanel.jpg

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:

  1. It has an optional header and an optional footer.
  2. The header text or pop-up title can be configured.
  3. The header can be used to drag the pop-up. If there is no header, the whole pop-up becomes draggable.
  4. The header has an image button to close the pop-up.
  5. 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.
  6. 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.
  7. 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.
  8. Its HTML content must be configurable both on the client and on the server. It should have no restrictions whatsoever.
  9. 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.
  10. It comes as a single unit: all JavaScript, CSS and images are embedded resources to simplify installation.
  11. It runs on both IE7 and Firefox 2.0.
  12. 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:

// Class prototype
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)
    {   // Firefox needs a bit of help handling 'outset'
        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:

  1. Register the control on the page.
    <%@ Register Assembly="KtmdServerControls" 
        Namespace="Kronos.Tmd.ServerControls" TagPrefix="Ktmd" %>
  2. 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>
  3. To make the embedded CSS effective, add an HTML link to the page's head element.
    <link rel="Stylesheet" id="htmlStyleSheetLink" runat="server" />
  4. 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Marc Schluper
Web Developer
United States United States
Member
Marc Schluper studied Applied Mathematics at Technical University Eindhoven, The Netherlands.
His employer is Kronos Hiring Solutions in Beaverton, OR.
He is married and has two children.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalpopup contentmemberw3Nima17 Oct '07 - 22:56 
It seems that content of popup is in same page. is there any way to load content of popup from another web form without iframe or dynamic user control.
 
Thanks
GeneralRe: popup contentmemberMarcSchluper18 Oct '07 - 4:39 
No, I am sorry there is no support for that.
But you could of course (from the client) access an ASP.NET AJAX System.Web.Script.Services.ScriptService which has a WebMethod like this:
 
[WebMethod]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = true)]
public string GetCustomersUsing(string productID)
{
Customer[] customers = DataAccess.FindCustomersUsingProduct(productID);
CustomerTable table = new CustomerTable(customers);
StringBuilder sb = new StringBuilder(1000);
TextWriter tw = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(tw);
table.RenderControl(htw);
return sb.ToString();
}
 
In this example CustomerTable happens to be a class derived from an HtmlTable, but the last five lines work with any UserControl as well. On the client you would need to assign the generated HTML to the innerHTML of a div element.
But ... I have not tried doing PostBacks from such a popup. Maybe if you want that kind of functionality a popup is not the right way to go.
 

 
Marc Schluper
Beaverton, OR

GeneralRe: popup contentmemberw3Nima20 Oct '07 - 21:50 
So thanks
 
content of popup is a asp.net form, I think using browser popup is a better idea.
GeneralMissing JS - StringUtilsmemberUnquaLeX6 Aug '07 - 21:06 
Thank you for this great stuff.
 
I think there is a missing resource.
I think we need that StringUtils.js also.
You use Trim function from this resource.
I wantted to confirm you.
 
Regards.
 
<script type="text/javascript" src="http://localhost/DMWeb/js/StringUtils.js"></script>
 

 
Doga Oztuzun

GeneralRe: Missing JS - StringUtilsmemberMarcSchluper7 Aug '07 - 4:41 
Good catch!
Here is the content. Change line 12 of the demo project's default.aspx file and make it refer to a file containing:
// BEGIN
function StringUtils() {}
 
StringUtils.replaceAll = function( str, searchTerm, replaceWith, ignoreCase )
{
var regex = "/"+searchTerm+"/g";
if( ignoreCase ) regex += "i";

return str.replace( eval(regex), replaceWith );
}
StringUtils.trim = function (value)
{
return value.replace(/^\s+|\s+$/g,"");
}
StringUtils.isDate = function (value)
{
var re = /(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?\d\d/
return (re.exec(value) != null);
}
StringUtils.isNumber = function (value)
{
var re = /^\d+$/
return (re.exec(value) != null);
}
// END
(Should have tested on different machine than localhost Sniff | :^) )
 
Marc Schluper
Beaverton, OR

Generalstyles in masterpagememberCesar to Dnn1 Aug '07 - 5:30 
great job!
but how do i load the css styles in a content page?
i put this in the head section:
 
<link rel="Stylesheet" id="StyleSheet" runat="server" />
 
and this in the content page
 
Dim cssLink As New HtmlLink()
cssLink.Href = PopupPanel.GetCssWebResourceUrl(Page)
 
(this works without problems if I have one stylesheet)
 
but popup is shown without styles!
how can i fix that?
GeneralRe: styles in masterpagememberMarcSchluper1 Aug '07 - 6:19 
The id of the HtmlLink must be the same in the .aspx page and the codebehind.
 
So if you have <link rel="Stylesheet" id="StyleSheet" runat="server" /> then in the codebehind it should be
 
StyleSheet.Href = PopupPanel.GetCssWebResourceUrl(Page)
 
(And do not add something like "Dim cssLink As New HtmlLink()" because the HtmlLink control has already been created for you. (As far as I know the Framework creates the control when it generates the code for the .aspx page, from which the codebehind derives.))
 

 
Marc Schluper
Beaverton, OR

GeneralRe: styles in masterpagememberCesar to Dnn1 Aug '07 - 6:32 
I tried something similar, but it did not work. messagebox does not appear if the code is in the event click, only appears if the code is in page_load event
 

GeneralRe: styles in masterpagememberMarcSchluper1 Aug '07 - 6:54 
The demo project contains an example event callback method, TestClick(), that creates a MessageBox:
 
MessageBox mb2 = new MessageBox("HI");
mb2.Title = "Be happy";
mb2.IsResizable = false;
mb2.Show(Page); // don't forget this line
 
Marc Schluper
Beaverton, OR

Generalthe same herememberMichael Sync31 Jul '07 - 22:32 
same here[^]
 
Thanks and Regards,
Michael Sync ( Blog: http://michaelsync.net)
 

GeneralRe: the same herememberMarcSchluper2 Aug '07 - 13:05 
An unsigned assembly is now available.
Could you please try again?
 
Marc Schluper
Beaverton, OR

GeneralRe: the same herememberMichael Sync2 Aug '07 - 15:12 
okay. i will try and will let you know. Smile | :)
Questioncan u please tell the passwordmembermoid.ahmed31 Jul '07 - 17:58 
Smile | :) when ever i run the application it s asking for password ie:Import key file.the project contains a password encrypted keyused for signing.Plz Dothe needful.
 
salman
AnswerRe: can u please tell the passwordmemberMarcSchluper31 Jul '07 - 18:37 
I submitted an update of the source code project, that does not sign the assembly. I did not realize signing the assembly would affect users (really) - I just did it to get rid of another Code Analysis warning.
I do not know at what time the update will be available. I am sorry for the inconvenience.

 
Marc Schluper
Beaverton, OR

GeneralVisual Studio ExpressmemberMarcSchluper31 Jul '07 - 17:52 
I developed this PopupPanel at work, with Visual Studio 2005 Team Edition for Software Developers.
At home I have only Visual Studio Express (Dutch people avoid spending money), which cannot open the projects. Does anybody know how to fix this? Can I download something? Or is VS Express simply too simple?
Thanks.
 
Marc Schluper
Beaverton, OR

GeneralRe: Visual Studio Expressmemberlegcsabi19 Apr '08 - 23:24 
I am also unable to open it with VS 2005 and 2008 professional editions
QuestionPassword?memberPierrickL31 Jul '07 - 15:58 
It's asking for a password. Did you include any sensitive data in there?
AnswerRe: Password?memberMarcSchluper31 Jul '07 - 17:39 
No, nothing sensitive in here. It should all unzip without a problem. When does it prompt for a password? Are you sure it is not a local machine issue?
 
Marc Schluper
Beaverton, OR

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 22 Sep 2008
Article Copyright 2007 by Marc Schluper
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid