Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

ASP.NET AJAX Control Toolkit ModalPopupExtender Control in Action

4.85/5 (169 votes)
4 Apr 2009CPOL13 min read 1.4M   64.8K  
Shows how you can display modal popup using modalpopupextender control of AjaxControlToolkit in various scenarios to achieve smooth user interaction

Table of Contents

Development Platform

  • Visual Studio 2008 SP1
  • Microsoft .NET Framework 3.5 SP1
  • ASP.NET Ajax 3.5 SP1
  • ASP.NET Ajax control toolkit for 3.5 SP1
  • IIS 5.1~7
Image 1
Figure: Expense listing demo application.

Introduction

ASP.NET Ajax control kit is a nice contribution from the ASP.NET community, which is equipped with a lot of good and handy control extenders. In this article, we are going to explore modal popup dialog extender control of Ajax control toolkit. We are going to see various scenarios in which modal popup controls can become a handy tool to use in ASP.NET rich clients and also in general purpose web applications. We will also cover few tricks and trouble shooting about modal popup extender control. First of all, we are going to cover what modal popup extender is and how we can use it.

Display a Modal Popup

Let's begin our journey by starting a hello world modal popup. In this section, we are going to see how we can use modal popup extender control to display modal popup. The best way to learn any new technology is by example. So let us put down a small example code and then we are going to see what the code means and how it works.

ASP.NET
<asp:scriptmanager id="ScriptManager1" runat="server">
</asp:scriptmanager>

<asp:button id="Button1" runat="server" text="Button" />

<cc1:modalpopupextender id="ModalPopupExtender1" runat="server" 
	cancelcontrolid="btnCancel" okcontrolid="btnOkay" 
	targetcontrolid="Button1" popupcontrolid="Panel1" 
	popupdraghandlecontrolid="PopupHeader" drag="true" 
	backgroundcssclass="ModalPopupBG">
</cc1:modalpopupextender>

<asp:panel id="Panel1" style="display: none" runat="server">
	<div class="HellowWorldPopup">
                <div class="PopupHeader" id="PopupHeader">Header</div>
                <div class="PopupBody">
                    <p>This is a simple modal dialog</p>
                </div>
                <div class="Controls">
                    <input id="btnOkay" type="button" value="Done" />
                    <input id="btnCancel" type="button" value="Cancel" />
		</div>
        </div>
</asp:panel>

The above code is self explanatory but still we are going to discuss it in a step by step manner.

Step 1

The engine behind the extender control is the Script Manager of ASP.NET Ajax 3.5. It must be declared in the page context as long as we want to use any extender control. So go ahead and drag drop scriptmanager from toolbox or write a tag for a Script Manager.

Step 2

Now add a Div or ASP.NET panel in the page that you want to display as a modal dialog. Give an id of the panel and put done and cancel button in the panel. Do add a header div in the panel, which will serve as a header of the popup. Last of all, add a target link or button anywhere in the page except inside the div that you want to show as a modal popup. Clicking on the link for the popup will make the popup display.

Step 3

Now add a modal popup extender control in the page and set the TargetControlID property to the id of the button on which the user will click to show the modal. Set PopupControlID property to the id of the ASP panel which you want to show as a modal. Last of all, set CancelControlID property to "btnCancel" and OkControlID property to "btnOkay".

Step 4

All is set, it's time to add a few styles so that we have a light box effect when the modal is displayed. The below two styles are given for demonstration purposes. But the important thing is that if we want to add transparency/light box effect on the page, we have to set the CSS of the modal popup extender. To achieve the effect, we add a background color and then apply a filter and the opacity CSS attributes. Then we must add styles to your popup dialog. All done. Now hit the target button and a modal popup will pop up.

CSS
.ModalPopupBG
{
    background-color: #666699;
    filter: alpha(opacity=50);
    opacity: 0.7;
}

.HellowWorldPopup
{
    min-width:200px;
    min-height:150px;
    background:white;
}

Close and Open Modal Popup Using Script

While developing applications, we might have a requirement to show the modal popup from JavaScript, that we might need to open the popup and also close the popup dynamically using JavaScript. For example, a warning message that stays for only 2 seconds and then automatically closes. There are a couple of tricks to do that. We are going to discuss mostly all of them. First let's discuss how we can open a modal popup without hitting a button or link. Assume that we have a modal popup all set in the page, and on page load we have to display a warning message. First we have to hide the target control id and the control buttons of the modal popup using style="display:none". Then we have to add BehaviorID property of modal popup extender control. Now define script to do our trick on pageLoad. PageLoad is a function that script manager automatically invokes when the page is loaded on the client side. In page load, we are going to add code to show the modal and again hide the popup after some period.

To show the popup, we are going to use $find('behaviourIDofModal').show(); and to hide the modal, we are going to use $fin('behaviourIDofTheModal').hide();. Alternately we can auto raise the click JavaScript event of the targetcontrolid using JavaScript to show the popup and also raise the click event of the cancel control of the popup to hide the popup again.

JavaScript
<script language="javascript" type="text/javascript">
    function pageLoad() {
        ShowPopup();
        setTimeout(HidePopup, 2000);
    }

    function ShowPopup() {
        $find('modalpopup').show();
        //$get('Button1').click();
    }

    function HidePopup() {
        $find('modalpopup').hide();
        //$get('btnCancel').click();
    }
</script>

Display an iframe Inside Modal Popup

In this section, we are going to see how we can use an iframe inside the modal popup and discuss some scenarios in which it can become handy to use an iframe inside the modal popup. Let's get started with a simple example. In this example, we are going to use a modal popup that will be used as a three step wizard control to add a new expense item. The wizard will be a separate page in which we will put our three steps beside a multiview ASP.NET control. In the first step, we are going to show the input panel for the client, upon use save data we are going to display a simple success message or an error message. If the data is saved successfully, the modal will close after showing the success message and if error occurs, we will show the error message and take us to the first step again. We will also implement the whole wizard in a separate aspx page and we will display this page using an iframe inside a modal popup.

In this section, we have a few problems. First the okay and cancel button of the modal. Since okay and cancel button of wizard are part of the wizard that is inside the iframe modal popup, extender will be unable to find it while loading the extender in the first place. So we got to add okay and cancel controls outside an iframe and then hide the controls. In a later section, we are going to see how we can handle the okay and cancel from the iframe source page.

Code in Host Page
ASP.NET
<asp:button id="btnAddNew" runat="server" text="New Expanse" />

<cc1:modalpopupextender id="ModalPopupExtender1" 
	runat="server" cancelcontrolid="btnCancel" 
	okcontrolid="btnOkay" targetcontrolid="btnAddNew" 
	popupcontrolid="Panel1" popupdraghandlecontrolid="PopupHeader" 
	drag="true" backgroundcssclass="ModalPopupBG">
</cc1:modalpopupextender>

<div class="popupConfirmation" id="Panel1" style="display: none">
    <iframe id="frameeditexpanse" src="EditExpanse.aspx" frameborder="0">
    </iframe>
    <div class="popup_Buttons" style="display: none">
        <input id="btnOkay" type="button" value="Done" />
        <input id="btnCancel" type="button" value="Cancel" />
    </div>
</div>
Code in Source Page
ASP.NET
<form id="form1" runat="server">
    <div class="popup_Container">
        <div class="popup_Titlebar" id="PopupHeader">
            <div class="TitlebarLeft">
                Edit Expanse
            </div>
            <div class="TitlebarRight" onclick="cancel();">
            </div>
        </div>
        <div class="popup_Body">
            <%--The content will go here--%>
        </div>
        <div class="popup_Buttons">
            <input id="btnOkay" type="button" value="Done" runat="server" />
            <input id="btnCancel" onclick="cancel();" type="button" value="Cancel" />
        </div>
    </div>
</form>

Close Popup from iframe

We have already seen how to show a framed content inside a modal popup. In this section, we are going to see how we can close the modal popup from the iframe source page. As we can see in the above source code, we have put our okay and cancel control twice. The okay and cancel button that are defined in the host page are for the popup extender, so that we can refer the buttons to the modal popup extender which will save us from any runtime error. We also have two okay and cancel buttons in the source page of iframe, which will be used by the user to do okay and cancel the dialog. The host page's buttons are hidden to the user.

In modal popup, if we put our okay and cancel buttons outside the iframe and if we click any of those buttons, it will close the modal regardless of whether we finish the job inside the modal or not. The code is given below.

C# Code in iframesourcepage codebehind
C#
protected void btnOkay_Click(object sender, EventArgs e)
{
    try
    {
       // code will go here
        MultiViewExpanse.ActiveViewIndex = 1;
        ClientScript.RegisterStartupScript(this.GetType(), 
		"onload", "onSuccess();", true);
    }
    catch
    {
        ClientScript.RegisterStartupScript(this.GetType(), 
		"onload", "onError();", true);
        MultiViewExpanse.ActiveViewIndex = 1;
    }
}
JavaScript Code in iframesourcepage HTML
JavaScript
<script language="javascript" type="text/javascript">
    function getbacktostepone() {
        window.location = "EditExpanse.aspx";
    }
    function onSuccess() {
        setTimeout(okay, 2000);
    }
    function onError() {
        setTimeout(getbacktostepone, 2000);
    }
    function okay() {
        window.parent.document.getElementById('btnOkay').click();
    }
    function cancel() {
        window.parent.document.getElementById('btnCancel').click();
    }
</script>

When user hits the okay button in the wizard, we perform some operation and then we raise the click event of the host page's okay or cancel button to dismiss the dialog.

Same Source Different Data in Side iframe

In the previous example, we have seen how we can display a framed content inside a modal popup. In this section, we are going to discuss about displaying a customized version of framed content in modal popup. In our expense listing example, we have an edit button in gird item. Let's say we don't want in place editing and when user clicks on the edit button, a modal window will popup with its relevant data. There are many ways to implement this requirement. But for now, we are going to use iframe inside a modal and change the source of the iframe and add appropriate query string to the src property to show that it shows relevant data in the modal.

In rowdataboundevent, we have changed the attribute of the edit button to show a modal window. Configure the modalpopupextender in such a way so that its target control id does not show up. When user clicks on edit button on any item, a client JavaScript function is invoked with argument expense id. Now all we have to do is to set the iframe src property and then display the popup using client JavaScript. Below the complete code is given for better understanding.

Code in RowDataBound Event
C#
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        Expanse expanse = e.Row.DataItem as Expanse;
        (e.Row.FindControl("lnkEdit") as LinkButton).Attributes.Add
		("onClick", "ShowEditModal('" + expanse.ID + "');");
        (e.Row.FindControl("lnkDelete") as LinkButton).CommandArgument = 
						expanse.ID.ToString();
    }
}
Code for Modal Popup
ASP.NET
<asp:button id="ButtonEdit" style="display: none" runat="server" text="Edit Expanse" />

<cc1:modalpopupextender id="ModalPopupExtender2" runat="server"
	cancelcontrolid="ButtonEditCancel" okcontrolid="ButtonEditDone"
	targetcontrolid="ButtonEdit" popupcontrolid="DivEditWindow"
	backgroundcssclass="ModalPopupBG" oncancelscript="EditCancelScript();"
	onokscript="EditOkayScript();" behaviorid="EditModalPopup">
</cc1:modalpopupextender>

<div class="popup_Buttons" style="display: none">
    <input id="ButtonEditDone" type="button" value="Done" />
    <input id="ButtonEditCancel" type="button" value="Cancel" />
</div>
<div class="popupConfirmation" id="DivEditWindow" style="display: none">
    <iframe id="IframeEdit" frameborder="0" scrolling="no" height="203">
    </iframe>
</div>
Code in JavaScript
JavaScript
<script language="javascript" type="text/javascript">
    function ShowEditModal(ExpanseID) {
        var frame = $get('IframeEdit');
        frame.src = "EditExpanse.aspx?UIMODE=EDIT&EID=" + ExpanseID;
        $find('EditModalPopup').show();
    }
    function EditCancelScript() {
        var frame = $get('IframeEdit');
        frame.src = "DemoLoading.aspx";
    }
    function EditOkayScript() {
        RefreshDataGrid();
        EditCancelScript();
    }
    function RefreshDataGrid() {
        $get('btnSearch').click();
    }
</script>

We can do a few tricks to show the page transaction from one edit window to another a little bit better. we will keep the source of the iframe to a demo page which says loading, when user clicks on loading and the ShowEditModal is invoked, then in that function we will set the appropriate src to load appropriate content. When user clicks okay or cancel, we will again reset the source to the demo page. The script given in the above code listing demonstrates the same idea.

Update Panel inside modalpopup

Update panel is the most easy and friendly control that we use while using ASP.NET Ajax in our web applications. In this section, we are going to see a few tricks about update panel inside modal popup extender. If we want to make the framed content even better, we can use update panel and other client side facility inside the source page. But in this case, we have to be sure that the HTTP Cache is refreshed properly. Just put the below code in page load to avoid unnecessary page cache. But you may also want to keep cache; in that case do use HTTP cache properly.

C#
Response.Cache.SetCacheability(HttpCacheability.NoCache);

Now let's talk about normal modal popup with a update panel inside. If we have a wizard inside the update panel, after the job is done we might want to make the wizard go to step one so that when user clicks the start wizard, the wizard starts from the beginning. In that case, use a hidden input button which will act as client trigger to update the update panel. And in click event of the button, reinitialize the wizard. Last of all, add necessary click script in onokayscript and oncancelscript to raise click event of the button to run the process. So when the user finishes or perhaps goes through few steps and then cancels the wizard, he will be able to start from the beginning after clicking start wizard.

Problem with validatorcalloutextender Inside Modal Popup

In this section, we are going to show another problem and trouble shooting of modal popup. It's about the validators and validatorcalloutextender. when we have an input panel in side a modal popup, we might want to incorporate some required field, or regular expression validator along with validator callouts. As you all have already guessed, the ASP.NET validator and validator callouts don't work properly inside modal popup extender. When user puts data inside an input panel which is located inside the modal popup and clicks okay to finish the operation, we might want to take the input and perform some operation and eventually clear input panel for new panel. When user clicks to show modal popup, the validatorcalloutextender pops up even though user didn't perform any operation. There is a simple workaround for this problem and we got to use it. Given below is the complete code listing:

ASP.NET
<asp:button id="Button1" runat="server" text="Click here to show the modal" 
	causesvalidation="false" />

<cc1:modalpopupextender id="ModalPopupExtender1" runat="server"
	cancelcontrolid="btnCancel" targetcontrolid="Button1"
	popupcontrolid="Panel1" popupdraghandlecontrolid="PopupHeader"
	drag="true" backgroundcssclass="ModalPopupBG" oncancelscript="ClearUI();"
	behaviorid="modalwithinput">
</cc1:modalpopupextender>

Note that in the above code, we have marked our target control's cause validation property to false. This is necessary otherwise when we click on the button, the popup will get launched with a validation callout already popped and in an invalid location, just like the figure shown below:

Image 2
Figure: Validator Callout with visual dislocation.

Below the code for the popup body is given where we have added the ValidatorCalloutExtender. Here we have to set the RequiredFieldValidator's Display property to None, otherwise the message for both required field validator and validator callout will be shown.

ASP.NET
<div class="popup_Body">
    <p>Enter you name:
        <asp:textbox id="TextBox1" runat="server"></asp:textbox>
        <asp:requiredfieldvalidator id="RequiredFieldValidator1" runat="server"
		controltovalidate="TextBox1" errormessage="Please Enter your name"
		setfocusonerror="true" display="None"></asp:requiredfieldvalidator>
        <cc1:validatorcalloutextender id=
		"RequiredFieldValidator1_ValidatorCalloutExtender"
		runat="server" targetcontrolid="RequiredFieldValidator1"
		behaviorid="textValidator" enabled="True">
	</cc1:validatorcalloutextender>
    </p>
</div>

The main script that actually does the trick is given below. You may note that we didn't mention any okaycontrolid or onokayscript in the modalpopupextender, rather we have included a client script in the onclientclick property of the okay button. In that okay button click we validate if the input is actually valid or not, then we manually close the popup if the input is valid otherwise keep the popup open and the validator callout automatically gets popped if the input is invalid. Next when we have a valid input or user clicks on cancel, we clear the input for the next round. Note that we have hidden the validatorcallout manually in the clearUI() function.

JavaScript
<script language="javascript" type="text/javascript">
    function ClearUI() {
        $find("textValidator").hide();
        $get("TextBox1").value = "";
    }
    function IsValid() {
        var textbox = $get("TextBox1");
        if (textbox.value == "") {
            return false;
        }
        else
            return true;
    }
    function ClosePopup() {
        if (IsValid()) {
            $find('modalwithinput').hide();
            alert("You have given your name");
            ClearUI();
        }
    }
</script>

Using Modal Popup as Interaction Confirmation Dialog

Most of the application we develop for web uses some kind of okay and cancel dialog to some extent in few areas, especially when we want to delete some data or perform an important modification on data. Generally we use window.alert() and window.confirm to show such kind of message to return user confirmation and perform operation upon user confirmation dialog result. ASP.NET Ajax control toolkit has an extender control called ConfirmButtonExtender which can also be used to show custom modal popup rather than the window.confirm and is used especially for confirmation dialog.

Let's visualize a scenario in which a user wants to delete one of the expenses from the grid clicking on Button delete. User must be alerted that she/he is going to delete one of his expenses. We will show a modal dialog in which we will ask the user whether she/he really intended to delete or not. Below the full code listing is given to demonstrate the idea a little bit better.

Image 3
Figure: ConfirmButtonExtender with modal popup.

A simple code is given below to demonstrate the idea of ConfirmButtonExtender with modal popup:

ASP.NET
<asp:templatefield showheader="False">
    <itemtemplate>
        <asp:linkbutton id="lnkDelete" runat="server" text="Delete" 
		causesvalidation="false" commandname="Delete" commandargument="ID">
		</asp:linkbutton><cc1:modalpopupextender 
		id="lnkDelete_ModalPopupExtender" runat="server" 
		cancelcontrolid="ButtonDeleteCancel" okcontrolid="ButtonDeleleOkay" 
		targetcontrolid="lnkDelete" popupcontrolid="DivDeleteConfirmation" 
		backgroundcssclass="ModalPopupBG">
        </cc1:modalpopupextender>
        <cc1:confirmbuttonextender id="lnkDelete_ConfirmButtonExtender" 
		runat="server" targetcontrolid="lnkDelete" enabled="True" 
		displaymodalpopupid="lnkDelete_ModalPopupExtender">
        </cc1:confirmbuttonextender>
    </itemtemplate>
    <itemstyle horizontalalign="Center" />
</asp:templatefield>

Code for the modal popup which is used to display as confirm window.

ASP.NET
<asp:panel class="popupConfirmation" id="DivDeleteConfirmation" 
	style="display: none" runat="server">
    <div class="popup_Container">
        <div class="popup_Titlebar" id="PopupHeader">
            <div class="TitlebarLeft">
                Delete Expanse</div>
            <div class="TitlebarRight" onclick="$get('ButtonDeleteCancel').click();">
            </div>
        </div>
        <div class="popup_Body">
            <p>
                Are you sure, you want to delete the expanse?
            </p>
        </div>
        <div class="popup_Buttons">
            <input id="ButtonDeleleOkay" type="button" value="Okay" />
            <input id="ButtonDeleteCancel" type="button" value="Cancel" />
        </div>
    </div>
</asp:panel>

Summary

In this article, we have seen a few scenarios in which we can use modal popup extender control of ASP.NET Ajax control toolkit. We have also learned few tricks and tips about modal popup extender. Many more interesting scenarios are out there to explore and many more areas to cover where we can use this modal popup. Please drop a comment if you feel that any part of the article is not clear. I would love to explain more about it and solve any difficulty that users might face while adding their modals. Last of all, if you liked the article, please vote for it.

References

History

  • 2nd April, 2009: Initial version

License

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