<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Tales from the Evil Empire : HTML</title><link>http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx</link><description>Tags: HTML</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Orchard team looking for a new developer</title><link>http://weblogs.asp.net/bleroy/archive/2009/11/23/orchard-team-looking-for-a-new-developer.aspx</link><pubDate>Mon, 23 Nov 2009 19:24:19 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7263678</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7263678</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/11/23/orchard-team-looking-for-a-new-developer.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2005 Bertrand Le Roy" border="0" alt="(c) 2005 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/Dragonfly_5E7683B7.jpg" width="244" height="164" /&gt; My team is looking for a new full-time developer. The project is to build a completely new open-source CMS based on ASP.NET MVC 2. It’s a lot of fun :)&lt;/p&gt;  &lt;p&gt;&lt;a href="https://careers.microsoft.com/JobDetails.aspx?ss=&amp;amp;pg=0&amp;amp;so=&amp;amp;rw=1&amp;amp;jid=9434&amp;amp;jlang=EN"&gt;https://careers.microsoft.com/JobDetails.aspx?ss=&amp;amp;pg=0&amp;amp;so=&amp;amp;rw=1&amp;amp;jid=9434&amp;amp;jlang=EN&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7263678" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/SQL/default.aspx">SQL</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>JavaScript class browser: once again with jQuery</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/30/javascript-class-browser-once-again-with-jquery.aspx</link><pubDate>Fri, 30 Oct 2009 17:43:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7243389</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7243389</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/30/javascript-class-browser-once-again-with-jquery.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/MercuryWeb_1CBF87AD.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2004 Bertrand Le Roy" border="0" alt="(c) 2004 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/MercuryWeb_thumb_1373269F.jpg" width="184" height="244" /&gt;&lt;/a&gt; I’ve already posted twice about that little class browser application. The first iteration was mostly declarative and can be found here:    &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The second one was entirely imperative and can be found here:   &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This new version builds on top of the code for the imperative version and adds the jQuery dependency in an attempt to make the code leaner and simpler. I invite you to refer to the imperative code (included in the &lt;a href="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQuery.zip"&gt;archive for this post&lt;/a&gt;) and compare it with the jQuery version, which shows a couple of ways the Microsoft Ajax Library lights up when jQuery is present.&lt;/p&gt;  &lt;p&gt;The first thing I want to do here is convert the plain function I was using to build the browser’s namespace and class tree into a jQuery plug-in:&lt;/p&gt;  &lt;pre class="code"&gt;$.fn.classBrowserTreeView = &lt;span style="color: blue"&gt;function &lt;/span&gt;(options) {
  &lt;span style="color: blue"&gt;var &lt;/span&gt;opts = $.extend({},&lt;br /&gt;    $.fn.classBrowserTreeView.defaults,&lt;br /&gt;    options);
  &lt;span style="color: blue"&gt;return this&lt;/span&gt;;
};&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That plug-in will have two options: the data to render (which will default to the root namespaces in the Microsoft Ajax Library), and the node template selector (which will default to “#nodeTemplate”):&lt;/p&gt;

&lt;pre class="code"&gt;$.fn.classBrowserTreeView.defaults = {
  data: Type.getRootNamespaces(),
  nodeTemplate: &lt;span style="color: maroon"&gt;&amp;quot;#nodeTemplate&amp;quot;
&lt;/span&gt;};&lt;/pre&gt;

&lt;p&gt;For the moment, as you can see, this plug-in does nothing. We want it to create a DataView control on each of the elements of the current wrapped set. We will do this by calling into the dataView plug-in.&lt;/p&gt;

&lt;p&gt;You may be wondering where this plug-in might come from. Well, that’s the first kind of lighting up that the Microsoft Ajax Library’s script loader (start.js) will do in the presence of jQuery: every control and behavior will get surfaced as a jQuery plug-in, and components will get added as methods on the jQuery object. This is similar to what I had shown a while ago in this post, only much easier:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, we can write this in our own plug-in to create DataView components over the current jQuery wrapped set:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;return this&lt;/span&gt;.dataView({
  data: opts.data,
  itemTemplate: opts.nodeTemplate,
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now we can wire up the itemRendered event of the data view and start enriching the markup that the DataView control rendered for each data item. First, let’s get hold of the nodes in the rendered template and wrap them:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;elt = $(args.nodes);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then, if the current node is representing a namespace, we want to hook up the expansion button’s click event so that it toggles visibility of the list of children, and we want to “unhide” the button itself (it has a “hidden” class in the default markup):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Type.isNamespace(args.dataItem)) {
  elt.find(&lt;span style="color: maroon"&gt;&amp;quot;.toggleButton&amp;quot;&lt;/span&gt;).click(&lt;span style="color: blue"&gt;function &lt;/span&gt;(e) {
    e.preventDefault();
    &lt;span style="color: blue"&gt;return &lt;/span&gt;toggleVisibility(&lt;span style="color: blue"&gt;this&lt;/span&gt;);
  }).removeClass(&lt;span style="color: maroon"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You can see here that we’re taking advantage of chaining.&lt;/p&gt;

&lt;p&gt;Next thing is to set-up the node link itself. We start by inhibiting the link’s default action. Then we set the text for the link, and finally we set the command that will bubble up to the DataView when the link gets clicked:&lt;/p&gt;

&lt;pre class="code"&gt;elt.find(&lt;span style="color: maroon"&gt;&amp;quot;.treeNode&amp;quot;&lt;/span&gt;).click(&lt;br /&gt;  &lt;span style="color: blue"&gt;function &lt;/span&gt;(e) {&lt;br /&gt;    e.preventDefault();&lt;br /&gt;    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;&lt;br /&gt;  })
  .text(getSimpleName(args.dataItem.getName()))
  .setCommand(&lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Here, I’m using a small plug-in to set the command:&lt;/p&gt;

&lt;pre class="code"&gt;$.fn.setCommand = &lt;span style="color: blue"&gt;function &lt;/span&gt;(options) {
  &lt;span style="color: blue"&gt;var &lt;/span&gt;opts = $.extend({},&lt;br /&gt;    $.fn.setCommand.defaults, options);
  &lt;span style="color: blue"&gt;return &lt;/span&gt;$(&lt;span style="color: blue"&gt;this&lt;/span&gt;).each(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    $.setCommand(&lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;br /&gt;      opts.commandName,&lt;br /&gt;      opts.commandArgument,&lt;br /&gt;      opts.commandTarget);
  });
}
$.fn.setCommand.defaults = {
    commandName: &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;,
    commandArgument: &lt;span style="color: blue"&gt;null&lt;/span&gt;,
    commandTarget: &lt;span style="color: blue"&gt;null
&lt;/span&gt;};&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I’m using $.setCommand here, which does get created by the framework for me, but I still need to create that small plug-in to make it work on a wrapped set instead of a static method off jQuery. I’ve sent feedback to the team that setCommand and bind should get created as plug-ins by the framework and hopefully it will happen in a future version.&lt;/p&gt;

&lt;p&gt;The last thing we need to do here is to recursively create the child branches of our tree:&lt;/p&gt;

&lt;pre class="code"&gt;elt.find(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;).classBrowserTreeView({
    data: getChildren(args.dataItem)
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This just finds the child UL element of the current branch and calls our plug-in on the results with the children namespaces and classes as the data.&lt;/p&gt;

&lt;p&gt;And this is it for the tree, we can now create it with this simple call:&lt;/p&gt;

&lt;pre class="code"&gt;$(&lt;span style="color: maroon"&gt;&amp;quot;#tree&amp;quot;&lt;/span&gt;).classBrowserTreeView();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The details view rendering will only differ in minor ways from the code we had in our previous imperative version. The only differences is the use of jQuery to traverse and manipulate the DOM instead of the mix of native DOM APIs and Sys.get that we were using before. For example,&lt;/p&gt;

&lt;pre class="code"&gt;args.get(&lt;span style="color: maroon"&gt;&amp;quot;li&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;  args.dataItem.getName ?&lt;br /&gt;    args.dataItem.getName() :&lt;br /&gt;    args.dataItem.name;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;pre class="code"&gt;$(args.nodes).filter("li").text(&lt;br /&gt;  args.dataItem.getName ?&lt;br /&gt;    args.dataItem.getName() :&lt;br /&gt;    args.dataItem.name);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice how jQuery’s text method makes things a little more secure than the innerHTML we had used before.&lt;/p&gt;

&lt;p&gt;Updating the details view with the data for the item selected in the tree is done by handling the select command of the tree from the following function:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
  &lt;span style="color: blue"&gt;if &lt;/span&gt;(args.get_commandName() === &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;      args.get_commandSource()).dataItem;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;isClass = Type.isClass(dataItem) &amp;amp;&amp;amp;&lt;br /&gt;                 !Type.isNamespace(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childData =&lt;br /&gt;      (isClass ? getMembers : getChildren)(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;detailsChild =&lt;br /&gt;      Sys.Application.findComponent(&lt;span style="color: maroon"&gt;&amp;quot;detailsChild&amp;quot;&lt;/span&gt;);
    detailsChild.onItemRendering =&lt;br /&gt;      isClass ?&lt;br /&gt;        onClassMemberRendering :&lt;br /&gt;        onNamespaceChildRendering;
    detailsChild.onItemRendered =&lt;br /&gt;      onDetailsChildRendered;
    detailsChild.set_data(childData);
    $(&lt;span style="color: maroon"&gt;&amp;quot;#detailsTitle&amp;quot;&lt;/span&gt;).text(dataItem.getName());
    $(&lt;span style="color: maroon"&gt;&amp;quot;.namespace&amp;quot;&lt;/span&gt;).css(&lt;br /&gt;      &lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;,&lt;br /&gt;      isClass ? &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;);
    $(&lt;span style="color: maroon"&gt;&amp;quot;.class&amp;quot;&lt;/span&gt;).css(&lt;br /&gt;      &lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;,&lt;br /&gt;      isClass ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;);
    $(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;).css(&lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;);
  }
}&lt;/pre&gt;

&lt;p&gt;Not much change here from the previous version, again, except for the use of jQuery and some chaining.&lt;/p&gt;

&lt;p&gt;And that is pretty much it. I’ve made other changes in the script to make use of the new script loader in the Microsoft Ajax Library but that will be the subject of a future post.&lt;/p&gt;

&lt;p&gt;Hopefully, this has shown you how the Microsoft Ajax Library can light up with jQuery. The automatic creation of plug-ins feels very much like native jQuery plug-ins and brings all the power of client templates to jQuery. Once we have bind and setCommand plug-ins as well, the Microsoft Ajax Library may become a very useful tool to jQuery programmers just as much as jQuery itself is a very useful tool to Microsoft Ajax programmers.&lt;/p&gt;

&lt;p&gt;The code can be found here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; fixed a problem in Firefox &amp; Chrome.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7243389" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>How to render the same template on the server and client with minimal redundancy</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/19/how-to-render-the-same-template-on-the-server-and-client-with-minimal-redundancy.aspx</link><pubDate>Mon, 19 Oct 2009 08:50:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7232857</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7232857</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/19/how-to-render-the-same-template-on-the-server-and-client-with-minimal-redundancy.aspx#comments</comments><description>&lt;h4&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) 2005 Bertrand Le Roy" border="0" alt="(c) 2005 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/buildingreflection_6007098A.jpg" width="180" height="260" /&gt; &lt;/h4&gt;  &lt;p&gt;Last week, I wrote &lt;a href="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx"&gt;a post about how the new Microsoft Ajax Library Preview 6 made it a lot easier to write unobtrusive and imperative data-driven applications&lt;/a&gt;. Because for the previous preview, I had written a cool little class browser using a declarative style, I thought it would be nice to rewrite this in a completely imperative way. The mistake I made though was to call it unobtrusive. Never mind that ‘unobtrusive’ is a perfectly well-defined word that actually existed way before JavaScript. ‘Unobtrusive JavaScript’ has a very specific meaning that people feel strongly about. To be worthy of that label, an application must basically conform to (at least) those two requirements:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Markup and behavior are strictly separated.&lt;/strong&gt; That means no DOM-0 event handlers, no custom attributes or tags, and even no microformats imo. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Graceful degradation / progressive enhancement.&lt;/strong&gt; This means that the application’s script is only used to improve what would work without script, in other words that the application is entirely usable without script. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;While my little sample strictly conformed to (1), it didn’t conform to (2). Not because I’m too dumb or ignorant, mind you, but because for this application, it didn’t make any sense at all: the application’s whole point is to display client-side script objects. The server does not have the first clue about the data that needs to be rendered. Which makes it impossible for anything to render without script. Which in turn triggered some unpleasant comments on the post: this was not really unobtrusive JavaScript in the full sense of the term. Not the library’s fault though, just my own for using the wrong example.&lt;/p&gt;  &lt;h4&gt;The right example&lt;/h4&gt;  &lt;p&gt;So I thought the best thing to fix this is to provide a more relevant example, one where the server could actually be a fallback scenario.&lt;/p&gt;  &lt;p&gt;The new sample code is a fairly simple master-details view on a silly data set: jedi data. We have a WCF web service that is returning a list of jedis and their associated data, which the application can render on the server-side or on the client-side.&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Jedis" border="0" alt="Jedis" src="http://weblogs.asp.net/blogs/bleroy/Jedis_0779A810.png" width="413" height="176" /&gt; Once you&amp;#160; have data that is available from both the server and client sides, your best and simplest tool to achieve progressive enhancement is the plain &amp;lt;a&amp;gt; tag. You can build the links in your application so that without script, they do something meaningful:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;?jedi=all&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;expandButton&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What you see above is the + link on the top-left of the screen that will expand the list of jedis. To make it work client-side instead of the server-side, you use script to add a click handler that suppresses the default behavior of the link and replaces it with the equivalent client-side action:&lt;/p&gt;

&lt;pre class="code"&gt;Sys.UI.DomEvent.addHandler(&lt;br /&gt;  Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#expandButton&amp;quot;&lt;/span&gt;), &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
    e.preventDefault();
    jediList.fetchData();
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
  });&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That’s fairly easy and has been possible since, well, I’m not sure but it’s been a looong time.&lt;/p&gt;

&lt;p&gt;Now there’s the templated rendering. Rendering the same thing from the server and the client without repeating oneself too much is not as simple. The key to it is to render the server template with an empty data item and then to use the result of that as the client template.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediList&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;if (!isDetails) { &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt; &lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;jedis = !isDetails ?
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Jedi&lt;/span&gt;&amp;gt;() {&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Jedi&lt;/span&gt;()} :
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;JediService&lt;/span&gt;().GetJedis();
  &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;jedi &lt;span style="color: blue"&gt;in &lt;/span&gt;jedis) { &lt;span style="background: yellow"&gt;%&amp;gt;
&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;?&lt;span style="color: red"&gt;jedi&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;jedi.Name &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&amp;gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;jedi.Name&lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;br /&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;} &lt;span style="background: yellow"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This way, there is only one template, only one version of the markup, that we are using on both the server and client sides. When rendered from the server with the actual data set, we get the list right away, and the browser just displays it (and search engines can see the list as well, something you can’t achieve with pure script). When rendered with the dummy dataset, we get the following:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediList&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;  &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;?jedi&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;all&amp;quot;&amp;gt;all&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This markup can be used as a template on the client-side by this code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;jediList = Sys.create.dataView(&lt;span style="color: maroon"&gt;&amp;quot;#jediList&amp;quot;&lt;/span&gt;, {
  dataProvider: &lt;span style="color: maroon"&gt;&amp;quot;JediService.svc&amp;quot;&lt;/span&gt;,
  fetchOperation: &lt;span style="color: maroon"&gt;&amp;quot;GetJedis&amp;quot;&lt;/span&gt;,
  autoFetch: &lt;span style="color: blue"&gt;false&lt;/span&gt;,
  itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;link = args.get(&lt;span style="color: maroon"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = args.dataItem;
    link.innerHTML = dataItem.Name;
    Sys.UI.DomEvent.addHandler(&lt;br /&gt;      link, &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
        e.preventDefault();
        details.set_data(dataItem);
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
      });
  }
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The details view is built on pretty much the same principle. The main difference is that it does have additional markup to delimit the fields that we’ll want to set dynamically. Here’s how it renders with the dummy data:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;details&amp;quot;&lt;/span&gt; &lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediName&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;owns a
    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediLightSaber&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;lightsaber and is on the
    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediSide&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;side.
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;All the itemRendered handler has to do then is fill in the blanks:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;details = Sys.create.dataView(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;, {
  itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediName&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.Name;
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediLightSaber&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.LightsaberColor;
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediSide&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.DarkSide ? &lt;span style="color: maroon"&gt;&amp;quot;dark&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;light&amp;quot;&lt;/span&gt;;
  }
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;So what do you think?&lt;/p&gt;

&lt;p&gt;Here’s the code (by the way, I’m using the Microsoft CDN in there): 
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplates.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplates.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplate.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7232857" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Entirely unobtrusive and imperative templates with Microsoft Ajax Library Preview 6</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx</link><pubDate>Thu, 15 Oct 2009 09:12:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7230434</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7230434</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/IMG_2305_0DB1EDD9.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) 2009 Bertrand Le Roy" border="0" alt="(c) 2009 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/IMG_2305_thumb_138C9172.jpg" width="244" height="164" /&gt;&lt;/a&gt; Today is the release of the sixth preview of Microsoft Ajax Library. Don’t get fooled by the somewhat silly and long name: this is a major release in many ways. The scripts have been majorly refactored since preview 5. Check out the other posts out there (links at the bottom of this post) to see just some of the many new features that are in there. Some of my favorite are all the small improvements that have been made to make imperative instantiation of components and templated contents easier than ever. Many of you have told us that you preferred to do things imperatively and this release makes it a lot better.&lt;/p&gt;  &lt;p&gt;When Preview 5 came out, I built a simple class browser using the declarative syntax. The class browser shows the hierarchy of namespaces and classes in a tree view on the left side of the page, and the details of whatever’s selected in the tree on the right side of the page:&lt;a href="http://weblogs.asp.net/blogs/bleroy/ClassBrowser2_36D98617.png"&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="The JavaScript class browser" border="0" alt="The JavaScript class browser" src="http://weblogs.asp.net/blogs/bleroy/ClassBrowser2_thumb_23B8596B.png" width="504" height="187" /&gt;&lt;/a&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It still works (and an updated version is attached to this post), but I thought I would demonstrate how you can take that same sample and re-implement it in a completely imperative way. Of course, you never have to go all the way one way or another, and it’s always possible for example to use the nice declarative syntax for bindings but instantiate your components imperatively if you choose to do so. In this post, I’m deliberately going imperative all the way. Just keep in mind this is rather extreme.&lt;/p&gt;  &lt;p&gt;The first thing to notice in the new version is that the markup is perfectly clean and contains no weird extension, namespace or custom binding syntax whatsoever. It’s 100% pure HTML 5. Here is for example the complete markup for the tree view on that page:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;toggleButton&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;treeNode&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The script that builds the dynamic contents is bootstrapped by the following code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Scripts/start.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
&lt;/span&gt;Sys.loadScripts([&amp;quot;Scr&lt;span style="color: maroon"&gt;ipts/Tree.js&amp;quot;], f&lt;/span&gt;unc&lt;span style="color: blue"&gt;tion() {
  &lt;/span&gt;Sys.require([Sys.components.dataView], function&lt;span style="color: blue"&gt;() {
    &lt;/span&gt;createTreeView(&amp;quot;#tree&amp;quot;,&lt;br /&gt;                   Typ&lt;span style="color: maroon"&gt;e.getRo&lt;/span&gt;otNamespaces(),&lt;br /&gt;                   &amp;quot;#nodeTempla&lt;span style="color: maroon"&gt;te&amp;quot;);
    &lt;/span&gt;Sys.create.dataView(&amp;quot;#detailsChild&amp;quot;, &lt;span style="color: maroon"&gt;{
      &lt;/span&gt;itemRendered: onDetailsChildRendered
    });
  });
});
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We’re making use of the new script loader here: we first include the bootstrapper file, start.js, and then we declare that we need one custom script, “tree.js” and everything necessary to instantiate a DataView. The script loader will figure out on its own the set of scripts it needs to download for that. Once those scripts have been downloaded, we call createTreeView, which is custom code that we’ll look at in a moment that creates nested DataView controls over the markup. We also create a second DataView to display the details of what’s selected in the&amp;#160; tree.&lt;/p&gt;

&lt;p&gt;Notice that we set some properties to a selector string here (for example “#nodeTemplate”). This is actually a breaking change from the previous preview, which only understood id strings. Microsoft Ajax does not include a full selector engine but it does understand the most basic of selectors (.class, tagName and #id). But where it gets really interesting is that if you had included jQuery on the page, the framework would detect it and enable you to use full selectors everywhere. Isn’t that sweet?&lt;/p&gt;

&lt;p&gt;So how does the imperative approach compare with the declarative one? Well, for instantiating components, you already have an example above, where we use Sys.create.dataView. But what about wiring up events, setting text contents and attribute values, instantiating components over the markup inside the template?&lt;/p&gt;

&lt;p&gt;All those are done by post-processing the template instances after they’ve been instantiated, by handling the itemRendered event:&lt;/p&gt;

&lt;pre class="code"&gt;itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
  &lt;span style="color: #006400"&gt;// do magic
&lt;/span&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Wiring up events is as simple as getting a reference to an element and calling addHandler:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;toggleButton = args.get(&lt;span style="color: maroon"&gt;&amp;quot;.toggleButton&amp;quot;&lt;/span&gt;);
Sys.UI.DomEvent.addHandler(toggleButton, &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;,&lt;br /&gt;  &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
    toggleVisibility(&lt;span style="color: blue"&gt;this&lt;/span&gt;);
  }, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The args.get function, which you will use a lot, takes a selector and returns the first element that matches it &lt;em&gt;inside the template&lt;/em&gt;. Here, we are looking for an element with class “toggleButton”, but a local id would work just as well.&lt;/p&gt;

&lt;p&gt;To set text contents and attribute values is trivial once you know how to get references to elements from local selectors (remember, jQuery also works here transparently or even explicitly when and if you need it).&lt;/p&gt;

&lt;p&gt;Finally, instantiating components is also quite easy. For example, here is the code that creates an inner DataView for the child nodes of a node in the tree, recursively:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;childView = args.get(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;);
createTreeView(childView,&lt;br /&gt;               getChildren(args.dataItem),&lt;br /&gt;               nodeTemplate);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The args.get funtion is used once more to get a reference to the first UL element within the template, and it is then easy to do a recursive call into our tree creation function and build the new branch of the tree.&lt;/p&gt;

&lt;p&gt;The command bubbling feature that makes it so easy to wire up custom commands into a template is still usable in imperative code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;treeNode = args.get(&lt;span style="color: maroon"&gt;&amp;quot;.treeNode&amp;quot;&lt;/span&gt;);
Sys.setCommand(treeNode, &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Finally, there is one feature that I’m not using in that sample, but that’s immensely useful, and I’m talking of course of live bindings. Those work too, all you have to do is call the Sys.bind function and give it the target object, the name of the target property to bind, the source object and the source property name.&lt;/p&gt;

&lt;p&gt;To render the details view, I decided to not use a single item DataView like I did with the declarative version: since I’m going to use imperative code instead of declarative bindings, it is just as easy to directly manipulate the DOM that already exists, and do some hiding and showing of elements:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
  &lt;span style="color: blue"&gt;if &lt;/span&gt;(args.get_commandName() === &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;      args.get_commandSource()).dataItem;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;isClass = Type.isClass(dataItem) &amp;amp;&amp;amp;&lt;br /&gt;                 !Type.isNamespace(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childData =&lt;br /&gt;      (isClass ? getMembers : getChildren)(dataItem),
      namespaceElementsDisplay = &lt;br /&gt;        isClass ? &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;,
      classElementsDisplay =&lt;br /&gt;        isClass ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;,
      detailsChild =&lt;br /&gt;        Sys.Application.findComponent(&lt;span style="color: maroon"&gt;&amp;quot;detailsChild&amp;quot;&lt;/span&gt;);
    detailsChild.onItemRendering =&lt;br /&gt;      isClass ?&lt;br /&gt;        onClassMemberRendering :&lt;br /&gt;        onNamespaceChildRendering;
    detailsChild.set_data(childData);
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#detailsTitle&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      dataItem.getName();
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#namespacesColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#classesColumn&amp;quot;&lt;/span&gt;).style.display =&lt;br /&gt;      namespaceElementsDisplay;
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#propertiesColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#eventsColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#methodsColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#staticMethodsColumn&amp;quot;&lt;/span&gt;).style.display =&lt;br /&gt;      classElementsDisplay;
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;).style.display = &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;;
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We do have a DataView to render the contents of the currently selected object though. The nice trick we used with the declarative version to dynamically switch the target place holder where the template gets rendered is still there, which enables a single DataView control to dispatch the data into two to four separate lists (or however much you want for that matter):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onNamespaceChildRendering(args) {
    args.set_itemPlaceholder(
        Type.isClass(args.get_dataItem()) ?
            &lt;span style="color: maroon"&gt;&amp;quot;#classPlaceHolder&amp;quot; &lt;/span&gt;:
            &lt;span style="color: maroon"&gt;&amp;quot;#namespacePlaceHolder&amp;quot;
    &lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I think all this is pretty cool and I hope the comparison between the declarative version and the imperative version of this little application gives you a sense of the flexibility that the Microsoft Ajax library now offers, and of how much you can choose your own development style and do pretty much anything with the same ease.&lt;/p&gt;

&lt;p&gt;Download the code for this post here: 
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Ajax Library Preview 6 can be downloaded from here:
  &lt;br /&gt;&lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488"&gt;http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are a few links about this release:
 &lt;br/&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2009/10/15/announcing-microsoft-ajax-library-preview-6-and-the-microsoft-ajax-minifier.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2009/10/15/announcing-microsoft-ajax-library-preview-6-and-the-microsoft-ajax-minifier.aspx&lt;/a&gt;
  &lt;br /&gt;&lt;a href="http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/"&gt;http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://www.jamessenior.com/post/How-the-Script-Loader-in-the-Microsoft-Ajax-Library-will-make-your-life-wonderful.aspx"&gt;http://www.jamessenior.com/post/How-the-Script-Loader-in-the-Microsoft-Ajax-Library-will-make-your-life-wonderful.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7230434" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>HTML now a data format</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/09/html-now-a-data-format.aspx</link><pubDate>Sat, 10 Oct 2009 06:54:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7226613</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7226613</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/09/html-now-a-data-format.aspx#comments</comments><description>&lt;p&gt;About a year ago, I asked the question on this blog whether HTML could and should be used as a data format:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2008/11/26/should-html-be-considered-as-a-data-format.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2008/11/26/should-html-be-considered-as-a-data-format.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After all, it actually already has semantic constructs appropriate for tabular data, for collections, for hierarchical data and for object graphs of any kind.&lt;/p&gt;  &lt;p&gt;Well, apparently I wasn’t the only one to think that (not that I expected I was):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html"&gt;http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7226613" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Building a class browser with Microsoft Ajax 4.0 Preview 5</title><link>http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx</link><pubDate>Mon, 14 Sep 2009 07:29:37 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7204694</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7204694</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2004 Bertrand Le Roy" border="0" alt="(c) 2004 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/DSCN3593_4CCCACF9.jpg" width="184" height="244" /&gt; The Microsoft Ajax Library 4.0 Preview 5 is the first release of Microsoft Ajax that I didn’t participate in: I left the team a few months ago. But that doesn’t mean I don’t love what’s in there, and I really do. And by the way I’ve also seen what’s in Preview 6 too and man that will seriously rock.&lt;/p&gt;  &lt;p&gt;So I thought I’d write a little something to celebrate the new preview. The new features include recursive templates, which is pretty much begging us to implement a treeview with it, and we’ll do just that in this post.&lt;/p&gt;  &lt;p&gt;There is also an intriguing capability, which enables you to dynamically set what template to render for each data item, and where to render it. At first, this doesn’t look like the most useful thing in the world, but it actually opens up some very interesting possibilities, which we’ll also show in this post.&lt;/p&gt;  &lt;p&gt;The sample code that I’m going to write for this post is a rudimentary class browser. It will render a treeview representing the hierarchical structure of namespaces and classes in Microsoft Ajax, and clicking one of the tree nodes will render a details view for it: a list of classes and subnamespaces for namespaces, and a grouped list of members for classes.&lt;/p&gt;  &lt;p&gt;Let’s start with the tree. It will be rendered as nested unordered lists by a simple recursive DataView:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ Type.getRootNamespaces() }}&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;oncommand&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ onCommand }}&amp;quot;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;return false;&amp;quot;
       &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;command&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;select&amp;quot;&amp;gt;
      &lt;/span&gt;{{ getSimpleName($dataItem.getName()) }}
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ getChildren($dataItem) }}&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;oncommand&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ onCommand }}&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On the first UL, which is the outer DataView for the tree, you can see that we set the data property to Type.getRootNamespaces(), which returns the set of root namespaces currently defined.&lt;/p&gt;

&lt;p&gt;We also set the template to point to the “nodeTemplate” element, which has to be outside the DataView itself when doing recursive templates. Note that the outer node of the template, the UL, won’t actually get rendered into the target ul (tree). It is only a container.&lt;/p&gt;

&lt;p&gt;The command event of the DataView is hooked to the onCommand function, and we’ll get back to that when we couple the tree with the detail view.&lt;/p&gt;

&lt;p&gt;In the template itself, you can see we have a link with the select command so that clicking it will trigger the nearest onCommand event up the DOM.&lt;/p&gt;

&lt;p&gt;The text of that link is the results of a call to getSimpleName, which will extract the last part of the fully-qualified name of the namespace or class.&lt;/p&gt;

&lt;p&gt;After that link, we find another DataView control. The data property of that control points to an array of namespaces and classes under the current object. But the nice part here is that the template property points to “nodeTemplate”, its own parent, enabling the recursive nature of the tree.&lt;/p&gt;

&lt;p&gt;In other words, we’ve morphed a simple DataView control into a tree, with minimal effort and code.&lt;/p&gt;

&lt;p&gt;There is just one thing missing to the tree, and that is the +/- buttons that will collapse and expand the tree nodes. This is actually very easy to set-up using CSS and some simple script. First, let’s collapse the tree by default. This is done by defining the style of the tree as follows in our stylesheet:&lt;/p&gt;

&lt;pre class="code"&gt;.tree ul 
{
    padding: 0;
    display:none;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This has the effect of collapsing all unordered list nodes under the tree.&lt;/p&gt;

&lt;p&gt;The +/- button is created by adding the following to the template, right before the existing link:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;toggleButton&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;
   &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;if&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Type.isNamespace($dataItem)&amp;quot; 
   &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;return toggleVisibility(this);&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The button is a simple link whose rendering is conditioned by whether the current data item is a namespace: only namespaces can be expanded, classes are leaf nodes.&lt;/p&gt;

&lt;p&gt;The toggling function itself is fairly simple:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;toggleVisibility(element) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childList = element.parentNode&lt;br /&gt;                     .getElementsByTagName(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;)[0],
        isClosed = element.innerHTML === &lt;span style="color: maroon"&gt;&amp;quot;+&amp;quot;&lt;/span&gt;;
    childList.style.display =&lt;br /&gt;        isClosed ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;;
    element.innerHTML = isClosed ? &lt;span style="color: maroon"&gt;&amp;quot;-&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;+&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This just toggles the display style of the first child UL between none and block, and the text of the link between + and –.&lt;/p&gt;

&lt;p&gt;So there it is, we have built a simple tree by simply making use of the recursive capabilities of DataView and some very simple script.&lt;/p&gt;

&lt;p&gt;Before we look at the details view, let’s look at the code that gets called when the user selects a node in the tree:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;        args.get_commandSource()).dataItem;
    $find(&lt;span style="color: maroon"&gt;&amp;quot;details&amp;quot;&lt;/span&gt;).set_data(dataItem);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That code gets a reference to the data item for the selected node from the template context that we can get from the sender of the event (the inner DataView that contains the selected node) using the command source as provided by the event arguments (that source is the element that triggered the command). We can then set the data of the details DataView to that data item, which will trigger that view to re-render.&lt;/p&gt;

&lt;p&gt;Now let’s build the details view. The details view will display the child namespaces and classes if a namespace is selected in the tree, and the properties, events and methods (instance and static) in the case of a class.&lt;/p&gt;

&lt;p&gt;For each case, we’ll use a different template: “namespaceTemplate” for namespaces, and “classTemplate” for classes,&amp;#160; but we’ll do so from the same DataView. This dynamic template switching is done by handling the onItemRendering event of the DataView:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onDetailsRendering(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = args.get_dataItem();
    args.set_itemTemplate(Type.isNamespace(dataItem) ?
        &lt;span style="color: maroon"&gt;&amp;quot;namespaceTemplate&amp;quot;&lt;/span&gt; : &lt;span style="color: maroon"&gt;&amp;quot;classTemplate&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This code gets the data item from the event arguments and sets the itemTemplate property depending on its type.&lt;/p&gt;

&lt;p&gt;Each of these two templates will have to display the contents of the selected object. But, and that will be the tricky part, we want all those to be neatly grouped into separated lists.&lt;/p&gt;

&lt;p&gt;One way to do that would be to have one DataView per list but where would the fun be in that? Here, we are going to enumerate only once through the data items to display and dispatch them dynamically to this or that placeholder depending on their nature.&lt;/p&gt;

&lt;p&gt;Once more, the key to doing that will be handling the onItemRendering event:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onNamespaceChildRendering(sender, args) {
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Type.isClass(args.get_dataItem())) {
        args.set_itemPlaceholder(&lt;span style="color: maroon"&gt;&amp;quot;classPlaceHolder&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This code is simply changing the rendering place holder for the curent item from the default (the DataView’s element) to “classPlaceHolder” if the current data item is a class (instead of a namespace). The template itself looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{{ $dataItem.getName() }}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;column&amp;quot;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Namespaces:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespacePlaceHolder&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ getChildren($dataItem) }}&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceChildTemplate&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;onitemrendering&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;br /&gt;           &amp;quot;{{ onNamespaceChildRendering }}&amp;quot;&amp;gt;
     &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;column&amp;quot;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Classes:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;classPlaceHolder&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceChildTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{{ $dataItem.getName() }}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see, there really is only one DataView in there, and thanks to the code above, it can dispatch its rendering to different places if necessary. The template for the items of that DataView happens to be the same in all cases (namespaceChildTemplate) but it could be easily different, as it was for the parent details view.&lt;/p&gt;

&lt;p&gt;The template for displaying classes is essentially the same thing, but with four placeholders instead of two.&lt;/p&gt;

&lt;p&gt;So here’s what it looks like in the end:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/ClassBrowser_5CC62533.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Class Browser" border="0" alt="Class Browser" src="http://weblogs.asp.net/blogs/bleroy/ClassBrowser_thumb_70730EC7.png" width="504" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt; of this post are that it’s now super-easy to render hierarchical data structures with DataView, and that you can do some interesting grouping of data on the fly by handling the item rendering event.&lt;/p&gt;

&lt;p&gt;You can play with the class browser live here:
  &lt;br /&gt;&lt;a href="http://boudin.vndv.com/AjaxPreview5Tree/default.htm"&gt;http://boudin.vndv.com/AjaxPreview5Tree/default.htm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can download the code here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Ajax 4.0 Preview 5:
  &lt;br /&gt;&lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=32770"&gt;http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=32770&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jim and Dave’s posts on Preview 5:
  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/jimwang/archive/2009/09/11/asp-net-ajax-preview-5-and-updatepanel.aspx"&gt;http://weblogs.asp.net/jimwang/archive/2009/09/11/asp-net-ajax-preview-5-and-updatepanel.aspx&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/infinitiesloop/archive/2009/09/10/microsoft-ajax-4-preview-5-the-dataview-control.aspx"&gt;http://weblogs.asp.net/infinitiesloop/archive/2009/09/10/microsoft-ajax-4-preview-5-the-dataview-control.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7204694" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Tell me what smells in WebForms as a view engine</title><link>http://weblogs.asp.net/bleroy/archive/2009/07/13/tell-me-what-smells-in-webforms-as-a-view-engine.aspx</link><pubDate>Mon, 13 Jul 2009 17:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7146686</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>27</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7146686</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/07/13/tell-me-what-smells-in-webforms-as-a-view-engine.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 20px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="Fisherman&amp;#39;s Friend" border="0" alt="Fisherman&amp;#39;s Friend" align="left" src="http://weblogs.asp.net/blogs/bleroy/FishermansFriend_29543AA9.jpg" width="192" height="136" /&gt; Don’t read too much into this, but I’d love to read your feedback on this. I’m compiling a list of stuff that smells in WebForms when used as a view engine in MVC.&lt;/p&gt;  &lt;p&gt;Along the lines of:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Noisy page directives that are useless for MVC&lt;/li&gt;    &lt;li&gt;runat=server&lt;/li&gt;    &lt;li&gt;Page lifecycle&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For once, you can let the inside troll take over :)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7146686" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Mandelbrot set in a twitcode</title><link>http://weblogs.asp.net/bleroy/archive/2009/07/10/mandelbrot-set-in-a-twitcode.aspx</link><pubDate>Sat, 11 Jul 2009 00:50:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7145174</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7145174</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/07/10/mandelbrot-set-in-a-twitcode.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://twitter.com/KiniK"&gt;Kinik&lt;/a&gt; just published &lt;a href="http://twitter.com/KiniK/statuses/2575582146"&gt;a pretty amazing #twitcode version&lt;/a&gt; of a &lt;a href="http://en.wikipedia.org/wiki/Mandelbrot_set"&gt;Mandelbrot set&lt;/a&gt; visualization in JavaScript that &lt;a href="http://blog.nihilogic.dk/2008/09/mandelbrot-in-less-than-128-bytes-of.html"&gt;Jacob Seidelin&lt;/a&gt; wrote.&lt;/p&gt;  &lt;p&gt;Here’s the code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(k=84;k-=1/32;document.write(k%3?i%8:&lt;span style="color: #a31515"&gt;'&amp;lt;br/&amp;gt;'&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(x=y=0,i=99;--i/y;x=t)t=x*x-y*y+1-k%3,y=1-k/42+y*x*2&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And here’s what it renders:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/Mandelbrot_23D68E9F.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Mandelbrot" border="0" alt="Mandelbrot" src="http://weblogs.asp.net/blogs/bleroy/Mandelbrot_thumb_286C9959.png" width="504" height="368" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/KiniK/statuses/2575582146"&gt;http://twitter.com/KiniK/statuses/2575582146&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7145174" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/TwitCode/default.aspx">TwitCode</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Twitter/default.aspx">Twitter</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>A (less) simple include for ASP.NET</title><link>http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx</link><pubDate>Fri, 10 Jul 2009 22:57:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7145123</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7145123</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2003 Bertrand Le Roy" border="0" alt="(c) 2003 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/DSCN2140_787CAEA3.jpg" width="184" height="244" /&gt; In &lt;a href="http://weblogs.asp.net/bleroy/archive/2009/07/09/a-simple-include-for-asp-net.aspx"&gt;yesterday’s post&lt;/a&gt;, I published the code for a simple include method for ASP.NET that I’ve been using in a couple of places, only to realize that it was fine for what I was doing but probably not very useful beyond that.&lt;/p&gt;  &lt;p&gt;So I spent some time today broadening its scope. It now supports nested includes (I modified the original post to reflect that change) and also setting properties on the control.&lt;/p&gt;  &lt;p&gt;You can still do plain includes:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Include(&lt;span style="color: #a31515"&gt;&amp;quot;contents.ascx&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;But now you can also set properties on the included user control using an anonymous object:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Include(&lt;span style="color: #a31515"&gt;&amp;quot;contents.ascx&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{number=2, what=&lt;span style="color: #a31515"&gt;&amp;quot;A&amp;quot;&lt;/span&gt;}); &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The code for the helper considerably grew along the way but it’s still reasonable:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Linq;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Reflection;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI;

&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IncludeHelper &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;Include(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TemplateControl &lt;/span&gt;host,&lt;br /&gt;                               &lt;span style="color: blue"&gt;string &lt;/span&gt;virtualPath) {
        Include(host, virtualPath, &lt;span style="color: blue"&gt;null&lt;/span&gt;);
    }

    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;Include(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TemplateControl &lt;/span&gt;host,&lt;br /&gt;                               &lt;span style="color: blue"&gt;string &lt;/span&gt;virtualPath,&lt;br /&gt;                               &lt;span style="color: blue"&gt;object &lt;/span&gt;properties) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;resolvedPath = host.ResolveUrl(virtualPath);
        &lt;span style="color: blue"&gt;var &lt;/span&gt;include = host.LoadControl(resolvedPath);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(properties != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;includeType = include.GetType();
            &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;fieldInfo &lt;span style="color: blue"&gt;in&lt;br /&gt;                         &lt;/span&gt;properties.GetType().GetProperties()) {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;targetInfo = includeType.GetMember(&lt;br /&gt;                    fieldInfo.Name,
                    &lt;span style="color: #2b91af"&gt;MemberTypes&lt;/span&gt;.Field |&lt;br /&gt;                    &lt;span style="color: #2b91af"&gt;MemberTypes&lt;/span&gt;.Property,
                    &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.IgnoreCase |&lt;br /&gt;                    &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.Instance |&lt;br /&gt;                    &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.Public)
                    .FirstOrDefault();
                &lt;span style="color: blue"&gt;var &lt;/span&gt;targetPropertyInfo = targetInfo &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyInfo&lt;/span&gt;;
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(targetPropertyInfo != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
                    targetPropertyInfo.SetValue(&lt;br /&gt;                        include,&lt;br /&gt;                        fieldInfo.GetValue(properties, &lt;span style="color: blue"&gt;null&lt;/span&gt;),&lt;br /&gt;                        &lt;span style="color: blue"&gt;null&lt;/span&gt;);
                }
                &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;targetFieldInfo = targetInfo &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FieldInfo&lt;/span&gt;;
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(targetFieldInfo != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
                        targetFieldInfo.SetValue(&lt;br /&gt;                            include,&lt;br /&gt;                            fieldInfo.GetValue(properties, &lt;span style="color: blue"&gt;null&lt;/span&gt;));
                    }
                    &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(
                            &lt;span style="color: #a31515"&gt;&amp;quot;There is no property of field with &amp;quot; +&lt;br /&gt;                            &amp;quot;that name on the target control.&amp;quot;&lt;/span&gt;,
                            fieldInfo.Name);
                    }
                }
            }
        }
        &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;writer =&lt;br /&gt;                   &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HtmlTextWriter&lt;/span&gt;(host.Page.Response.Output)) {
            include.RenderControl(writer);
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I hope this helps. Again, if you are OK with the regular syntax to include a user controls, you probably shouldn’t use this and stick to what you know. I built this because I’m not entirely satisfied with that syntax and because I have a clear use case where it makes more sense. Make your own opinion and follow it :)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; The control is still not going into the control tree, which breaks lots of stuff. I don't really care that much about it but it may be important to you so I thought I'd point it out.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7145123" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>A simple include for ASP.NET</title><link>http://weblogs.asp.net/bleroy/archive/2009/07/09/a-simple-include-for-asp-net.aspx</link><pubDate>Thu, 09 Jul 2009 23:30:55 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7144049</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7144049</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/07/09/a-simple-include-for-asp-net.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) 2005 Bertrand Le Roy" border="0" alt="(c) 2005 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/IMG_03402_64755BBB.jpg" width="164" height="244" /&gt; In &lt;a href="http://weblogs.asp.net/bleroy/archive/2009/07/08/are-master-pages-too-complex.aspx"&gt;yesterday’s post&lt;/a&gt;, I alluded to a simple include extension method that I like to use when I don’t care about designer support. In a comment, Andrew asked if I could share the code for it, so here it is.&lt;/p&gt;  &lt;p&gt;I never liked the regular way of including user controls in WebForms and how they require a registration &lt;strong&gt;and&lt;/strong&gt; a declaration, both of which are more verbose than they need to be. A plain #include would work but is a little outdated (and if I’m not mistaken it’s not even available by default in IIS7).&lt;/p&gt;  &lt;p&gt;My Include method is quite similar to MVC’s RenderPartial except that it doesn’t deal with view data. It’s a plain and simple include. Just give it the relative path to a user control:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Include(&lt;span style="color: #a31515"&gt;&amp;quot;Header.ascx&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Here’s the code for that extension method:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI;

&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IncludeHelper &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;Include(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TemplateControl &lt;/span&gt;host,&lt;br /&gt;                               &lt;span style="color: blue"&gt;string &lt;/span&gt;virtualPath) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;resolvedPath = host.ResolveUrl(virtualPath);
        &lt;span style="color: blue"&gt;var &lt;/span&gt;include = host.LoadControl(resolvedPath);
        &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;writer =&lt;br /&gt;                   &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HtmlTextWriter&lt;/span&gt;(host.Page.Response.Output)) {
            include.RenderControl(writer);
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;It just resolves the path, loads the control and renders it in place.&lt;/p&gt;

&lt;p&gt;To use that method, just drop the code as a cs file into App_code if you’re using a web site, or just add it to your project otherwise.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx"&gt;I played with the idea of enabling an anonymous object parameter to set properties on the user control&lt;/a&gt;, but I guess if you’re going to do that, the benefits of the helper get dimmer and going with the regular WebForms user control registration and tags is probably just easier (you’ll get IntelliSense on the properties for example).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer/update: &lt;/strong&gt;No, this does not run the control through the page lifecycle (although it could by adding it to the page’s control tree and removing it after rendering it). No, if you use master pages you probably don’t need it. No, you can’t set properties.&lt;/p&gt;

&lt;p&gt;This is just the simplest include I could build, and it does only that: including contents. If it seems useless to you, it probably is. I published it mainly because I was asked to. :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I wrote a more complex version that can set properties on the included controls:

  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7144049" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Are Master Pages too complex?</title><link>http://weblogs.asp.net/bleroy/archive/2009/07/08/are-master-pages-too-complex.aspx</link><pubDate>Wed, 08 Jul 2009 23:38:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7143759</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7143759</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/07/08/are-master-pages-too-complex.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="MasterLock" border="0" alt="MasterLock" align="left" src="http://weblogs.asp.net/blogs/bleroy/MasterLock_thumb_07ECEFF7.jpg" width="198" height="210" /&gt;Master Pages are a wonderful concept that as developers we highly value. It’s the sort of pattern that just looks like the right thing to do (to our twisted, concept hungry developer minds) and that even makes you wonder why we haven’t done it that way since the beginning of time (&lt;a href="http://en.wikipedia.org/wiki/World_Wide_Web"&gt;1990&lt;/a&gt;). For the record, master pages were invented by &lt;a href="http://blogs.msdn.com/davidebb/default.aspx"&gt;David Ebbo&lt;/a&gt;, who is behind a lot of the smartest things in ASP.NET.&lt;/p&gt;  &lt;p&gt;Just in case you have no idea, what are Master Pages? Before master pages, sharing layout between pages was done using includes (or user controls). For example, your typical hello world page might have looked like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Register &lt;/span&gt;&lt;span style="color: red"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;include&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;TagName&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;header&amp;quot;&lt;br /&gt;             &lt;/span&gt;&lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/HelloHeader.ascx&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Register &lt;/span&gt;&lt;span style="color: red"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;include&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;TagName&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;footer&amp;quot;&lt;br /&gt;             &lt;/span&gt;&lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/HelloFooter.ascx&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello world with includes&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;include&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;header &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; /&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;Hello world!
&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;include&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;footer &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice that the page does contain markup that is not specific to the page (boilerplate markup mainly that you could put into includes as well, but only at the cost of breaking beginnings and ends of semantic blocks into separate includes).&lt;/p&gt;

&lt;p&gt;As a side note, I’ve always thought the user control syntax above was overly verbose when all you want is a plain include. It has the one advantage of enabling the Visual Studio designer but having a separate registration and declaration seems overkill. The #include directive still exists but I personally prefer to use a simple helper extension method to Page that brings the code down to this (MVC gives you Html.RenderPartial, which is roughly equivalent):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello world with includes&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;meta &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;keywords&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hello world&amp;quot; /&amp;gt;&lt;/span&gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Include(&lt;span style="color: #a31515"&gt;&amp;quot;HelloHeader.ascx&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;    Hello world!&lt;br /&gt;    &lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Include(&lt;span style="color: #a31515"&gt;&amp;quot;HelloFooter.ascx&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;With master pages, you can get rid of all common markup and really limit what you put into the page to just what varies from page to page. for example, the above hello world page might be written like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/MasterPage.master&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Hello world!&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;

&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Content &lt;/span&gt;&lt;span style="color: red"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;head&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Server&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;meta &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;keywords&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hello world&amp;quot; /&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Content &lt;/span&gt;&lt;span style="color: red"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Server&amp;quot;&amp;gt;
    &lt;/span&gt;Hello from the content page!
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;That is clean, but pretty puzzling the first time you see it. To understand where the markup comes from, you need to track that @Page directive and understand that you need to look into the corresponding master page file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Master &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Master page&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ContentPlaceHolder &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;head&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ContentPlaceHolder&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Hello from a master page&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ContentPlaceHolder &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ContentPlaceHolder&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;Footer says hi.
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You need to understand that those content place holder ids correspond to other controls that are in the master page and that the framework will make the match.&lt;/p&gt;

&lt;p&gt;Master pages also come with the price of mangled ids, but that’s an implementation detail (one could imagine an implementation that wouldn’t suffer from that problem). The price we pay for master pages also comes in the form of a weird control tree: master pages are really implemented as user controls that get included by the page, a concept that is the &lt;em&gt;inverse&lt;/em&gt; of the model they seem to promote; in other words, the implementation is the reverse of the concept, in a way. There are also complications about putting contents in the head section (head must be runat=server, script tags are tricky, setting the title, etc.).&lt;/p&gt;

&lt;p&gt;So are master pages worth the price? It depends on who your audience is and on how your pages are built.&lt;/p&gt;

&lt;p&gt;By audience, I mean the person who is going to write the views. If it’s just you and you are a developer, they might actually be a pretty solid choice. But if external designers are going to build the views, maybe you need to pause and try not to think as a developer for a moment.&lt;/p&gt;

&lt;p&gt;The main problem with the include approach (and the reason why master pages were invented) is that the outer markup for the page needs to be on all pages. So if you decide to change that markup, you need to do so on all pages.&lt;/p&gt;

&lt;p&gt;But in more and more applications, in particular CMS, this problem becomes moot. If your application decouples the content from the view code, and if the layout or view to use for a given content can be determined at runtime by a themeing engine, you might end-up with templates that look like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Title &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.RenderZone(&lt;span style="color: #a31515"&gt;&amp;quot;Header&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;    &lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.RenderZone(&lt;span style="color: #a31515"&gt;&amp;quot;Contents&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;    &lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.RenderZone(&lt;span style="color: #a31515"&gt;&amp;quot;Footer&amp;quot;&lt;/span&gt;); &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This is actually no different in concept from master pages (there are place holders in generic markup and no specific contents) but the contents do not come from a content page. Instead, they are dynamically inserted by the application.&lt;/p&gt;

&lt;p&gt;The template file then becomes no more than layout. It is easy to understand and easier to assign a different layout to any given contents.&lt;/p&gt;

&lt;p&gt;So in general there is no perfect answer on whether you should use master pages or not, but if you are able, in your application, to decouple page layout from contents, there is an opportunity to have clean and easy to understand markup that also maximizes re-use.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7143759" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CMS/default.aspx">CMS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Why is ASP.NET encoding &amp;’s in script URLs? A tale of looking at entirely the wrong place for a cause to a non-existing bug.</title><link>http://weblogs.asp.net/bleroy/archive/2009/06/05/why-is-asp-net-encoding-amp-s-in-script-urls-a-tale-of-looking-at-entirely-the-wrong-place-for-a-cause-to-a-non-existing-bug.aspx</link><pubDate>Sat, 06 Jun 2009 00:27:15 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7109236</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7109236</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/06/05/why-is-asp-net-encoding-amp-s-in-script-urls-a-tale-of-looking-at-entirely-the-wrong-place-for-a-cause-to-a-non-existing-bug.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/Bug_50FD5922.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) Bertrand Le Roy 2003" border="0" alt="(c) Bertrand Le Roy 2003" align="left" src="http://weblogs.asp.net/blogs/bleroy/Bug_thumb_774F16A0.jpg" width="254" height="184" /&gt;&lt;/a&gt; Several people have &lt;a href="http://ajaxcontroltoolkit.codeplex.com/WorkItem/View.aspx?WorkItemId=13134"&gt;reported&lt;/a&gt; seeing errors in their logs that seem to be due to requests such as this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;/ScriptResource.axd?d=     &lt;br /&gt;[lots of junk]&lt;strong&gt;&amp;amp;amp;       &lt;br /&gt;&lt;/strong&gt;t=ffffffffee24147c&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The important part here is the HTML-encoded “&amp;amp;amp;” sequence, which stands for “&amp;amp;” of course. &lt;em&gt;If&lt;/em&gt; this exact URL is sent to the server, the server won’t know what to do with the escape sequence (URLs are not supposed to be HTML-encoded on the wire) so the parameters won’t get separated as expected, potentially resulting in a server error. This bug in the toolkit is an example of that: &lt;a href="http://ajaxcontroltoolkit.codeplex.com/WorkItem/View.aspx?WorkItemId=13134"&gt;http://ajaxcontroltoolkit.codeplex.com/WorkItem/View.aspx?WorkItemId=13134&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Of course, when people see 500 errors popping up in their server logs, they immediately assume the application is failing for some users. Or that some idiot at Microsoft did something incredibly stupid (that’s what we idiots at Microsoft do after all).&lt;/p&gt;  &lt;p&gt;Case in point, a quick peek into the source code of the application’s pages immediately reveals that the script tags generated by ScriptManager do indeed generate these URLs:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;script src=&amp;quot;/ScriptResource.axd?d=[lots of junk]&amp;amp;amp;t=ffffffff8824ac28&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;So that’s where it came from! See? &lt;strong&gt;When I copy this URL into the browser’s URL bar, I do get the same error!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Then ensue various more or less rational reactions such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Correlate the user agent to the faulty requests (which correlates more or less with normal browser usage, i.e. lots of IE and then lots of Firefox, when there is a large enough sample).&lt;/li&gt;    &lt;li&gt;Blame IE6 (lots of these requests come from IE6, hence it must be responsible: IE6 sucks).&lt;/li&gt;    &lt;li&gt;“Fix” ScriptManager and remove the HTML encoding.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Well, by copying the URL from the source view into the URL bar, you did indeed reproduce the problem. A little too well. Better than you realize.&lt;/p&gt;  &lt;p&gt;This is why. &lt;strong&gt;All of the errors in your server logs come from people doing precisely what you just did&lt;/strong&gt;: copy the URL from the source view into the browser’s URL bar. They do it for various reasons: look at the source code for the scripts, understand what these weird URLs are, who knows?&lt;/p&gt;  &lt;p&gt;But the point is, you will never be able to reproduce these errors during normal use of the application. There is nothing to fix here. The value that gets sent to the server never has the “&amp;amp;amp;” sequence. You can verify it in IE6, you can verify it in any browser on any OS, it will just work.&lt;/p&gt;  &lt;p&gt;When putting a URL in an HTML attribute, you should &lt;strong&gt;*always*&lt;/strong&gt; HTML-encode it. It’s the standard, and for good reason (it enables the browser to tell between “&amp;amp;”, “&amp;amp;amp;” and “&amp;amp;amp;amp;”, it enables quotes to be embedded into attributes, etc.).&lt;/p&gt;  &lt;p&gt;A consequence of that is that if you’re going to copy the value of one of these attributes from the source view, you should do what the browser does when parsing the HTML: decode the value first (in other words, replace “&amp;amp;amp;” with “&amp;amp;”).&lt;/p&gt;  &lt;p&gt;So yes, people do fail to do that and copy the URL without decoding. Well, they are not supposed to do that, nor do they need to do it. The error is normal, it results from a bad URL having been entered manually. Nobody would be surprised to get an error when querying foo.aspx?somenumber=thisisnotanumber for example. Same thing here. Pretty much.&lt;/p&gt;  &lt;p&gt;Of course, this is not entirely trivial to figure out and I did pull my remaining hair a bit trying to understand what was going on, and you tend to trust people when they tell you there is a problem, especially when the description seems to make sense. There is some sort of confirmation bias going on there. But the more I looked at the different pieces of evidence, the more this explanation looked like the most likely, by far.&lt;/p&gt;  &lt;p&gt;But of course, I may be missing something…&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7109236" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/Ajax+Control+Toolkit/default.aspx">Ajax Control Toolkit</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category></item><item><title>New release of the Ajax Control Toolkit</title><link>http://weblogs.asp.net/bleroy/archive/2009/05/13/new-release-of-the-ajax-control-toolkit.aspx</link><pubDate>Thu, 14 May 2009 05:19:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7086151</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>50</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7086151</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/05/13/new-release-of-the-ajax-control-toolkit.aspx#comments</comments><description>&lt;p&gt;A &lt;a href="http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27326"&gt;new version of the AJAX Control Toolkit&lt;/a&gt; is now available for download from the CodePlex website. It contains three new controls:&lt;/p&gt;  &lt;p style="clear: both"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="HtmlEditor" border="0" alt="HtmlEditor" align="left" src="http://weblogs.asp.net/blogs/bleroy/HtmlEditor_1E6A1BAC.png" width="244" height="159" /&gt; &lt;strong&gt;&lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HTMLEditor/HTMLEditor.aspx"&gt;HTMLEditor&lt;/a&gt;&lt;/strong&gt; - allows you to easily create and edit HTML content. You can edit in WYSIWYG mode or in HTML source mode. The control exists as a server-side extender but can also be instantiated purely on the client-side with a single line of code. Many thanks to &lt;a href="http://www.obout.com"&gt;Obout&lt;/a&gt; for building this.&lt;/p&gt;  &lt;p style="clear: both"&gt;&lt;br/&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px; display: inline; border-top: 0px; border-right: 0px" title="ComboBox" border="0" alt="ComboBox" align="right" src="http://weblogs.asp.net/blogs/bleroy/ComboBox_0834005A.png" width="162" height="244" /&gt; &lt;strong&gt;&lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/ComboBox/ComboBox.aspx"&gt;ComboBox&lt;/a&gt;&lt;/strong&gt; - provides a DropDownList of items, combined with TextBox. Different modes determine the interplay between the text entry and the list of items. this control behaves very much like a Windows combo. Many thanks to Dan Ludwig for building this.&lt;/p&gt;  &lt;p style="clear: both"&gt;&lt;br/&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ColorPicker" border="0" alt="ColorPicker" align="left" src="http://weblogs.asp.net/blogs/bleroy/ColorPicker_23002666.png" width="238" height="189" /&gt; &lt;strong&gt;&lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/ColorPicker/ColorPicker.aspx"&gt;ColorPicker&lt;/a&gt;&lt;/strong&gt; - can be attached to any ASP.NET TextBox control to provide client-side color-picking functionality from a popup. Many thanks to Alexander Turlov for building this.&lt;/p&gt;  &lt;p style="clear: both"&gt;&lt;br/&gt;The ASP.NET website has been updated with new &lt;a href="http://www.asp.net/learn/ajax-videos"&gt;videos&lt;/a&gt; and &lt;a href="http://www.asp.net/learn/ajax"&gt;tutorials&lt;/a&gt; for these controls.&lt;/p&gt;  &lt;p&gt;This new release also includes fixes for over 20 of the most voted bugs in existing AJAX Control Toolkit controls and now features minimized release versions of the script files.&lt;/p&gt;  &lt;p&gt;The release can be downloaded as a server dll or as a set of files for use with pure client-side applications.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27326"&gt;http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27326&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7086151" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Ajax+Control+Toolkit/default.aspx">Ajax Control Toolkit</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Glimmer: visually build jQuery animations and stuff</title><link>http://weblogs.asp.net/bleroy/archive/2009/04/28/glimmer-visually-build-jquery-animations-and-stuff.aspx</link><pubDate>Tue, 28 Apr 2009 18:35:29 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7063913</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7063913</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/04/28/glimmer-visually-build-jquery-animations-and-stuff.aspx#comments</comments><description>&lt;p&gt;&lt;a title="Glimmer" href="http://visitmix.com/Articles/Glimmer-a-jQuery-Interactive-Design-Tool"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="glim4s" border="0" alt="glim4s" align="left" src="http://weblogs.asp.net/blogs/bleroy/glim4s_380D1EFE.png" width="244" height="183" /&gt;&lt;/a&gt;If you’re still intimidated by jQuery or DOM manipulation in general, if you need to quickly build web animations, if you’re more a designer guy, if you think tooling makes sense, or a combination of the above, you should probably check out &lt;a href="http://visitmix.com/Articles/Glimmer-a-jQuery-Interactive-Design-Tool"&gt;Glimmer&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;In a nutshell, &lt;a href="http://visitmix.com/Articles/Glimmer-a-jQuery-Interactive-Design-Tool"&gt;Glimmer&lt;/a&gt; is a visual tool that builds HTML animations, menus, tooltips on jQuery. It builds all the code you need (HTML, CSS and JavaScript with jQuery) at the click of a button.&lt;/p&gt;  &lt;p&gt;Check it out!   &lt;br /&gt;&lt;a href="http://visitmix.com/Articles/Glimmer-a-jQuery-Interactive-Design-Tool"&gt;http://visitmix.com/Articles/Glimmer-a-jQuery-Interactive-Design-Tool&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7063913" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>CSS isolation: there has got to be a better way</title><link>http://weblogs.asp.net/bleroy/archive/2009/04/14/css-isolation-there-has-got-to-be-a-better-way.aspx</link><pubDate>Tue, 14 Apr 2009 07:26:04 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7045774</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7045774</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/04/14/css-isolation-there-has-got-to-be-a-better-way.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) Bertrand Le Roy 2003" border="0" alt="(c) Bertrand Le Roy 2003" align="left" src="http://weblogs.asp.net/blogs/bleroy/spider_058EE49A.jpg" width="244" height="184" /&gt; CSS can be a tricky thing. I’m trying to do something that I think should be pretty simple. Let’s say a page contains a section (e.g. an admin panel) that must be styled independently from the rest of the page, but consistently and predictably. The DOM and CSS for the main part of the page is undetermined (e.g. because it’s part of a user-defined theme). Of course, you could use iframes, which are about the only isolation mechanism in HTML but we can’t do this here because iframes are quite rigid in shape (they are rectangles), they make scripting the DOM more difficult and they pretty much require an additional round-trip to the server to serve their contents.&lt;/p&gt;  &lt;p&gt;The real problem to solve here is that if the main CSS for the page defines very general styles that for example target all elements with a given tag name, and those styles are going to bleed into our specialized region unless we find a way to block that CSS from cascading down. Ideally, you’d have an attribute on the tag, something like inheritcss=”false”, but no such thing exists.&lt;/p&gt;  &lt;p&gt;So the only way I’ve found to solve this problem is to write a stylesheet that explicitly resets the defaults for all properties and all elements. Here is an excerpt from the CssIsolation.css file:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #a31515"&gt;.isolate *
&lt;/span&gt;{
    &lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;white none repeat scroll 0% 0%&lt;/span&gt;;
    &lt;span style="color: red"&gt;border&lt;/span&gt;: &lt;span style="color: blue"&gt;0px none black&lt;/span&gt;;
    &lt;span style="color: red"&gt;border-collapse&lt;/span&gt;: &lt;span style="color: blue"&gt;separate&lt;/span&gt;;
    &lt;span style="color: red"&gt;border-spacing&lt;/span&gt;: &lt;span style="color: blue"&gt;0px&lt;/span&gt;;&lt;br /&gt;[...]
    &lt;span style="color: red"&gt;z-index&lt;/span&gt;: &lt;span style="color: blue"&gt;auto&lt;/span&gt;;
}
&lt;span style="color: #a31515"&gt;.isolate p 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;display&lt;/span&gt;:&lt;span style="color: blue"&gt;block&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin-top&lt;/span&gt;: &lt;span style="color: blue"&gt;16px&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color: blue"&gt;16px&lt;/span&gt;;
}
&lt;span style="color: #a31515"&gt;.isolate strong&lt;/span&gt;, &lt;span style="color: #a31515"&gt;.isolate b 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;font-weight&lt;/span&gt;: &lt;span style="color: blue"&gt;bold&lt;/span&gt;;
}
&lt;span style="color: #a31515"&gt;.isolate h1
&lt;/span&gt;{
    &lt;span style="color: red"&gt;display&lt;/span&gt;: &lt;span style="color: blue"&gt;block&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-size&lt;/span&gt;: &lt;span style="color: blue"&gt;xx-large&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-weight&lt;/span&gt;: &lt;span style="color: blue"&gt;bold&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin-top&lt;/span&gt;: &lt;span style="color: blue"&gt;21px&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color: blue"&gt;21px&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This is lame for a number of reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Defaults might vary from browser to browser (this is particularly true of fonts and sizes).&lt;/li&gt;

  &lt;li&gt;Some styles can’t be reset to defaults, such as default button styles (at least, not without using browser-specific styles that aren’t consistently available):
    &lt;br /&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px; display: inline; border-top: 0px; border-right: 0px" title="Default button styles can&amp;#39;t be reproduced." border="0" alt="Default button styles can&amp;#39;t be reproduced." src="http://weblogs.asp.net/blogs/bleroy/DefaultButtonCSS_3086D29F.png" width="329" height="78" /&gt; &lt;/li&gt;

  &lt;li&gt;An exhaustive list of tags and style properties is sure to be wrong now or in the future (I did CSS 2, so it’s already outdated by CSS3).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still, imperfect as it is, this is a solution that works reasonably well and can be improved as problems are found. The equivalent of that inheritcss=”false” attribute, using my isolation stylesheet, is to set class=”isolate” on the parent element of the section of the page you want to isolate. None of the styles defined for the rest of the page (which is defined just as usual, with no difference whatsoever) should bleed then.&lt;/p&gt;

&lt;p&gt;Here a snapshot of my test page, where you can see, side-by-side, unstyled HTML and HTML with reset styles:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px 0px; display: inline; border-top: 0px; border-right: 0px" title="Comparison of contents, unstyled and with reset applied." border="0" alt="Comparison of contents, unstyled and with reset applied." src="http://weblogs.asp.net/blogs/bleroy/CssIsolationTest_7DB6CC2A.png" width="411" height="838" /&gt; &lt;/p&gt;

&lt;p&gt;Differences exist but are quite subtle.&lt;/p&gt;

&lt;p&gt;The HTML for an isolated section is defined like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;isolate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;isolated1&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;Isolated 1...
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If for example the main style sheet defines the style of lists like follows, this style won’t bleed into any element that has the isolate class (on the right on the next screenshot), just because we set the “isolate” class on the parent element.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #a31515"&gt;ul li 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;list-style-type&lt;/span&gt;: &lt;span style="color: blue"&gt;square&lt;/span&gt;;
}
&lt;span style="color: #a31515"&gt;ol li 
&lt;/span&gt;{
    &lt;span style="color: red"&gt;list-style-type&lt;/span&gt;: &lt;span style="color: blue"&gt;upper-roman&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px; display: inline; border-top: 0px; border-right: 0px" title="Main CSS doesn&amp;#39;t bleed into isolated section." border="0" alt="Main CSS doesn&amp;#39;t bleed into isolated section." src="http://weblogs.asp.net/blogs/bleroy/CssResetList_1F52F4FC.png" width="304" height="189" /&gt; &lt;/p&gt;

&lt;p&gt;You can then style each of these sections independently by just qualifying each of the style selectors with the ID of the parent element. In other words, just paste “#isolated1” in front of each selector of the local stylesheet, if the id of the parent element is “isolated1”:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #a31515"&gt;#isolated1 p
&lt;/span&gt;{
    &lt;span style="color: red"&gt;color&lt;/span&gt;: &lt;span style="color: blue"&gt;Green&lt;/span&gt;;
    &lt;span style="color: red"&gt;border&lt;/span&gt;: &lt;span style="color: blue"&gt;solid 1px black&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This style will override the isolation CSS because it is qualified by id, which always wins over styles that are only qualified by class:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px; display: inline; border-top: 0px; border-right: 0px" title="Local isolated CSS" border="0" alt="Local isolated CSS" src="http://weblogs.asp.net/blogs/bleroy/LocalIsolatedCSS_057EBECD.png" width="307" height="37" /&gt; &lt;/p&gt;

&lt;p&gt;I really wish one of you will tell me how stupid I am for not knowing about feature/hack X that is way simpler and gets you to the same place… There has &lt;strong&gt;got&lt;/strong&gt; to be a better way.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The code for the isolation stylesheet, as well as the test pages, can be found here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/CssIsolation.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/CssIsolation.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/CssIsolation.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7045774" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item></channel></rss>