Making the most out of the AjaxControlToolkit’s ModalPopupExtender Part 4

Let's dive right into putting the ControlLoader and ControlLoaderManager to work. Well go back to our simple modal dialog first covered here and make some changes

Here's the form markup

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<Controls:ControlLoaderManager ID="MainLoader" runat="Server" />
<div>
<asp:Button ID="ShowModal" runat="server" Text="Show The Modal" />
<asp:Button ID="DummyOkayControl" runat="server" style="display:none;" />
<ajaxToolkit:ModalPopupExtender
ID="ModalPopup"
runat="server"
TargetControlID="ShowModal"
CancelControlID="CloseButton"
OkControlID="DummyOkayControl"
OnCancelScript="OnCanceledHandler();"
OnOkScript="OnOkayedHandler();"
PopupControlID="ModalContentWrapper"
PopupDragHandleControlID="DragHandle"
RepositionMode="repositionOnWindowResize"
DropShadow="false"
>
</ajaxToolkit:ModalPopupExtender>
<asp:Panel ID="ModalContentWrapper" runat="Server">
<table width="600px" border="0" cellpadding="0" cellspacing="0" class="Modal">
<tr>
<td style="width:580px" colspan="2" class="Modal" id="DragHandle" runat="server">
<img src="images/spacer.gif" width="580px" height="20px" alt=""/>
</td>
<td style="width:20px"><asp:Linkbutton ID="CloseButton" runat="server" CssClass="CloseButtonStyle">X</asp:Linkbutton></td>
</tr>
<tr>
<td style="width:20px">
<img src="images/spacer.gif" width="20px" height="360px" alt=""/>
</td>
<td style="width:560px;">
<asp:UpdatePanel ID="Content" runat="server">
<ContentTemplate>
<Controls:ControlLoader ID="MainContent" Key="FirstLoader" runat="server" OnGetControlPath="MainContent_GetControlPath" />
</ContentTemplate>
</asp:UpdatePanel>
</td>
<td style="width:20px">
<img src="images/spacer.gif" width="20px" height="360px" alt=""/>
</td>
</tr>
<tr>
<td style="width:600px" colspan="3">
<img src="images/spacer.gif" width="600px" height="20px" alt=""/>
</td>
</tr>
</table>

 </asp:Panel>
</div>
</form>

All we've done here is Drop a ControlLoaderManager onto the page, just after the ScriptManager. And then we've added an UpdatePanel with a ControlLoaderManger within the UpdatePanel (note we'd likely make this an ConditionalUpdating UpdatePanel, but there's no real need for this example, and it leads to some discussion about the use of UpdatePanels later).

 Here's our JavaScript

<script type="text/javascript">
function OnCanceledHandler(){
alert("Cancel Completed");
}

 function OnOkayedHandler(){
alert("Okay Completed");
}

 function addOkayHandler(clientID, extenderID){
var comp = Sys.Application.findComponent(extenderID);
$addHandler($get(clientID), 'click', Function.createDelegate(comp, comp._onOk));
}

 function addCancelHandler(clientID, extenderID){
var comp = Sys.Application.findComponent(extenderID);
$addHandler($get(clientID), 'click', Function.createDelegate(comp, comp._onCancel));
}

 function init(){
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm){
if (!prm.get_isInAsyncPostBack()){
prm.add_endRequest(endHandler);
if (wireUpHandlers){
wireUpHandlers();
}
}
}

 

function endHandler(sender,args){
wireUpHandlers();
}

</script>
We've made some changes here, for instance adding an EndRequest handler to the PageRequestManager. We need to do this because each time the content of the update panel gets refreshed we need to re-wire or closing/okay buttons.

Here's the Default.aspx.cs code:

protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "RegScript",
string.Format("MODAL_EXTENDER_ID = '{0}'; Sys.Application.add_load(init);", ModalPopup.ClientID), true);
}

protected string MainContent_GetControlPath(object sender, GetControlPathEventArgs e)
{
if (e.Target == "2")
{
return "ControlTwo.ascx";
}
return "ControlOne.ascx";
}
This is our very simple logic to translate a "target" to a control path. In this case if the target == 2, we want to load ControlTwo (code at bottom) else we default to ControlOne (code at bottom). This event delegation of work allows us to insert what ever scheme of control selection we want. Of note this event is trigger twice once at OnInit and once at OnPreRender. We've also added a call to Application.add_load in our StartupScript. This will execute this method every time a response is sent to the client, so we need to have a check in that method "prm.get_isInAsyncPostBack()" that prevents multiple executions of our setup code.

That's basically it. There's some special Code in our controls but nothing that shouldn't be self explanatory. It is fair to argue that there's too much third party handshaking going on here, especially for such a specialized case, but In reality something like the ControlLoaderManager can be very useful even when no controls are being loaded dynamically. It's all too that controls end up implementing interfaces, so they can be cast to it, and values pushed down to it. With the ControlLoaderManager acting as a broker a much more flexible and passive Pull approach can be put into play when managing shared values across controls.

Control Listings:

ControlOne:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ControlOne.ascx.cs" Inherits="ModalClosingExample.ControlOne" %>

 This is the Content of ControlOne:<br />
Put some Text Here for ControlTwo:<asp:TextBox ID="DataFromOne" runat="server" /><br />
<asp:Button ID="Submit" runat="server" Text="Go Get ControlTwo" OnClick="Submit_Click" /><br />
<asp:Label ID="TextFromControlTwo" runat="server" /><br />
<asp:Button ID="OKButton" runat="server" Text="OK" /><br />
<asp:Button ID="CancelButton" runat="server" Text="Cancel" /><br />
<asp:Button ID="MinimizeButton" runat="server" Text="Minimize"/><br /> 
 

protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "wireScripts", getWireScripts(), true);
TextFromControlTwo.Text = ControlLoaderManager.GetManagedValue(Page, "DataFromTwo");

}

protected void Submit_Click(object sender, EventArgs e)
{
ControlLoaderManager.SetManagedValue(Page, "DataFromOne", DataFromOne.Text);
ControlLoaderManager.SetControlLoaderTarget(Page, "FirstLoader", "2");
}

string getWireScripts()
{
StringBuilder script = new StringBuilder();
script.Append("function wireUpHandlers(){");
script.Append("var extenderID = MODAL_EXTENDER_ID;");
script.AppendFormat("addCancelHandler('{0}', extenderID);", CancelButton.ClientID);
script.AppendFormat("addCancelHandler('{0}', extenderID);", MinimizeButton.ClientID);
script.AppendFormat("addOkayHandler('{0}', extenderID);", OKButton.ClientID);
script.Append("}");

return script.ToString();
}

 

ControlTwo:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ControlTwo.ascx.cs" Inherits="ModalClosingExample.ControlTwo" %>

This is the Content of ControlTwo:<br />
Put some Text Here for ControlOne:<asp:TextBox ID="DataFromTwo" runat="server" /><br />
<asp:Button ID="Submit" runat="server" Text="Go Get ControlOne" OnClick="Submit_Click" /><br />
<asp:Label ID="TextFromControlOne" runat="server" /><br />
<asp:Button ID="OKButton" runat="server" Text="OK" /><br />
<asp:Button ID="CancelButton" runat="server" Text="Cancel" /><br />
<asp:Button ID="MinimizeButton" runat="server" Text="Minimize"/><br />
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "wireScripts", getWireScripts(), true);
TextFromControlOne.Text = ControlLoaderManager.GetManagedValue(Page, "DataFromOne"); 
 

}

protected void Submit_Click(object sender, EventArgs e)
{
ControlLoaderManager.SetManagedValue(Page, "DataFromTwo", DataFromTwo.Text);
ControlLoaderManager.SetControlLoaderTarget(Page, "FirstLoader", "1");
}

string getWireScripts()
{
StringBuilder script = new StringBuilder();
script.Append("function wireUpHandlers(){");
script.Append("var extenderID = MODAL_EXTENDER_ID;");
script.AppendFormat("addCancelHandler('{0}', extenderID);", CancelButton.ClientID);
script.AppendFormat("addCancelHandler('{0}', extenderID);", MinimizeButton.ClientID);
script.AppendFormat("addOkayHandler('{0}', extenderID);", OKButton.ClientID);
script.Append("}");

return script.ToString();
}

Print | posted on Sunday, October 07, 2007 9:39 PM
Comments have been closed on this topic.