Welcome to MSDN Blogs Sign in | Join | Help

Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

I previously blogged a sample demonstrating how to use the AJAX Control Toolkit's dynamic population functionality with a data-bound ModalPopup. That sample was well received, but some of the changes that happened as part of the ASP.NET AJAX Beta 1 and Beta 2 releases have rendered the sample code I originally posted un-runnable on current builds.

No worries - it's a simple matter to update the sample and the exercise should serve as a good example of some of the things that need to be done as part of an upgrade. (For a far more in depth guide to upgrading, please refer to Shawn's AJAX Control Toolkit Migration Guide and follow-up about upgrading Web Services/Methods.)

Referring to the sample code I posted earlier as a starting point, the 5 things we need to do to update it are:

  1. Change the tag prefix for ScriptManager from "atlas" to "asp" to point to the new location for ScriptManager
  2. Change the @Register tag to refer to the AjaxControlToolkit by its new name ("AtlasControlToolkit"->"AjaxControlToolkit" twice and "atlasToolkit"->"ajaxToolkit" once)
  3. Change the corresponding tag prefix for ModalPopupExtender from "atlasToolkit" to "ajaxToolkit"
  4. Copy the properties of the ModalPopupProperties element to the ModalPopupExtender element and remove the empty ModalPopupProperties element now that the XxxProperties elements are no longer used
  5. Update the web method definition by making the GetContent method static and adding the [Microsoft.Web.Script.Services.ScriptMethod] attribute

That's it! As you can see, it's mostly simple "find-and-replace" naming changes that can easily be applied to an entire site at once. The XxxProperties change is slightly more involved, but requires very little effort since it's basically just a "cut-and-paste" operation. The web method changes are also a little bit of effort, but the changes themselves are simple and it's easy to find where to make them by searching for the pre-existing "WebMethod" attribute. Nothing here is risky or error-prone and - with the exception of the web method changes - the compiler will report all of them as errors until they're fixed correctly.

For completeness, here's a reminder of what dynamic population looks like in action:

Animated demonstration

And here's the complete sample code after the changes discussed above have been applied. This sample runs fine on the ASP.NET AJAX Beta 2 and the AJAX Control Toolkit 61106 release:

<%@ Page Language="C#" %>
<%
@ 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">

<
script runat="server">
  [System.Web.Services.WebMethod]
  [Microsoft.Web.Script.Services.
ScriptMethod]
  
public static string GetContent(string contextKey)
  {
    
// Create a random color
    string color = (new Random()).Next(0xffffff).ToString("x6");
    
// Use the style specified by the page author
    string style = contextKey;
    
// Display the current time
    string time = DateTime.Now.ToLongTimeString();
    
// Compose the content to return
    return "<span style='color:#" + color + "; " + style + "'>" + time + "</span> ";
  }
</script>

<
html xmlns="http://www.w3.org/1999/xhtml">
<
head id="Head1" runat="server">
  <title>Dynamic ModalPopup Demonstration</title>

  <%-- Style the page so it looks pretty --%>
  
<style type="text/css">
    body { font-family:Verdana;     font-size:10pt; }
    
.background { background-color:Gray; }
    
.popup { width:200px;             padding:10px;        background-color:White;
            
border-style:solid;      border-color:Black;  border-width:2px;
            
vertical-align: middle;  text-align:center; }
  
</style>
</
head>
<
body>
  <form id="form1" runat="server">

    <%-- Atlas pages need a ScriptManager --%>
    
<asp:ScriptManager ID="ScriptManager1" runat="server" />

    <%-- A very simple data source to drive the demonstration --%>
    
<asp:XmlDataSource ID="XmlDataSource1" runat="server">
      <Data>
        <items>
          <item style="font-weight:bold" />
          <item style="font-style:italic" />
          <item style="text-decoration:underline" />
        </items>
      </Data>
    </asp:XmlDataSource>

    <%-- A simple list of all the data items available --%>
    
<asp:DataList ID="DataList1" runat="server" DataSourceID="XmlDataSource1">

      <HeaderTemplate>
        How would you like your dynamic content styled?
      
</HeaderTemplate>

      <ItemTemplate>
        &bull; <asp:LinkButton ID="LinkButton" runat="server" Text='<%# Eval("style") %>' />

        <%-- The ModalPopupExtender, popping up Panel1 and dynamically populating Panel2 --%>
        
<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender" runat="server"
            TargetControlID="LinkButton" PopupControlID="Panel1" OkControlID="Button1"
            BackgroundCssClass="background" DynamicControlID="Panel2"
            DynamicContextKey='<%# Eval("style") %>' DynamicServiceMethod="GetContent" />
      </ItemTemplate>

    </asp:DataList>

    <%-- All ModalPopups share the same popup --%>
    
<asp:Panel ID="Panel1" runat="server" CssClass="popup" style="display:none;">
      <p>This popup popped at <asp:Label ID="Panel2" runat="server" /> and all was well.</p>
      <p><asp:Button ID="Button1" runat="server" Text="OK" /></p>
    </asp:Panel>

  </form>
</
body>
</
html>

Enjoy!

Published Friday, November 17, 2006 7:55 PM by Delay

Comments

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, November 20, 2006 12:37 PM by leomrozek

I tried the above and it works great if you are on a single aspx page. However, If I nest the code into a Web User Control and drop onto a web page that uses a Master Web Page the Web Method is never executed. Any suggestions on how to make this scenario work? Are there scripts I need to move/update for this scenario?

I am using other AJAX Controls on this page like the CollapsiblePanelExtender, UpdateProgress and UpdatePanels and they are working fine, its just the WebMethod is never called from the ModalPopupExtender.

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, November 20, 2006 11:44 PM by Delay

leomrozek,

The problem seems to come about when you insert the sample code into a WebUserControl. When the attempt is made to call the GetContent method to populate the dynamic content, the call is made relative to the page hosting the WebUserControl. However, the GetContent method isn't defined there, and the relevant logic to connect the caller to the method doesn't seem to be done by ASP.NET AJAX. To address this issue, you can simply move the GetContent implementation out to the page hosting the WebUserControl. Alternatively, make it a WebService and then you can host it and call it from anywhere you want!

# Dynamic content made easy *remix* [How to: Use the new dynamic population support for Toolkit controls]

Thursday, November 30, 2006 6:10 PM by Delay's Blog

I previously blogged an update to my sample demonstrating how to use the AJAX Control Toolkit's dynamic

# DataGrid inside Panel1

Sunday, December 17, 2006 4:11 AM by Steward5732

How about if I want DataGrid or DataView inside Panel1 which value depends on DynamicContextKey?

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, December 18, 2006 8:33 PM by Delay

Steward5732,

Something like what ScottGu blogged about in the following post should work for you:

http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx

We're hoping to incorporate a method of rendering ASP.NET controls for dynamic content into the Toolkit in a future release in order to make this easy for everyone. For now, ScottGu's blog has helped a number of people out, so please give it a try!

# HoverMenuExtender - Web Service call failed: 500 (with ASP.NET AJAX 1.0)

Thursday, January 25, 2007 1:48 PM by ASP.NET AJAX Toolkit Forum Posts

Hi all, I have installed ASP.NET AJAX 1.0 (the 01/23/2007 release) I have a usercontrol with a Panel

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, January 29, 2007 5:20 PM by jf25

I am getting an javascript "unknown runtime error" occurring on the below method.

The error is on "e.innterHMTL = results" line .

Has anyone else had this problem?

Thanks.

_onMethodComplete : function (result, userContext, methodName) {

       // ignore if it's not the current call.

       if (userContext != this._currentCallID) return;

       // Time has passed; make sure the element is still accessible

       var e = this.get_element();

       if (e) {

           e.innerHTML = result;

       }

       this._setUpdating(false);

   },

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, January 29, 2007 8:28 PM by Delay

jf25,

I've seen IE give errors like this when attempting to write to the innerHTML property of an INPUT element. Maybe check that the DynamicControlID is pointing to something like an asp:Label instead of an asp:TextBox?

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Friday, February 23, 2007 12:32 PM by ric_castagna

OK...I've got a variation on a theme here, and I'm starting to beat my head against the wall.

I can see from your example, you're able to set the DynamicContextKey with the Eval statement because you've got the databinding going on in the same context.

What I've got is a cascading dropdown list which is populated from external web service calls. This effectively removes the "local" databinding that you enjoy in your example.

So, I've been trying to get the value out of the dropdown list but for the life of me can't get it to select just the value of the appropriate dropdown.

Can you help shed some light on this? I know it's probably not 100% a modalpopup problem, but it's starting to get really annoying! :)

I've tried all the things I know to try:

DynamicContextKey="<%# Eval(ddlLessons.SelectedValue.ToString()) %>"

DynamicContextKey = <%= ddlLessons.SelectedValue %>

etc...

Of course, when I pass in a plain 'ol string value of "Test" the WebService receives the value of "Test" as the parameter. I just need to make it Dynamic now.

Thanks for the help!

Ric

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Friday, February 23, 2007 4:53 PM by Delay

ric_castagna,

The <%=/<%# syntax you're using in your example is evaluated on the server at page render time when creating the HTML for the web page. It sounds like you're trying to use that syntax to set DynamicContextKey on the client to whatever value is chosen in a DropDownList control that doesn't postback. If so, I don't think that'll work since the server doesn't get involved and has no opportunity to render out the desired value.

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Friday, February 23, 2007 5:15 PM by ric_castagna

Delay,

That makes a lot of sense, actually...so, have you found a way to make that DynamicContextKey something that can be set from a client-side function or in response to the OnSelectedIndexChanged event of the dropdown(s) that are already being 'watched' by an update panel?

I'd hate to have to scrap this entire idea, but populating the information and tracking the value is necessary if I'm going to be able to use this for modify/delete operations.

I appreciate the help!

Ric

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Friday, February 23, 2007 5:35 PM by Delay

ric_castagna,

ModalPopupBehavior exposes a set_DynamicContextKey method (defined by DynamicPopulateBehaviorBase in BaseScripts.js) that you can use for this purpose. However, because the populate method in DynamicPopulateBehaviorBase caches the DynamicPopulateBehavior instance it creates, that technique will only affect the first invocation of ModalPopup. If that's not a problem for your scenario, great!

But if you need to change the value subsequently, you could examine the _dynamicPopulateBehavior member of your ModalPopupBehavior instance to verify the internal DynamicPopulateBehavior has been created and then call set_ContextKey on that instance to update the value it uses. This technique should work fine, though please note that _dynamicPopulateBehavior is officially "private", so this method could possibly break in a future release (though I doubt it will).

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, February 26, 2007 11:56 AM by ric_castagna

OK, I must be too dumb to understand how to implement the set_DynamicContextKey method you've talked about.

Where can I wire this up? I've tried attaching it to the "OnClientClick" property of the linkbutton that is supposed to fire my modalpopup, but it just hangs the browser. Odd discovery, when I put simple javascript such as alert("Hello") into that OnClientClick property it works just as expected...it's only when I try to call a javascript function that the browser hangs.

I know that Davaus was trying to do this on another thread of your blog, but unfortunately for me, he didn't show how to call the javascript function either.

I really appreciate and need some help on this one!

Ric

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, February 26, 2007 4:49 PM by Delay

ric_castagna,

The sample code below is derived from the sample from this post (which is available as ToolkitTests\Manual\DataboundDynamicPopulate.aspx in Toolkit releases). I've simplified the code and modified it to demonstrate the use of set_DynamicContextKey as discussed above. To see it in action, view the page, click "Popup", note the text "Original", dismiss the popup, click "Change", click "Popup", and note the updated text "Changed". This text comes from the ModalPopup's contextKey and the "Change" button uses set_DynamicContextKey to make the switch.

Hope this helps!

<%@ Page Language="C#" %>

<%@ 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">

<script runat="server">

 [System.Web.Services.WebMethod]

 [System.Web.Script.Services.ScriptMethod]

 public static string GetContent(string contextKey)

 {

   return contextKey;

 }

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

 <title>ModalPopup set_DynamicContextKey Demonstration</title>

 <style type="text/css">

   body { font-family:Verdana;     font-size:10pt; }

   .background { background-color:Gray; }

   .popup { width:200px;             padding:10px;        background-color:White;

            border-style:solid;      border-color:Black;  border-width:2px;

            vertical-align: middle;  text-align:center; }

 </style>

</head>

<body>

 <form id="form1" runat="server">

   <asp:ScriptManager ID="ScriptManager1" runat="server" />

   <asp:LinkButton ID="LinkButton" runat="server" Text='Popup' />

   <ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender" runat="server"

     TargetControlID="LinkButton" PopupControlID="Panel1" OkControlID="Button1"

     BackgroundCssClass="background" DynamicControlID="Label1"

     DynamicServiceMethod="GetContent" DynamicContextKey="Original"

     BehaviorID="ModalPopupBehavior" />

   <asp:Button ID="Button" runat="server" Text="Change" UseSubmitBehavior="true"

     OnClientClick="$find('ModalPopupBehavior').set_DynamicContextKey('Changed'); return false;" />

   <asp:Panel ID="Panel1" runat="server" CssClass="popup" style="display:none;">

     <p><asp:Label ID="Label1" runat="server" /></p>

     <p><asp:Button ID="Button1" runat="server" Text="OK" /></p>

   </asp:Panel>

 </form>

</body>

</html>

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Tuesday, February 27, 2007 5:05 PM by ric_castagna

Dude...you rock! Works like a champ. I never would've thought to chain javascript into the OnClientClick event...I kept looking for a way to call a single function and, as we saw, that wasn't doing me a bit of good.

Thanks for the help!

Ric

# Using DynamicServiceMethod with HoverMenu Extender

Monday, March 19, 2007 2:21 PM by ASP.NET AJAX Toolkit Forum Posts

hi I would like to dynamically populate a datalist on a panel that will be popped up by my HoverExtender.

# ModalPopupExtender as a wait cursor possible?

Thursday, March 29, 2007 8:14 PM by Mehdi_LA

Is it possible to use the ModalPopupExtender to simply display a wait panel with no OK/Cancel button on it while a web service call is being made and then remove panel (modal popup) once the web server returns the results (and display the results on the page)?

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Thursday, March 29, 2007 8:49 PM by Delay

Mehdi_LA,

Yes, this should be pretty easy! All you need to do in JavaScript on the client side is to find the ModalPopupBehavior (use $find and specify the value of the ModalPopupExtender's BehaviorID property), call the behavior's .show() method before calling your web service to display the popup, and then call the .hide() method after the web service completes (successfully or unsuccessfully). It's that easy! :)

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Sunday, April 08, 2007 6:24 PM by verrrierRoberts

Setting the DynamicContextKey on the client side - One solutio.

I have seen the methods to set the DynamicContextKey at dynamically at databinding using set_DynamicContextControl, this does not work for me, though setting _DynamicContextKey does work. This means you can have one modalPOpUpExtender driven off the entries in at table set on an onclick event roughly set up by

   popper = $find('yourmodalPopupExtender');

   popper._DynamicContextKey = ctxval;

   popper.show();

This is based on an idea from Damian Meher's blog at

http://damianblog.com/2007/02/28/calling-extenders-from-js/

It seems you have to set the DynamicControlID to a div tag you want to replace which leaves the OKButton in place.

Jonathan Roberts

# When setting in web.config cookieless="true" I get "Web Service call failed: 500"

Saturday, May 12, 2007 6:09 AM by joergbauer

Hello,

thanks for your nice code. Everything works fine.

When I upload this on my server and set in my web.config sessionState to cookieless="true"

I get this error message: Web Service call failed: 500

What can I do now? Is there any solutions for this?

Thanks for any help!

Joerg

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Sunday, May 13, 2007 7:08 PM by Delay

Joerg,

When you set configuration/system.web/sessionState[cookieless="true"], ASP.NET stores its SessionID in the URL instead of in a cookie. The Toolkit's ServicePathConverter (ExtenderBase\ServicePathConverter.cs] doesn't preserve the SessionID part of the URL for page method web services (i.e., web services where the ServicePath is not set and the method lives in the same page), so a System.InvalidOperationException results with the message "Authentication failed." and the web service call fails as you report. I was able to fix this on my machine by changing the ServicePathConverter's use of currentContext.Request.FilePath to currentContext.Request.RawUrl on line 27 of ServicePathConverter.cs. I've just created work item 10262 [http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=10262] to address this in a future release of the Toolkit.

Thanks for reporting this!

# currentContext.Request.RawUrl works but not with a query in URL

Monday, May 14, 2007 6:16 PM by joergbauer

Delay,

I changed it to currentContext.Request.RawUrl and it worked but if the URL has a query like http://mydomain.com?query=xxx it does not work.

Do you have a solution for this new problem?

Thanks for your help!

Joerg

# re: Dynamic content made easy *redux* [How to: Use the new dynamic population support for Toolkit controls]

Monday, May 14, 2007 8:40 PM by Delay

Joerg,

Indeed I have a new solution. :) Well, I guess it's more of a revised solution... Like before, we want to get at the URL with the SessionID in it - except this time the implementation's a little more involved. The RawUrl property was nice for having the SessionID in it, but didn't work in the more complicated scenario because it also had the query string in it. So what we want is to get access to a Uri object based on RawUrl so we can use the methods of the Uri class to strip off the query string properly. With this alternate approach the line of code (same location as before) looks like:

return (new Uri(currentContext.Request.Url, currentContext.Request.RawUrl)).AbsolutePath;

I've this out and it seems to work with/without a query string. I hope it works as well for you!

Anonymous comments are disabled
 
Page view tracker