In previous blog post we created simple popup box behaving like javascript "alert" function.
This time I want to create universal confirm dialog. I suppose it will work like this:
1) Dialog should be shown from client script. We should be able to call it with javascript function.
2) Javascript function will take three parameters: button object that invoked the function, title - text that will appear as title of confirmation dialog, and html - text tat will appear inside popup dialog - html parameter will be the question or warning that the user will see inside confirmation box.
3) Confirmation dialog will have two buttons - Yes and No (OK/Cancel). Clicking on "No" will do nothing - confirmation dialog will just hide. Clicking "Yes" will post back the button that invoked confirmation dialog to the server, and the server will process event for that button.
The completed demo looks like:
You can see it online or download source code.
The trick with posting back a corresponding button works simple. When invoking javascript function responsible for showing dialog, we pass instance of a button object that invoked the function. This way we know the button.name property, and later we can post back the value to the server if user clicked "Yes".
To accomplish this task I created the following files:
Script.js:
/// -------------------------------------------------- /// mainScreen object /// -------------------------------------------------- var mainScreen = { mainModalExtender : null, // modalExtender object on main page mainModalTitleSpan : null, // title span object mainModalContentsDiv : null, // div inside modal dialog pageTheme : "Default" } mainScreen.Init = function() { /// <summary> /// Initializes mainScreen variables /// </summary> this.mainModalExtender = $find('mbMain'); this.mainModalTitleSpan = $get("spanTitle"); this.mainModalContentsDiv = $get("mainModalContents"); }; mainScreen.ShowConfirm = function(_button,_title, _html) { /// <summary> /// Shows modal dialog with contents equal to _html /// </summary> /// <param name="_button">Button object</param> /// <param name="_title">Title of modal popup</param> /// <param name="_html">HTML that should be shown inside popup</param> this.currentButtonUID = _button.name this.mainModalTitleSpan.innerHTML = _title; this.mainModalContentsDiv.innerHTML = _html; this.mainModalExtender.show(); }; mainScreen.CancelConfirm = function() { /// <summary> /// Hides modal dialog /// </summary> this.mainModalExtender.hide(); this.currentButtonUID = null; }; mainScreen.SubmitConfirm = function() { /// <summary> /// Hides modal dialog /// </summary> if(this.currentButtonUID) { __doPostBack(this.currentButtonUID, ""); } this.mainModalExtender.hide(); this.currentButtonUID = null; }; /// -------------------------------------------------- /// Page events processing /// -------------------------------------------------- Sys.Application.add_load( applicationLoadHandler ); Sys.WebForms.PageRequestManager.getInstance().add_endRequest( endRequestHandler ); Sys.WebForms.PageRequestManager.getInstance().add_beginRequest( beginRequestHandler ); function applicationLoadHandler() { /// <summary> /// Raised after all scripts have been loaded and /// the objects in the application have been created /// and initialized. /// </summary> mainScreen.Init() } function endRequestHandler() { /// <summary> /// Raised before processing of an asynchronous /// postback starts and the postback request is /// sent to the server. /// </summary> // TODO: Add your custom processing for event } function beginRequestHandler() { /// <summary> /// Raised after an asynchronous postback is /// finished and control has been returned /// to the browser. /// </summary> $get("resultDiv").innerHTML = "<img src='App_Themes/"+ mainScreen.pageTheme+ "/Img/activity_small.gif'/>"; }
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Theme="Default" %> <%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="AjaxToolkit" %> <!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> Using AjaxControlToolkit ModalPopup Control to Show Confirmation Dialog Instead of Javascript "confirm" Popup Box </title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager EnablePageMethods="true" ID="MainSM" runat="server" ScriptMode="Release" LoadScriptsBeforeUI="true"> <Scripts> <asp:ScriptReference Path="~/Scripts/Main.js" /> </Scripts> </asp:ScriptManager> <div> This sample shows confirm dialog when you click on any button on the page. If you confirm the query, original button you clicked will be posted back to the server using __doPostBack('button.UniqueID','') method. So you can process event as normally in the code behind code. <br /> <br /> <asp:UpdatePanel runat="server" ID="up" UpdateMode="Conditional" > <ContentTemplate> <div> <asp:Button runat="server" ID="btn1" Text="btn1" onclick="btn1_Click" OnClientClick=" mainScreen.ShowConfirm( this, 'Please confirm', 'Are you sure to submit <b>btn1</b>?' ); return false;" /> <asp:Button runat="server" ID="btn2" Text="btn2" onclick="btn2_Click" OnClientClick=" mainScreen.ShowConfirm( this, 'Please confirm', 'Are you sure to submit <b>btn2</b>?' ); return false;" /> <asp:Button runat="server" ID="btn3" Text="btn3" onclick="btn3_Click" OnClientClick=" mainScreen.ShowConfirm( this, 'Please confirm', 'Are you sure to submit <b>btn3</b>?' ); return false;" /> <asp:Button runat="server" ID="btn4" Text="btn4" onclick="btn4_Click" OnClientClick=" mainScreen.ShowConfirm( this, 'Please confirm', 'Are you sure to submit <b>btn4</b>?' ); return false;" /> <!-- We set UseSubmitBehavior="false" to have __doPostBack function present in the scope of the page --> <asp:Button UseSubmitBehavior="false" runat="server" ID="btn5" Text="btn5" onclick="btn5_Click" OnClientClick=" mainScreen.ShowConfirm( this, 'Please confirm', 'Are you sure to submit <b>btn5</b>?' ); return false;" /> <br /><br /> </div> <div style="border: dashed 1px black; font-weight:bold; height:20px;" id="resultDiv" runat="server" > </div> </ContentTemplate> </asp:UpdatePanel> <br /><br /> <br /> <br /> <asp:Panel ID="MPanel" runat="server" Style="display: none"> <table class="mainModalTable" cellpadding="0" cellspacing="0"> <tr> <td class="mainModaTableTD"> <table class="mainModalInnerTable" cellspacing="0" cellpadding="0"> <tr> <td class="mainModalInnerTableTD"> <table border="0" width="100%" cellspacing="0" cellpadding="4"> <tr> <td class="mainModalDraggablePanelTD"> <asp:Panel CssClass="mainModalDraggablePanel" ID="MPD" runat="server"> <span class="mainModalTitle" id="spanTitle" Text=""> </span> </asp:Panel> </td> <td align="right" class="mainModalDraggablePanelCloseTD"> <asp:ImageButton SkinID="CloseModal" runat="server" ID="clB" /> </td> </tr> <tr> <td style="text-align:center" class="mainModalContentsTD" colspan="2"> <div id="mainModalContents"> </div> </td> </tr> <tr> <td class="mainModalContentsTD" align="center" colspan="2"> <input type="button" value="Yes" onclick="mainScreen.SubmitConfirm();" class="btn btnYes" /> <input type="button" value="No" onclick="mainScreen.CancelConfirm();" class="btn btnCancel" /> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </asp:Panel> <AjaxToolkit:ModalPopupExtender ID="mpeModal" runat="server" PopupControlID="MPanel" TargetControlID="btnHid" BehaviorID="mbMain" BackgroundCssClass="modalBackground" CancelControlID="clB" OnCancelScript="mainScreen.CancelConfirm();" /> <asp:Button runat="server" ID="btnHid" style="display:none;" /> </div> </form> </body> </html>
and CSS files.
Hope this helps.
Thank you! This is a really good article. I was trying to figure out the modal popup extender...thanks to your article, my code is now up & running. The only thing that I cannot figure out is why I can't use a LinkButton instead of a Button control to start the postback process. I did try updating the ShowConfirm function in "main.js" to use the proper control ID ("this.currentButtonUID = _button.id" instead of "this.currentButtonUID = _button.name"). No luck, tho.
ReplyDeleteAnyhow, thanks again for the helpful post.
- GreggTB
Hello GreggTB,
ReplyDeleteSorry to being late to answer you, I was a little busy these days and did not notice the comment notification.
ABout the LinkButtons .. -
I think this is because I use __doPostBack function in the conformation chunk of code.
But this is not only the function that is used to postback the data to the server.
There is also __doPostBackWithOptions function, so if you need to use some another control just see the source of the generated web page and find your link button there, It will have onclick attribute. You can see what function is uses to post the data to the server and use that in the modalpopup instead of __doPostBack.
Hope this helps.
Okay, I'll try that. Thanks again for the excellent article. You've been a huge help!
ReplyDelete- GreggTB
Excellent article -- thank you.
ReplyDeleteOne thing I am having trouble with is that I keep getting
"Sys.WebForms.PageRequestManager.getInstance() is null or not an object."
when the main page loads up. Popup still functions as expected. Any help would be appreciated.
--Chad
Please disregard earlier question. I found the error and it was mine. Great article.
ReplyDelete--Chad
this doesn't exactly behave like a javascript confirm does it? This solution does not 'block thread' while the user selects an option nor does it return a true/false.
ReplyDeleteIs there anyone who can demonstrate how to use the ModalPopupExtender with the same sort of call semantics as the javascript confirm?
what is the function of
ReplyDeleteasp:Button
runat="server"
ID="btnHid"
style="display:none;"
??
Очень полезно
ReplyDelete