<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Encosia &#187; jQuery</title>
	<atom:link href="http://encosia.com/category/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://encosia.com</link>
	<description>ASP.NET and AJAX code, ideas, and examples.</description>
	<lastBuildDate>Sun, 29 Jan 2012 01:06:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Adding your own callbacks to existing JavaScript functions</title>
		<link>http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/</link>
		<comments>http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 20:08:31 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1242</guid>
		<description><![CDATA[Hey Dave, is there a way to create an event handler so when .tmpl() is done it will fire a function? I&#8217;m trying to make it global, so I was hoping I could say, when ANY template gets done, do this&#8230; The question of how to retroactively add hooks before and/or after a pre-existing JavaScript [...]
Related posts:<ol>
<li><a href='http://encosia.com/how-to-easily-enhance-your-existing-tables-with-simple-css/' rel='bookmark' title='How to easily enhance your existing tables with simple CSS'>How to easily enhance your existing tables with simple CSS</a></li>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/composition-with-jquery-templates-why-and-how/' rel='bookmark' title='Composition with jQuery Templates: Why and How'>Composition with jQuery Templates: Why and How</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<blockquote><p>Hey Dave, is there a way to create an event handler so when .tmpl() is done it will fire a function? I&#8217;m trying to make it global, so I was hoping I could say, when ANY template gets done, do this&#8230;</p></blockquote>
<p>The question of how to retroactively add hooks before and/or after a pre-existing JavaScript function executes is one that comes up from time to time. Whether it&#8217;s a simple method like <code>tmpl()</code>, a server-generated script artifact, or a function in a third-party script, <strong>sometimes it&#8217;s desirable to alter a JavaScript function without access to change the original declaration of the function</strong>.</p>
<p>One of the handy things about JavaScript is that you can combine its functional and dynamic aspects to make surprisingly quick work of tasks like this one. Doing so is fairly straightforward, but it involves an approach you might not consider if you&#8217;re more familiar with languages that lack JavaScript&#8217;s unique features.</p>
<p>In this post, I&#8217;ll briefly cover a few examples of how to &#8220;patch&#8221; existing JavaScript functions with callbacks. We&#8217;ll begin with simple examples, then address an issue that stems from applying this approach to jQuery plugins, and finish with a more elegant way to handle the problem of patching functions that accept parameters.</p>
<h3>A simple() example</h3>
<p>Let&#8217;s start with the simplest possible example, a function that accepts no arguments and returns nothing:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> simple<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// I am a black box.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Maybe that function is pre-defined and emitted by server-side code. Maybe it&#8217;s part of a script you&#8217;re referencing from a public CDN. For whatever reason, assume that this function is part of your page, but that you don&#8217;t have the ability to directly change its code.</p>
<p>If you need to run some of your own code before and/or after any time the <code>simple()</code> function is called, you can use a technique called <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey patching</a> to achieve that without access to the original function declaration.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Get a reference to the previously defined simple() function.</span>
<span style="color: #003366; font-weight: bold;">var</span> oldSimple <span style="color: #339933;">=</span> simple<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> simple<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Code that runs before any call to simple() here.</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Make a call to the old/previous simple() function.</span>
  oldSimple<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Code that runs after any call to simple() here.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Since functions are just like any other variable in JavaScript, it&#8217;s that simple.</p>
<p>Without touching the original <code>simple()</code> function declaration, this snippet has effectively redefined it anyway. Calls to the original function will also execute our before and after code now, unaware that anything has changed.</p>
<h3>Parameters and external &#8220;event&#8221; handlers</h3>
<p>If you want to apply this technique to a function that accepts parameters, you&#8217;ll also need to capture and relay those parameters.</p>
<p>Take this more complex function, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> complex<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> bar<span style="color: #339933;">,</span> baz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// An assortment of black boxes.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You could patch in a &#8220;before&#8221; event, parameters unimpeded, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldComplex <span style="color: #339933;">=</span> complex<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Capture the parameters that the original complex()</span>
<span style="color: #006600; font-style: italic;">//  function expects.</span>
<span style="color: #003366; font-weight: bold;">function</span> complex<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> bar<span style="color: #339933;">,</span> baz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Call onBeforeComplex() if it's defined when this runs, and</span>
  <span style="color: #006600; font-style: italic;">//  pass a copy of the parameters that complex() was called with.</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onBeforeComplex <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onBeforeComplex<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> bar<span style="color: #339933;">,</span> baz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Call the original function, parameters included.</span>
  oldComplex<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> bar<span style="color: #339933;">,</span> baz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Using a separate <code>onBeforeComplex()</code> function instead of inline code isn&#8217;t necessary, but I prefer that approach. Now, you can drop this code into a script include anywhere after <code>complex()</code> is defined and then declare the &#8220;handler&#8221; function anywhere on the page (or not at all).</p>
<p>Passing foo, bar, and baz to <code>onBeforeComplex()</code> is optional, of course, but it&#8217;s usually helpful to know something about what sort of call triggered the event.</p>
<h3>Applying this to jQuery plugins</h3>
<p>Now let&#8217;s apply this technique to the real-world problem of updating <code>tmpl()</code>. Doing that isn&#8217;t much more difficult than the previous example, but we do need to identify the method&#8217;s signature first so that we can apply the patch.</p>
<p>Digging into the last version of <a href="https://github.com/jquery/jquery-tmpl/blob/master/jquery.tmpl.js#L80" target="_blank">jQuery.tmpl.js on GitHub</a>, the function we&#8217;ll need to override can be found beginning on line 80:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2012/01/original-tmpl-function.png" rel="attachment"><img src="http://encosia.com/blog/wp-content/uploads/2012/01/original-tmpl-function-sm.png" style="border: 1px solid #ccc;" /></a></p>
<p>So, the function we&#8217;ll need to patch is <code>jQuery.fn.tmpl</code>. Given the previous examples, you might thing it would be as easy as this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldTmpl <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span><span style="color: #339933;">;</span>
&nbsp;
jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onBeforeTmpl <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onBeforeTmpl<span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  oldTmpl<span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Unfortunately, that will break <code>tmpl()</code></strong> (in two separate ways, no less).</p>
<h3>jQuery plugins make &#8220;this&#8221; more complicated</h3>
<p>Applying the monkey patching approach to functions that operate on and return <a href="http://docs.jquery.com/Types#jQuery" target="_blank">jQuery collection objects</a>, such as the <code>tmpl()</code> plugin that led to this post, requires extra consideration. The crux of jQuery&#8217;s fluent API is that chainable jQuery methods both operate upon and return an instance of the jQuery object.</p>
<p>Now that we&#8217;re interjecting an additional level of abstraction, we need to be sure to maintain the scope of <code>this</code> down into the original jQuery plugin method <em>and</em> preserve the original function&#8217;s return value. <strong>Otherwise, our intermediary function will break jQuery&#8217;s chaining.</strong></p>
<p>Using <a href="http://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply" target="_blank"><code>apply()</code></a> to call the original function allows us to control its <code>this</code> value:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldTmpl <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Note: the parameters don't need to be named the same as in the</span>
<span style="color: #006600; font-style: italic;">//  original. This could just as well be function(a, b, c).</span>
jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onBeforeTmpl <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onBeforeTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Make a call to the old tmpl() function, maintaining the value </span>
  <span style="color: #006600; font-style: italic;">//  of &quot;this&quot; and its expected function arguments.</span>
  <span style="color: #003366; font-weight: bold;">var</span> tmplResult <span style="color: #339933;">=</span> oldTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onAfterTmpl <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onAfterTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>data<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> parentItem<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Returning the result of tmpl() back so that it's actually </span>
  <span style="color: #006600; font-style: italic;">//  useful, but also to preserve jQuery's chaining.</span>
  <span style="color: #000066; font-weight: bold;">return</span> tmplResult<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>By capturing the return value of the original <code>tmpl()</code> function and returning that back to the original caller, chaining is preserved at that previous level. That&#8217;s particularly important in this specific example because that return value is the rendered template.</p>
<h3>Better argument handling</h3>
<p>If you&#8217;re like me, explicitly capturing and passing each individual function parameter doesn&#8217;t feel great. Not only is it extra work to determine how many parameters a method accepts, but our patched version of <code>tmpl()</code> would stop working correctly if the original were updated to begin accepting additional parameters.</p>
<p>We can improve this situation easily enough by taking advantage of JavaScript&#8217;s built-in way to capture all of the parameters that were passed to a function. Aptly named <a href="https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments" target="_blank"><code>arguments</code></a>, this so-called array-like object is perfect for eliminating the explicit plumbing code to pass parameters between the patched function and the original.</p>
<p>Even better, arguments will capture all the parameters passed into a function even if that function&#8217;s declaration doesn&#8217;t accept parameters at all. So, now there&#8217;s no need to worry about matching the original&#8217;s function signature:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldTmpl <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span><span style="color: #339933;">;</span>
&nbsp;
jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">tmpl</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onBeforeTmpl <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onBeforeTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> tmplResult <span style="color: #339933;">=</span> oldTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> onAfterTmpl <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
    onAfterTmpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> tmplResult<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Throw that code on a page, anywhere after the reference to jquery.tmpl.js, and then all existing usages of <code>tmpl()</code> will begin triggering the before and after &#8220;events&#8221;.</p>
<h3>Conclusion</h3>
<p>We took a circuitous route to get here, but I hope you agree that it was worthwhile to build the solution up step by step. Even if you don&#8217;t need to patch an event into <code>tmpl()</code>, you might be surprised how often this technique comes in handy once you&#8217;re keeping the possibility in mind.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/how-to-easily-enhance-your-existing-tables-with-simple-css/' rel='bookmark' title='How to easily enhance your existing tables with simple CSS'>How to easily enhance your existing tables with simple CSS</a></li>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/composition-with-jquery-templates-why-and-how/' rel='bookmark' title='Composition with jQuery Templates: Why and How'>Composition with jQuery Templates: Why and How</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/">Adding your own callbacks to existing JavaScript functions</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Using CORS to access ASP.NET services across domains</title>
		<link>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/</link>
		<comments>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 06:25:26 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1223</guid>
		<description><![CDATA[Work on client-side applications long enough and it&#8217;s just about inevitable that you&#8217;ll eventually want to make an AJAX request that breaches the browser&#8217;s XMLHttpRequest security restrictions. Limitations on cross-domain requests are great when they&#8217;re preventing malicious sites from malfeasing, but are a thorn in the side when they complicate your legitimate applications. Traditionally, direct [...]
Related posts:<ol>
<li><a href='http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/' rel='bookmark' title='Save yourself some typing when you call ASP.NET services'>Save yourself some typing when you call ASP.NET services</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/successful-cors-request.png" alt="Successfully completing a cross-domain request to an ASMX service using CORS" title="Successful CORS request" style="border: 1px solid #ccc;" /></p>
<p>Work on client-side applications long enough and it&#8217;s just about inevitable that you&#8217;ll eventually want to make an AJAX request that breaches the browser&#8217;s XMLHttpRequest security restrictions. Limitations on cross-domain requests are great when they&#8217;re preventing malicious sites from malfeasing, but are a thorn in the side when they complicate your legitimate applications.</p>
<p>Traditionally, direct communication across the same-origin boundary required using a rickety (though clever) workaround called JSONP. JSONP is a reasonable compromise if all you need to do is make blind requests to a third-party API like Twitter, but comes up short if you need to use any HTTP verb other than GET. Of course, that&#8217;s <a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx" target="_blank">a deal-breaking issue when you&#8217;re working with ASMX ScriptServices or ASPX page methods</a>.</p>
<p>Luckily, a relatively new feature has been making its way into browsers which provides a robust solution to the cross-domain AJAX problem: <strong>CORS</strong>.</p>
<p>In this post, I&#8217;m going to show you how to recognize exactly which requests are cross-origin, how to enable CORS for your ASP.NET site, and the extra configuration necessary when you&#8217;re working with ASP.NET&#8217;s JSON-enabled services.</p>
<p><em>Before we get started, I want to emphasize that this approach won’t work with any version of IE prior to IE10. If supporting older versions of IE is a requirement in your target environment, you’re stuck with something like JSONP or <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/" target="_blank">a server-side proxy</a>. This will work in any version of IE if Chrome Frame is installed and enabled by your site/server though.</em></p>
<h3>Understanding what constitutes a different “origin”</h3>
<p>When it comes to making cross-origin AJAX requests, it&#8217;s helpful to understand which requests actually are cross-origin. Of course, a request from a page served under one domain to a resource on an entirely different one definitely falls under the umbrella of cross-origin:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/failed-cors-request.png" width="490" style="border: 1px solid #ccc;" /></p>
<p>However, the common moniker for these requests, <em>cross-domain</em>, tends to be misleading. While a request from one domain to another is obviously cross-origin, browsers are much more picky than that.</p>
<p>For example, a request from <code>foo.domain.com</code> to <code>bar.domain.com</code> is just as much cross-origin request as one to <code>abc.com</code>. That’s not quite as intuitive as the traditional cross-domain scenario, but requires the same consideration.</p>
<p>A less obvious troublemaker is making a request from <code>localhost:8080</code> to <code>localhost:8081</code>, which XMLHttpRequest’s security restrictions will also deny you from making. That’s a particularly troublesome scenario for ASP.NET developers since Visual Studio is all too happy to help you spin up a separate services/API project almost transparently hosted at its own separate port.</p>
<p>The easiest way to determine whether a particular request will fall under the umbrella of cross origin resource sharing is to <strong>compare the portion of both addresses appearing before the first forward slash</strong>. Any difference before the first forward slash, including the port, protocol (HTTP vs. HTTPS), and sub-domain, will thwart a traditional XHR-based AJAX request.</p>
<h3>Enabling CORS for an ASP.NET site</h3>
<p>Though the conventional wisdom about cross-domain or cross-origin requests has long been JSONP or nothing, a solution called <a href="http://www.w3.org/TR/cors/" target="_blank">Cross-Origin Resource Sharing</a> has gained broad support in modern browsers over the past couple years. This standard defines a set of HTTP headers that a server can use to instruct browsers that it’s okay for certain XMLHttpRequest requests to that server to cross the same-origin boundary.</p>
<p>In the broadest case, enabling CORS for an ASP.NET site is simple. The <a href="http://enable-cors.org/" target="_blank">enable-cors.org</a> site has handy list of concise examples of how to configure a variety of servers for CORS, including IIS. For sites hosted on IIS7.0+ and Integrated Pipeline, enabling CORS is as simple as adding this to the site’s web.config:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Origin&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>That simple change gets you half way there. A regular GET request for an ASPX page&#8217;s HTML would work now, for example. Unfortunately, the Content-Type necessary for working with ASMX ScriptServices throws a new wrench in the works:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/almost-successful-cors-request.png" alt="A partially successful CORS request to an ASMX ScriptService" title="Almost successful CORS request" width="490" height="106" style="border: 1px solid #ccc;" /></p>
<p>As it turns out, requests to ASP.NET’s JSON-enabled endpoints require one last configuration step to allow the request to go through unimpeded.</p>
<h3>Access-Control-Allow-Headers</h3>
<p>Sending the <code>Access-Control-Allow-Origin</code> header allows basic cross-origin access, but calling ASP.NET services like ASMX ScriptServices, ASPX page methods, and WCF services with AspNetCompatibilityRequirements enabled <a href="http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/" target="_blank">requires jumping through a few more hoops</a>. Namely, sending a specific Content-Type header of <code>application/json</code>.</p>
<p>One of the security precautions that the CORS specification includes is that browsers must tightly control what&#8217;s sent along with these cross-origin requests. Among the items that must be explicitly allowed: any but the most basic HTTP headers, including <code>Content-Type</code>.</p>
<p>In order for CORS requests to specify their Content-Type, your site needs to respond with one additional CORS header: <code>Access-Control-Allow-Headers</code></p>
<p>That brings the web.config modifications necessary to this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Origin&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Headers&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And finally, it&#8217;s possible to use the same, familiar jQuery <code>$.ajax()</code> syntax to request our service from same- and cross-domain origins alike:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/successful-cors-request.png" alt="A successful CORS request to an ASMX service with jQuery" title="Successful CORS request" width="490" height="170" style="border: 1px solid #ccc;" /></p>
<h3>Conclusion</h3>
<p>Even as we&#8217;re teetering at the precipice of 2012, CORS is still a fairly new feature and lacks ubiquitous support. IE10 should support CORS as fully as Chrome and Firefox already do, but the XDomainRequest implementation in earlier versions of IE does not (to my knowledge) support <code>Access-Control-Allow-Headers</code>, which makes it all but useless in this scenario.</p>
<p>If you&#8217;re comfortable leaving the comfy confines of XMLHttpRequest and jQuery&#8217;s <code>$.ajax</code>, a more cross-browser friendly solution does exist: <a href="http://easyxdm.net/wp/" target="_blank">easyXDM</a>. I haven&#8217;t personally used easyXDM beyond a bit of experimentation, but the approach it takes in older browsers is one that has been proven to be solid by similar libraries like <a href="http://socket.io/" target="_blank">Socket.IO</a>.</p>
<p>However, if you&#8217;re working in an environment where you can mandate Chrome (or Chrome Frame in IE9-) and/or Firefox as the browser of choice, CORS is an invaluable addition to your bag of tricks (I feel like I&#8217;ve typed that phrase in another post recently&#8230;). I hope this post will help you get your feet wet with this new technology which seems to get more lip service than actual usage.</p>
<h3>Get the source</h3>
<p>If you’d like to browse through a complete working example of what’s been covered in this post, take a look at the companion project at GitHub. Or, if you’d like to download the entire project and run it in Visual Studio to see it in action yourself, grab the ZIP archive.</p>
<p><a href="https://github.com/Encosia/Encosia-Samples-ASMX-CORS/tree/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: left; text-align: center;">Browse on GitHub</a><a href="https://github.com/Encosia/Encosia-Samples-ASMX-CORS/zipball/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: right; text-align: center;">Download the ZIP</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/' rel='bookmark' title='Save yourself some typing when you call ASP.NET services'>Save yourself some typing when you call ASP.NET services</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/using-cors-to-access-asp-net-services-across-domains/">Using CORS to access ASP.NET services across domains</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/using-cors-to-access-asp-net-services-across-domains/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Help me organize my posts about using jQuery with ASP.NET</title>
		<link>http://encosia.com/help-me-organize-my-posts-about-using-jquery-with-asp-net/</link>
		<comments>http://encosia.com/help-me-organize-my-posts-about-using-jquery-with-asp-net/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 19:12:22 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1219</guid>
		<description><![CDATA[One of the longest running themes here has been the compelling intersection between ASP.NET and jQuery. Beginning with my post about using jQuery to circumvent ASP.NET AJAX&#8217;s client-side apparatus for calling ASMX services, I&#8217;ve been writing about using ASP.NET and jQuery since the Spring of 2008. As these related posts have accumulated over the years, [...]
Related posts:<ol>
<li><a href='http://encosia.com/best-of-2008-5-most-popular-posts/' rel='bookmark' title='Best of 2008: 5 most popular posts'>Best of 2008: 5 most popular posts</a></li>
<li><a href='http://encosia.com/best-of-2007-5-most-popular-posts-and-contest-winners/' rel='bookmark' title='Best of 2007: 5 most popular posts (and contest winners)'>Best of 2007: 5 most popular posts (and contest winners)</a></li>
<li><a href='http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img alt="Image by OZinOH on Flickr" src="http://encosia.com/blog/wp-content/uploads/2011/11/library-catalog-cabinet.jpg" style="border: 1px solid #ccc;" width="490" /></p>
<p>One of the longest running themes here has been the compelling intersection between ASP.NET and jQuery. Beginning with <a href="http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/" target="_blank">my post about using jQuery to circumvent ASP.NET AJAX&#8217;s client-side apparatus for calling ASMX services</a>, I&#8217;ve been writing about using ASP.NET and jQuery since the Spring of 2008.</p>
<p>As these related posts have accumulated over the years, I&#8217;ve made an effort to weave a thread of cross-links between them posts where appropriate. However, it&#8217;s nearly impossible to anticipate every possible entry point and subsequent path that someone might find themselves following here.</p>
<p>So, I&#8217;ve decided to finally do what I should have done a year or two ago: Create a top-level index to organize and improve the accessibility of my content for ASP.NET developers interested in integrating jQuery into their sites.</p>
<p>You can see my first draft of that here: <a href="http://encosia.com/jquery-for-the-asp-net-developer/" title="jQuery for the ASP.NET Developer" target="_blank">jQuery for the ASP.NET Developer</a></p>
<p>Unlike the other content here, I&#8217;m publishing this one <em>long</em> before it&#8217;s &#8220;finished&#8221;. My hope is that I can solicit early feedback to help better construct a useful narrative while the document is still in its formative stages. So, if you have any feedback on the current page or what you think should ultimately be there, please leave me a comment on either this post or that page, <a href="http://encosia.com/contact/" target="_blank">contact me directly</a>, or even <a href="http://twitter.com/Encosia" target="_blank">@mention it my way on Twitter</a>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/best-of-2008-5-most-popular-posts/' rel='bookmark' title='Best of 2008: 5 most popular posts'>Best of 2008: 5 most popular posts</a></li>
<li><a href='http://encosia.com/best-of-2007-5-most-popular-posts-and-contest-winners/' rel='bookmark' title='Best of 2007: 5 most popular posts (and contest winners)'>Best of 2007: 5 most popular posts (and contest winners)</a></li>
<li><a href='http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/help-me-organize-my-posts-about-using-jquery-with-asp-net/">Help me organize my posts about using jQuery with ASP.NET</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/help-me-organize-my-posts-about-using-jquery-with-asp-net/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/help-me-organize-my-posts-about-using-jquery-with-asp-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why PhoneGap 1.1.0 broke jQuery Mobile&#8217;s back button</title>
		<link>http://encosia.com/why-phonegap-1-1-0-broke-jquery-mobiles-back-button/</link>
		<comments>http://encosia.com/why-phonegap-1-1-0-broke-jquery-mobiles-back-button/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 18:01:02 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1197</guid>
		<description><![CDATA[For the past week, I&#8217;ve been neck-deep in a challenging project that combines jQuery Mobile and PhoneGap to do some relatively heavy lifting. Though I&#8217;ve used both jQuery Mobile and PhoneGap in the past, this recent exercise left me with a few morsels of newly-hard-earned knowledge. Among that education was learning that PhoneGap 1.1.0 breaks [...]
Related posts:<ol>
<li><a href='http://encosia.com/disable-a-button-control-during-postback/' rel='bookmark' title='Disable a button control during postback.'>Disable a button control during postback.</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
<li><a href='http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/' rel='bookmark' title='jQuery 1.6.2 syntax error? You may be the victim of SEO.'>jQuery 1.6.2 syntax error? You may be the victim of SEO.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>For the past week, I&#8217;ve been neck-deep in a challenging project that combines jQuery Mobile and PhoneGap to do some relatively heavy lifting. Though I&#8217;ve used both jQuery Mobile and PhoneGap in the past, this recent exercise left me with a few morsels of newly-hard-earned knowledge. Among that education was learning that <strong>PhoneGap 1.1.0 breaks jQuery Mobile&#8217;s back button on Android devices</strong>.</p>
<p>Being able to use a web-based framework like jQuery Mobile to create a &#8220;native&#8221; mobile app is one of PhoneGap&#8217;s most appealing propositions. So, you can imagine my dismay when wrapping this latest project in PhoneGap broke its navigation. Worse yet, even closing jQuery Mobile&#8217;s dialog windows stopped working under PhoneGap 1.1.0.</p>
<p>Luckily, the problem ended up being a minor one with a simple fix. In this post, I&#8217;ll briefly show you why PhoneGap 1.1.0 caused jQuery Mobile&#8217;s back buttons to stop working and how you can fix that problem in your own app.</p>
<h3>Getting back() to basics</h3>
<p>If you&#8217;ve ever navigated through a jQuery Mobile app with the document&#8217;s address visible, you&#8217;ve probably noticed that jQuery Mobile makes heavy use of the browser&#8217;s history API to maintain state and facilitate navigation. Whether using its recently added pushState support or the more traditional hash-based history management, even something as simple as opening a dialog window creates a new history entry.</p>
<p>Conversely, moving back to previous states is then as simple as executing a quick <code>history.back()</code> in the browser. And, that&#8217;s exactly how jQuery Mobile&#8217;s built-in back buttons and dialog close buttons work. Surprisingly, that&#8217;s even <a href="https://github.com/jquery/jquery-mobile/blob/1.0rc1/js/jquery.mobile.dialog.js#L70" target="_blank">what initially happens</a> when you make a call to <code>$.dialog('close')</code>.</p>
<h3>Finding the problem</h3>
<p>Knowing that the problem I faced was related to the browser&#8217;s <code>history.back()</code> API helped narrow it down quite a bit. The first thing I did was use <a href="http://remysharp.com/" target="_blank">Remy Sharp</a>&#8216;s invaluable <a href="http://jsconsole.com" target="_blank">JsConsole</a> to establish a console session linked to the embedded browser window in my PhoneGap app. Using that interface to poke around at the browser&#8217;s history object made the problem clear:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/10/history.back-phonegap-1.1.0.png" width="490" height="110" style="border: 1px solid #ccc;" /></p>
<p>PhoneGap&#8217;s client-side library had replaced the <code>history.back()</code> function with one of its own (app-native Java code, no less). Digging into the Android version of phonegap-1.1.0.js, the culprit can be found beginning at line 1,277:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">PhoneGap.<span style="color: #660066;">addConstructor</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    navigator.<span style="color: #660066;">app</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> App<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    navigator.<span style="color: #660066;">app</span>.<span style="color: #660066;">origHistoryBack</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">history</span>.<span style="color: #000066;">back</span><span style="color: #339933;">;</span>
    window.<span style="color: #660066;">history</span>.<span style="color: #000066;">back</span> <span style="color: #339933;">=</span> navigator.<span style="color: #660066;">app</span>.<span style="color: #660066;">backHistory</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>JavaScript&#8217;s incredible flexibility is usually a strength, but it is a bit like running with scissors at times. The latter couple lines of that function stores a reference to the browser&#8217;s native <code>history.back</code> function and then <a href="http://webdevwonders.com/monkey-patching-extend-built-in-javascript-functions-with-custom-code/" target="_blank">monkey patches</a> it with PhoneGap&#8217;s implementation instead.</p>
<h3>The fix</h3>
<p>Fixing the issue could have been accomplished (at least) two different ways. Either jQuery Mobile needed to use <code>navigator.app.origHistoryBack</code> if it existed, or PhoneGap&#8217;s interloping needed to be curtailed. Since reverting PhoneGap&#8217;s <code>history.back</code> monkey patch was much simpler, I was already leaning that direction.</p>
<p>Then, when I saw <a href="https://github.com/phonegap/phonegap-android/commit/fe3e7041b7b0c19ae258818fb8ff17f17bf760f6" target="_blank">this recent commit on GitHub</a>, the choice was an easy one.</p>
<p>Presumably, this change will be included in the next PhoneGap release since it was committed to the master branch. In the meantime, you can easily apply the change to your own copy of phonegap-1.1.0.js by finding this code (beginning at line 1,277):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">PhoneGap.<span style="color: #660066;">addConstructor</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    navigator.<span style="color: #660066;">app</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> App<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    navigator.<span style="color: #660066;">app</span>.<span style="color: #660066;">origHistoryBack</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">history</span>.<span style="color: #000066;">back</span><span style="color: #339933;">;</span>
    window.<span style="color: #660066;">history</span>.<span style="color: #000066;">back</span> <span style="color: #339933;">=</span> navigator.<span style="color: #660066;">app</span>.<span style="color: #660066;">backHistory</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And changing it to this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">PhoneGap.<span style="color: #660066;">addConstructor</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    navigator.<span style="color: #660066;">app</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> App<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As I mentioned earlier, this only impacts the Android version of PhoneGap (to my knowledge). So, don&#8217;t go digging through versions of phonegap-1.1.0.js for other platforms looking to remove this monkey patch &#8211; it isn&#8217;t there.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/disable-a-button-control-during-postback/' rel='bookmark' title='Disable a button control during postback.'>Disable a button control during postback.</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
<li><a href='http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/' rel='bookmark' title='jQuery 1.6.2 syntax error? You may be the victim of SEO.'>jQuery 1.6.2 syntax error? You may be the victim of SEO.</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/why-phonegap-1-1-0-broke-jquery-mobiles-back-button/">Why PhoneGap 1.1.0 broke jQuery Mobile&#8217;s back button</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/why-phonegap-1-1-0-broke-jquery-mobiles-back-button/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/why-phonegap-1-1-0-broke-jquery-mobiles-back-button/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>ASP.NET page methods are only as secure as you make them</title>
		<link>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/</link>
		<comments>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 16:47:58 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1155</guid>
		<description><![CDATA[One of the most persistent misconceptions about ASP.NET&#8217;s page methods is the notion that they have some intrinsic protection against requests that don&#8217;t originate from the page where they&#8217;re defined. Since a page method&#8217;s code resides within a page&#8217;s code-behind file, it&#8217;s intuitive to assume that those methods benefit from some form of inherent security. [...]
Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/why-do-aspnet-ajax-page-methods-have-to-be-static/' rel='bookmark' title='Why do ASP.NET AJAX page methods have to be static?'>Why do ASP.NET AJAX page methods have to be static?</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>One of the most persistent misconceptions about ASP.NET&#8217;s page methods is the notion that they have some intrinsic protection against requests that don&#8217;t originate from the page where they&#8217;re defined. Since a page method&#8217;s code resides within a page&#8217;s code-behind file, it&#8217;s intuitive to assume that those methods benefit from some form of inherent security.</p>
<p>Unfortunately, that is not the case.</p>
<h3>Exploiting your page&#8217;s insecurities</h3>
<p>In case it&#8217;s hard to believe these code-behind methods truly are so easily accessible, let&#8217;s take a look at a quick example. Let&#8217;s say you have a page method that returns sensitive business information, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>WebMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">int</span> SecretFormula<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">42</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Assuming that method is defined in a <code>Default.aspx</code> file&#8217;s code-behind, located in a folder named <code>TopSecret</code>, here&#8217;s a bit of jQuery you could use to request the secret formula from any page on the site:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/TopSecret/Default.aspx/SecretFormula'</span><span style="color: #339933;">,</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/json'</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">'{}'</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>result.<span style="color: #660066;">d</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In fact, you can even make that request from a plain HTML file. In this example, I&#8217;m making the request right from a simple HTML file named <code>index.htm</code>:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/09/accessing-page-method-firebug.png" rel="attachment"><img src="http://encosia.com/blog/wp-content/uploads/2011/09/accessing-page-method-firebug.png" title="Using jQuery to access the page method from outside its ASPX page." width="492" height="83" /></a></p>
<p>Not only is the request not originating from the ASPX file that contains the page method, <strong>that request wasn&#8217;t originating from an ASPX file at all!</strong></p>
<h3>Is this really a problem?</h3>
<p>You might be asking yourself if this is really a problem to begin with. After all, you aren&#8217;t very likely to write client-side code that requests sensitive data unless you actually need that data, regardless of whether you write that code on an ASPX page, HTML page, or anywhere else.</p>
<p>The trouble is, a villain could land on any of your site&#8217;s pages, open up Firebug, and start probing for weaknesses like this one. In this case, the obscurity of the exact location of the page method might lead you to a false sense of security, but <strong>if an attacker has any knowledge of your system&#8217;s architecture then the door is wide open</strong>.</p>
<p>Even more troubling, as long as an attacker uses POST requests with an <code>application/json</code> Content-Type, they could use a tool as simple as Fiddler to interrogate your site&#8217;s services remotely. A few lines of server-side code, and your competition could set up a site driven by the page method APIs on your site that you thought were private!</p>
<h3>A fixable problem</h3>
<p>Page methods aren&#8217;t indefensible against the shenanigans of external interlopers though. You can secure them with ASP.NET&#8217;s built-in authorization mechanism, just as you would any other ASPX page (or ASMX service). In fact, if you secure an ASPX page with ASP.NET authorization, page methods defined in its code-behind are automatically equally secure.</p>
<p>To deny unauthenticated access to methods in our <code>TopSecret</code> folder, <a href="http://msdn.microsoft.com/en-us/library/wce3kxhd.aspx" target="_blank">adding an authorization entry to the web.config in that folder</a> is all that&#8217;s necessary:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;authorization<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;deny</span> <span style="color: #000066;">users</span>=<span style="color: #ff0000;">&quot;?&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/authorization<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Now, an unauthenticated user trying to access the <code>SecretFormula</code> method from <code>index.htm</code> (or anywhere else, without authenticating first) is denied access:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/09/secured-page-method-firebug.png" rel="attachment"><img src="http://encosia.com/blog/wp-content/uploads/2011/09/secured-page-method-firebug.png" alt="Attempting to request the same page method with jQuery after securing it." title="secured-page-method-firebug" width="492" height="83" /></a></p>
<p>Of course, there are a variety of ways to control access to these methods. You might test to see which role a user&#8217;s in and respond accordingly, or you might only need to verify some token stored in the Session. </p>
<p>Regardless of the particular mechanism, <strong>the key is to remember that none of this is automatic and that you must be mindful of regulating access to your page methods</strong>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/why-do-aspnet-ajax-page-methods-have-to-be-static/' rel='bookmark' title='Why do ASP.NET AJAX page methods have to be static?'>Why do ASP.NET AJAX page methods have to be static?</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/">ASP.NET page methods are only as secure as you make them</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Use ASP.NET&#8217;s HttpHandler to bridge the cross-domain gap</title>
		<link>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/</link>
		<comments>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 14:59:25 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1105</guid>
		<description><![CDATA[When you&#8217;re developing client-side applications, a problem you&#8217;ll almost inevitably have to deal with is how to work with services that reside outside your website&#8217;s domain. Though many modern APIs do support JSONP, which is a clever workaround to somewhat mitigate the cross-domain problem, JSONP has its own problems. Worse, if you encounter an API [...]
Related posts:<ol>
<li><a href='http://encosia.com/ajax-file-downloads-and-iframes/' rel='bookmark' title='AJAX, file downloads, and IFRAMEs'>AJAX, file downloads, and IFRAMEs</a></li>
<li><a href='http://encosia.com/the-easiest-way-to-break-aspnet-ajax-pages/' rel='bookmark' title='The easiest way to break ASP.NET AJAX pages'>The easiest way to break ASP.NET AJAX pages</a></li>
<li><a href='http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/' rel='bookmark' title='Why ASP.NET AJAX UpdatePanels are dangerous'>Why ASP.NET AJAX UpdatePanels are dangerous</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re developing client-side applications, a problem you&#8217;ll almost inevitably have to deal with is how to work with services that reside outside your website&#8217;s domain. Though many modern APIs do support JSONP, which is a clever workaround to somewhat mitigate the cross-domain problem, JSONP has its own problems.</p>
<p>Worse, if you encounter an API with no JSONP support, <strong>the cross-domain barrier can quickly become a formidable one</strong>. <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/" target="_blank">CORS</a> is slowly becoming a viable alternative, but it requires that the remote service support it via special HTTP headers and browser support for <a href="http://caniuse.com/#search=cors" target="_blank">CORS is still not ubiquitous</a>.</p>
<p>Until CORS is more broadly supported, an alternative solution is to bounce cross-domain requests through the web server that hosts your website. In ASP.NET, the best tool for implementing that sort of middleman endpoint is the <a href="http://msdn.microsoft.com/en-us/library/ms228090.aspx" target="_blank">HttpHandler</a>.</p>
<p>In this post, I’ll show you <strong>how to create an HttpHandler</strong> to service cross-domain requests, how to <strong>use jQuery to communicate with the handler</strong>, and <strong>an example of one improvement</strong> that this approach makes possible.</p>
<h3>An example remote API</h3>
<p>To focus on an example that&#8217;s already familiar to many, I&#8217;m going to use Twitter. Twitter&#8217;s API <em>does</em> support JSONP, which is a viable alternative for consuming it across domains. In fact, the Twitter status that you see in my sidebar to the right was retrieved from Twitter&#8217;s API via JSONP.</p>
<p>However, not every service supports JSONP, its third-party script injection mechanism is sometimes problematic, and using JSONP robs us of niceties like local caching. So, for the sake of a good example, let&#8217;s find a way to use the Twitter API on the client-side without resorting to JSONP.</p>
<p>Specifically, I&#8217;m interested in querying the service for my last few status updates. The Twitter API request to accomplish that looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">http://api.twitter.com/1/statuses/user_timeline.json?id=Encosia</pre></div></div>

<p>Twitter will respond to that with a JSON array of objects representing my (or your) last 20 tweets, which is exactly what we&#8217;re after.</p>
<h3>The best tool for the job: HttpHandler</h3>
<p>If you&#8217;re accustomed to using ASP.NET&#8217;s <a href="http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/" target="_blank">page methods</a> and <a href="http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/" target="_blank">ScriptServices</a> to facilitate communication between client and server, those tools begin to look like a hammer that matches every JSON-shaped nail in sight. However, when simply relaying an external API&#8217;s JSON through to the client, they often add unnecessary overhead and complexity.</p>
<p>Rather, a lower-level tool is more appropriate in this case.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.processrequest.aspx" target="_blank" rel="nofollow">HttpHandlers</a> are one of ASP.NET’s most under-utilized tools. They&#8217;re simple to implement and allow you to handle requests closer to the metal than WebForms pages or MVC controller actions.</p>
<p>One place in particular where HttpHandlers shine is where you would otherwise consider writing <code>Response.Write</code> statements in a WebForms page’s code-behind. This anti-pattern of using ASPX&#8217;s code-behind to get closer to the metal <em>looks</em> similar to approaches that you&#8217;ll see on some other platforms, such as PHP, but is not equivalent.</p>
<p>Unfortunately, even if you don&#8217;t use WebForms controls or ASPX markup at all, executing that low-level code from an ASPX page&#8217;s code-behind requires that every request filter through the full page life cycle. That means even the simplest request still has to percolate <a href="http://msdn.microsoft.com/en-us/library/ms178472.aspx#lifecycle_events" target="_blank" rel="nofollow">all the way from PreInit to Unload</a>, adding needless overhead.</p>
<p>Instead, the HttpHandler is where you should write that sort of code that ultimately boils down to <code>Response.Write</code> calls.</p>
<h3>Choosing the right handler type</h3>
<p>A tricky issue when you&#8217;re writing your first HttpHandler is that Visual Studio presents you with two templates, “ASP.NET Handler” and “Generic Handler”:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/07/add-httphandler-dialog.png" rel="attachment" class="cboxElement"><img src="http://encosia.com/blog/wp-content/uploads/2011/07/add-httphandler-dialog.png" alt="The add item dialog presents two choices of HttpHandler templates" title="Add HttpHandler dialog" width="492" height="330" /></a></p>
<p>Both are similar, but the “ASP.NET Handler” template’s approach requires modifying your web.config to configure which URL your handler accepts requests at. Mucking around in the web.config isn&#8217;t terribly difficult, but it’s extra friction which makes the process less approachable.</p>
<p>In the spirit of keeping things simple, let&#8217;s stick with the more traditionally file-based “Generic Handler”.</p>
<h3>Getting started with your first HttpHandler</h3>
<p>After choosing that template, specifying a name, and adding the new file to your site, you’ll end up with a bit of boilerplate code that includes this method:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;text/plain&quot;</span><span style="color: #008000;">;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Hello World&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>If you start the site up in Visual Studio and then request your newly-created HttpHandler in a browser, <code>Handler1.ashx</code> if you accept the default name, you will see “Hello World” as you might expect.</p>
<p>That&#8217;s not very impressive yet, but the response you saw made its way to your browser without touching WebForms’ page life cycle or filtering through ASP.NET MVC’s routing engine and action filters. While those things are worthwhile niceties for the majority of your application, they’re unwanted overhead when all you need is to efficiently relay some content through the server.</p>
<h3>Bouncing a request to Twitter through the HttpHandler</h3>
<p>To adapt an HttpHandler for relaying requests to the Twitter API, we can use <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx" target="_blank" rel="nofollow">.NET&#8217;s handy WebClient class</a> to make the request to Twitter&#8217;s API, and then return the result back through as the handler&#8217;s response:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// The base URL for Twitter API requests.</span>
  <span style="color: #FF0000;">string</span> baseUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// The specific API call that we're interested in.</span>
  <span style="color: #FF0000;">string</span> request <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;statuses/user_timeline.json?id=Encosia&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Make a request to the API and capture its result.</span>
  <span style="color: #FF0000;">string</span> response <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>baseUrl <span style="color: #008000;">+</span> request<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Set the content-type so that libraries like jQuery can </span>
  <span style="color: #008080; font-style: italic;">//  automatically parse the result.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Relay the API response back down to the client.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>response<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>That code simply makes an HTTP request to the Twitter API and blindly bounces the result back through as the HttpHandler&#8217;s response. For the time being, everything is hard-coded, but we&#8217;ll improve on that soon enough.</p>
<h4>Using the handler proxy on the client-side</h4>
<p>With our web server doing the heavy lifting, using this server-side proxy to make a remote request is trivial:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'TwitterProxy.ashx'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Call a magical function that does all the presentational work.</span>
  displayTweets<span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The jQuery code here is actually identical what you&#8217;d use when requesting the API via JSONP. Whether that response is truly being fulfilled by the specified URL or it&#8217;s being relayed through our HttpHandler, <strong>it&#8217;s all the same to the jQuery code on the client-side</strong>.</p>
<p>As you&#8217;ll see when we add caching, this can easily be exploited for good.</p>
<h3>Mixing things up with QueryString parameters</h3>
<p>The hard-coded approach works well enough, but what if we wanted to be able to query any Twitter account&#8217;s recent updates instead of being limited to just <a href="https://twitter.com/encosia" target="_blank">that boring Encosia character</a>?</p>
<p>Since HttpHandlers receive an instance of the current HttpContext as the parameter to their ProcessRequest method, it&#8217;s easy to access QueryString parameters and react accordingly. For example, this would allow us to request any Twitter account&#8217;s timeline by via an <code>id</code> parameter on the QueryString:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #FF0000;">string</span> baseUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Extract the desired account ID from the QueryString.</span>
  <span style="color: #FF0000;">string</span> id <span style="color: #008000;">=</span> context.<span style="color: #0000FF;">Request</span>.<span style="color: #0000FF;">QueryString</span><span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;id&quot;</span><span style="color: #000000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Make a request to the API for the specified id.</span>
  <span style="color: #FF0000;">string</span> request <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;statuses/user_timeline.json?id=&quot;</span> <span style="color: #008000;">+</span> id<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Same as before, from here on out:</span>
  <span style="color: #FF0000;">string</span> response <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>baseUrl <span style="color: #008000;">+</span> request<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>response<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Now it works exactly the same way as before, but we can choose which Twitter account&#8217;s timeline is requested. For example, this URL would request <a href="http://weblogs.asp.net/scottgu/" target="_blank">Scott Guthrie</a>&#8216;s latest tweets:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">TwitterProxy.ashx?id=ScottGu</pre></div></div>

<h4>Supplying parameters with $.getJSON</h4>
<p>To pass this new parameter in from the client-side, you could handcraft the entire URL including the appropriate QueryString. Even better though, <code>$.getJSON</code> has <a href="http://api.jquery.com/jQuery.getJSON/" target="_blank">an optional &#8220;data&#8221; argument</a> that accepts a JavaScript object and converts it to QueryString parameters:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'TwitterProxy.ashx'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span> <span style="color: #3366CC;">'ScottGu'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  displayTweets<span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>jQuery will automatically URLEncode the parameters you specify in the &#8220;data&#8221; argument and properly assemble them into the final URL to be requested:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/08/request-in-firebug.png" alt="Screenshot of the HttpHandler request generated by the jQuery code above." title="HttpHandler request in Firebug" width="490" height="145" style="border: 1px solid #333;" /></p>
<p>Which is exactly what we need it to do.</p>
<p>Using a configuration object like this is cleaner than manually concatenating a string together and makes it easier to vary the parameter at runtime.</p>
<h3>Improving performance with server-side caching</h3>
<p>An advantage the HttpHandler proxy has over CORS and JSONP is that you can perform any arbitrary server-side processing that you wish, both before and after the remote service repsonds. <strong>A great way to take advantage of that is adding a server-side caching layer</strong>. </p>
<p>Server-side caching will reduce how often requests actually trigger API calls and can significantly improve performance for requests that are already cached. A caching middleman like this is especially valuable when dealing with rate-limited APIs like Twitter&#8217;s.</p>
<p>Let&#8217;s say that we wanted to cache Twitter responses for up to five minutes, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// This will be the case whether there's a cache hit or not.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Check to see if the twitter status is already cached,</span>
  <span style="color: #008080; font-style: italic;">//   then retrieve and return the cached value if so.</span>
  <span style="color: #008080; font-style: italic;">// 8/3/11: Updated with more robust test, thanks to ctolkien.</span>
  <span style="color: #FF0000;">object</span> tweetsCache <span style="color: #008000;">=</span> context.<span style="color: #0000FF;">Cache</span><span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;tweets-&quot;</span> <span style="color: #008000;">+</span> id<span style="color: #000000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>tweetsCache <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #FF0000;">string</span> cachedTweets <span style="color: #008000;">=</span> tweetsCache.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>cachedTweets<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// We're done here.</span>
    return<span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
&nbsp;
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Move along; nothing to see here. The concatenation is just</span>
  <span style="color: #008080; font-style: italic;">//  to avoid horizontal scrolling within the meager 492</span>
  <span style="color: #008080; font-style: italic;">//  pixels I have to work with here.</span>
  <span style="color: #FF0000;">string</span> url <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/statuses/&quot;</span> <span style="color: #008000;">+</span>
               <span style="color: #666666;">&quot;user_timeline.json?id=Encosia&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #FF0000;">string</span> tweets <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>url<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// This monstrosity essentially just caches the WebClient result</span>
  <span style="color: #008080; font-style: italic;">//  with a maximum lifetime of 5 minutes from now.</span>
  <span style="color: #008080; font-style: italic;">// If you don't care about the expiration, this can be a simple</span>
  <span style="color: #008080; font-style: italic;">//  context.Cache[&quot;tweets&quot;] = tweets; instead.</span>
  context.<span style="color: #0000FF;">Cache</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tweets&quot;</span>, tweets,
    <span style="color: #0600FF;">null</span>, DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">AddMinutes</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">5</span><span style="color: #000000;">&#41;</span>, 
    <span style="color: #000000;">System.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Caching</span></span>.<span style="color: #0000FF;">Cache</span>.<span style="color: #0000FF;">NoSlidingExpiration</span>,
    <span style="color: #000000;">System.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Caching</span></span>.<span style="color: #0000FF;">CacheItemPriority</span>.<span style="color: #0000FF;">Normal</span>, 
    <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>tweets<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Adding the intermediate cache results in a tremendous performance improvement after the first request:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/08/cached-twitter-requests.png" style="border: 1px solid #333;" width="490" height="134" alt="Screenshot of an initial uncached request to Twitter and then the subsequent, cached requests" /></p>
<p>With the server able to immediately serve requests within the five minute caching window, subsequent $.getJSON requests are an order of magnitude faster!</p>
<p>Perhaps even more importantly in the case of Twitter, these four refreshes only counted as one API call against my hourly rate-limit.</p>
<h3>Conclusion</h3>
<p>Using HttpHandlers as server-side proxies turns out to be a simple way to solve the pesky cross-domain restrictions that we&#8217;ve all run into from time to time. All said and done, using an HttpHandler to proxy third-party requests takes few lines of code, but offers nearly unlimited flexibility.</p>
<p>In addition to the obvious benefit of getting around the cross-domain restriction, bouncing requests through your own server potentially has a range of other benefits, including:</p>
<ul>
<li><strong>Error handling</strong> &#8211; This approach not only passes unhandled exceptions on the WebClient request back through to the client-side, but it also gives you the ability to enhance the error handling with your own sanity checks and constraints.</li>
<li><strong>Caching</strong> &#8211; As shown in this post&#8217;s final example, you can very easily interject your own caching layer for requests passing through the HttpHandler proxy. That&#8217;s especially useful when working against rate limited or potentially slow/flaky APIs (like Twitter&#8217;s).</li>
<li><strong>Security</strong> &#8211; When you&#8217;re accustomed to server-side programming, the revealing nature of client-side JavaScript can be unnerving. Learning to appropriately partition sensitive algorithms and data between client and server is key to mitigating that issue. Along those lines, moving the remote request to code running on your server is one way to keep sensitive information like API keys and passwords safely hidden from view-source and client-side developer tools.</li>
<li><strong>Reliability</strong> &#8211; One of JSONP&#8217;s less obvious drawbacks is the fact that it relies on injecting a third-party script. However, your users may be using something like NoScript to purposely block third-party scripts, effectively shutting down your ability to use JSONP. Even if you prefer JSONP in most cases, a local server-side proxy can be helpful as a fallback in case of unexpected JSONP failures.</li>
</ul>
<p>That&#8217;s not to say that there&#8217;s no downsides to this approach. When you&#8217;re using an HttpHandler proxy, it&#8217;s important to keep in mind that it can be slower since you&#8217;re making a series of two connections instead of a single, direct one. You also lose the ability to request content with the user&#8217;s third-party cookies attached to the request, which is helpful in some cases.</p>
<p>Overall, using server-side proxies is a very useful item to have in your toolbox. I hope this post has served to introduce you to the approach and/or given you better insight into how you can use HttpHandlers to your advantage.</p>
<h3>Get the source</h3>
<p>If you&#8217;d like to browse through a complete working example of what&#8217;s been covered in this post, take a look at the companion project at GitHub. Or, if you&#8217;d like to download the entire project and run it in Visual Studio to see it in action yourself, grab the ZIP archive.</p>
<p><a href="https://github.com/Encosia/Encosia-Samples-HttpHandler-Proxy/tree/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: left; text-align: center;">HttpHandler-Proxy on GitHub</a><a href="https://github.com/Encosia/Encosia-Samples-HttpHandler-Proxy/zipball/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: right; text-align: center;">HttpHandler-Proxy.zip</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/ajax-file-downloads-and-iframes/' rel='bookmark' title='AJAX, file downloads, and IFRAMEs'>AJAX, file downloads, and IFRAMEs</a></li>
<li><a href='http://encosia.com/the-easiest-way-to-break-aspnet-ajax-pages/' rel='bookmark' title='The easiest way to break ASP.NET AJAX pages'>The easiest way to break ASP.NET AJAX pages</a></li>
<li><a href='http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/' rel='bookmark' title='Why ASP.NET AJAX UpdatePanels are dangerous'>Why ASP.NET AJAX UpdatePanels are dangerous</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/">Use ASP.NET&#8217;s HttpHandler to bridge the cross-domain gap</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery 1.6.2 syntax error? You may be the victim of SEO.</title>
		<link>http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/</link>
		<comments>http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 14:11:14 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1129</guid>
		<description><![CDATA[A reader contacted me this weekend to inform me that jQuery 1.6.2 had broken all of my old examples of using jQuery with ASP.NET services. Not good! How could such a simple update have caused this?! I didn&#8217;t really expect that updating from jQuery 1.6.1 to 1.6.2 would break anything, much less break everything. As [...]
Related posts:<ol>
<li><a href='http://encosia.com/what-aspnet-developers-should-know-about-jquery/' rel='bookmark' title='What ASP.NET developers should know about jQuery'>What ASP.NET developers should know about jQuery</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
<li><a href='http://encosia.com/mastering-jquery-now-available-at-tekpub/' rel='bookmark' title='Mastering jQuery now available at TekPub'>Mastering jQuery now available at TekPub</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-1.6.2-fake-errors.png" align="right" style="border: 1px solid #ccc; margin-top: 4px; margin-left: 5px;" width="256" height="94" />A reader contacted me this weekend to inform me that <a href="http://blog.jquery.com/2011/06/30/jquery-162-released/" target="_blank">jQuery 1.6.2</a> had broken all of my old examples of using jQuery with ASP.NET services. Not good! How could such a simple update have caused this?!</p>
<p>I didn&#8217;t really expect that updating from jQuery 1.6.1 to 1.6.2 would break anything, much less break <em>everything</em>.</p>
<p>As it turns out, the problem didn&#8217;t have anything to do with <a href="http://blog.jquery.com/2011/06/30/jquery-162-released/" target="_blank">jQuery 1.6.2</a> or my own code.  However, while investigating, <strong>I ended up falling prey to the same treachery that led to the original bug report.</strong></p>
<h3>This is why we can&#8217;t have nice things</h3>
<p>Google has been raked across the coals this year, with <a href="http://www.codinghorror.com/blog/2011/01/trouble-in-the-house-of-google.html" target="_blank">serious questions being raised about their ability to handle the mounting problems of hyper-SEO&#8217;d spam sites and content farms</a>.  Unfortunately, this weekend&#8217;s problem with <a href="http://blog.jquery.com/2011/06/30/jquery-162-released/" target="_blank">jQuery 1.6.2</a> was yet another failure in Google&#8217;s ongoing struggle with that dross.</p>
<p>Hopefully, the situation will have improved by the time you&#8217;re reading this post, but as I&#8217;m writing this, the first organic search result for <strong>jQuery 1.6.2</strong> is this one:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-1.6.2-search-result.png" style="border: 1px solid #ccc;" /></p>
<p>If you&#8217;re in a hurry to download a copy of the latest jQuery revision, that result looks legitimate enough, but look closely at the domain name.  Notice that it&#8217;s <code>.it</code>, not <code>.com</code>.  This domain is <em>not</em> owned or controlled by the jQuery Project.</p>
<p>Regardless, following the link to this search result takes you to what appears to be an authentic jQuery blog post:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-fake-in-browser.png" rel="attachment" class="cboxElement"><img src="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-fake-in-browser.png" width="492" height="429" /></a></p>
<p>As legitimate as it looks, that site is an entirely unsanctioned ripoff of the official jQuery site.  Yet, <strong>this impostor has somehow out-ranked the official jQuery blog in Google searches for its own content</strong>.</p>
<h3>That&#8217;s lame, but what&#8217;s the harm?</h3>
<p>In my hurry, I didn&#8217;t notice the <code>.it</code> domain, much less that this seemingly authentic jQuery blog post was an automated copy of the real thing.  I right-clicked the link to unminified jQuery 1.6.2, saved it locally, and went about my testing. </p>
<p>After unwittingly downloading this fraud&#8217;s copy of <a href="http://blog.jquery.com/2011/06/30/jquery-162-released/" target="_blank">jQuery 1.6.2</a> and testing it in some of my old samples, I did indeed begin seeing JavaScript errors as my reader had reported.  Closer inspection revealed that the errors were related to the jQuery script include itself though, not my own code.</p>
<p>So, what was going on?  Following the errors back to their source, I found this at the very end of the jQuery script I had downloaded:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Expose jQuery to the global object</span>
window.<span style="color: #660066;">jQuery</span> <span style="color: #339933;">=</span> window.$ <span style="color: #339933;">=</span> jQuery<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>window<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>Time to generate<span style="color: #339933;">:</span> <span style="color: #CC0000;">1.35903</span></pre></div></div>

<p>Things were looking good until that final <code>Time to generate</code> bit at the very end.  That is obviously not valid JavaScript.  Likely, it was appended to the file by whatever tool was used to clone the official site.</p>
<p>When browsers hit a hard syntax error like this while parsing a script include, the entire script is ignored and no part of it makes its way into the DOM.  So, this tiny error at the very end of thousands of lines of code was all it took to effectively disable the entire library.</p>
<h3>Finding a legitimate copy of jQuery</h3>
<p>So, where should you be looking for the authentic copies of jQuery 1.6.2?</p>
<ul>
<li>You can find unfettered copies of <a href="http://blog.jquery.com/2011/06/30/jquery-162-released/" target="_blank">jQuery 1.6.2 on the (real) jQuery blog</a>.</li>
<li>The latest version is also available on <a href="http://docs.jquery.com/Downloading_jQuery" target="_blank">the jQuery site&#8217;s download page</a>.</li>
<li>Finally, I&#8217;m a long-time proponent of the <a href="http://encosia.com/6953-reasons-why-i-still-let-google-host-jquery-for-me/" title="6,953 reasons why I still let Google host jQuery for me" target="_blank">performance advantages that Google&#8217;s AJAX APIs CDN can bring to your site</a> via its public CDN for jQuery. That CDN is another authoritative source for jQuery 1.6.2 (<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js" target="_blank">uncompressed</a>, <a href="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" target="_blank">minified</a>).</li>
</ul>
<h3>Conclusion</h3>
<p><strike>Posting criticisms of Google on a site that depends on search for over 60% of its traffic may be asking for trouble, but this is a flagrant failure on Google&#8217;s part.  Algorithms be damned; they simply cannot allow a random AdSense splog to hijack well-targeted searches for the most popular JavaScript library on the planet.</p>
<p><strong>Imagine how much worse things could have been if this site were actively evil instead of harmlessly inept</strong>.  Injecting even a tiny bit of malicious JavaScript into such a ubiquitous library could have resulted in a minor catastrophe, as thousands of developers downloaded that subverted version and tested it on their sites.</strike></p>
<p><strong>Update:</strong> Thanks to <a href="#comment-44287">Pierre&#8217;s helpful comment below</a>, the issue that allowed the scraper&#8217;s site to outrank the original is now apparent: requests to individual post permalinks on blog.jQuery.com return a 500 error when requested with a User-Agent of Googlebot.</p>
<p>As frustrating it is to see a splog outrank the original, there&#8217;s no way to fault Googlebot for not indexing something that it couldn&#8217;t see.  My original conclusion about this being a failure on Google&#8217;s part was obviously unwarranted.</p>
<p>Sorry about that.</p>
<p><strong>Epilogue:</strong> As of last night, this is what I&#8217;m seeing returned for jQuery 1.6.2 searches now.</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-blog-mission-accomplished.png" title="jQuery 1.6.2 release post ranking #1" rel="attachment" class="cboxElement"><img src="http://encosia.com/blog/wp-content/uploads/2011/07/jquery-blog-mission-accomplished.png" width="490" height="321" class="attachment-medium"></a></p>
<p>All&#8217;s well that ends well.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/what-aspnet-developers-should-know-about-jquery/' rel='bookmark' title='What ASP.NET developers should know about jQuery'>What ASP.NET developers should know about jQuery</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
<li><a href='http://encosia.com/mastering-jquery-now-available-at-tekpub/' rel='bookmark' title='Mastering jQuery now available at TekPub'>Mastering jQuery now available at TekPub</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/">jQuery 1.6.2 syntax error? You may be the victim of SEO.</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/jquery-1-6-2-syntax-error-you-may-be-the-victim-of-seo/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Save yourself some typing when you call ASP.NET services</title>
		<link>http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/</link>
		<comments>http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 16:17:47 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1126</guid>
		<description><![CDATA[Mea culpa: I may owe your fingers an apology. If you&#8217;ve been using my approach for directly calling ASP.NET&#8217;s JSON-based services with jQuery, you know that specifying the correct Content-Type on your requests to them is a crucial part of coaxing JSON out of them. However, when I suggested that a Content-Type of application/json; charset=utf-8 [...]
Related posts:<ol>
<li><a href='http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/' rel='bookmark' title='jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well'>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a></li>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Mea culpa: I may owe your fingers an apology.</p>
<p>If you&#8217;ve been using my approach for <a href="http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/">directly calling ASP.NET&#8217;s JSON-based services with jQuery</a>, you know that specifying the correct Content-Type on your requests to them is a crucial part of coaxing JSON out of them.  However, when I suggested that a Content-Type of <code>application/json; charset=utf-8</code> was necessary, that was <em>overly</em> specific.</p>
<h3>Charset=who-cares</h3>
<p>As it turns out, only the <code>application/json</code> portion is necessary.</p>
<p>More accurately, ASP.NET checks that your request&#8217;s Content-Type header <em>begins</em> with <code>application/json</code>.  Beyond that, you can even specify a charset of <em>acrobatic-unicorns</em> and it still works (no, really; I tried).</p>
<p>That may only sound like a minor reduction in typing, but I find that it makes a non-trivial improvement in how memorable the parameter is.  At least for me, the punctuation in <code>; charset=utf-8</code> made that Content-Type string tedious to remember and I would often resort to copy/paste to be sure that it was correct.</p>
<p>It&#8217;s nice to be able to quickly type out an <code>$.ajax()</code> call to your services without tedious memorization, online reference, or copy/paste.</p>
<h3>Bonus: Ditch the dataType</h3>
<p>When I originally wrote about using jQuery with ASP.NET&#8217;s web services, the current jQuery version was 1.2 and jQuery&#8217;s <code>$.ajax()</code> method looked nothing like what it does today.  One of the changes that occurred over the years is that <a href="http://jquery14.com/day-01/jquery-14" target="_blank">jQuery 1.4 added support for parsing responses based on their Content-Type</a>.</p>
<p>Before that addition, it was imperative that you specify a <code>dataType</code> of <code>json</code> if you wanted jQuery to automatically handle converting JSON responses to JavaScript objects.  Beginning with version 1.4, responses with the Content-Type <code>application/json</code> are automatically treated as JSON and parsed accordingly.</p>
<p>Since ASP.NET does set the correct Content-Type on its JSON-serialized responses, manually <strong>specifying a dataType is no longer necessary as long as you&#8217;re using jQuery 1.4 or later</strong>.</p>
<h3>So, what&#8217;s left?</h3>
<p>Eliminating all that dead weight, your AJAX calls to ASMX ScriptServices, Page Methods, and WCF services can now be simplified to this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Service.asmx/Method'</span><span style="color: #339933;">,</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/json'</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">'{&quot;Parameters&quot;:&quot;Must be JSON strings!&quot;}'</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Don't forget that the response is wrapped in a</span>
    <span style="color: #006600; font-style: italic;">//  &quot;.d&quot; object in ASP.NET 3.5 and later.</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>response.<span style="color: #660066;">d</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Sometimes it&#8217;s the little things&#8230;</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/' rel='bookmark' title='jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well'>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a></li>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/">Save yourself some typing when you call ASP.NET services</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Using jQuery 1.6 to find an array of an object&#8217;s keys</title>
		<link>http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/</link>
		<comments>http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 17:22:39 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1125</guid>
		<description><![CDATA[With the confusion surrounding jQuery 1.6&#8242;s changes to .attr() and the addition of .prop(), one of my favorite new features nearly slipped under the radar. The feature I&#8217;m referring to is that $.map() now works against plain JavaScript objects in addition to arrays. $.map() has always been a useful utility method, somewhat mimicking ECMAScript 5&#8242;s [...]
Related posts:<ol>
<li><a href='http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/' rel='bookmark' title='Use jQuery to extract data from HTML lists and tables'>Use jQuery to extract data from HTML lists and tables</a></li>
<li><a href='http://encosia.com/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Use jQuery and ASP.NET AJAX to build a client side Repeater'>Use jQuery and ASP.NET AJAX to build a client side Repeater</a></li>
<li><a href='http://encosia.com/avoid-this-tricky-conflict-between-aspnet-ajax-and-jquery/' rel='bookmark' title='Avoid this tricky conflict between ASP.NET AJAX and jQuery'>Avoid this tricky conflict between ASP.NET AJAX and jQuery</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>With the confusion surrounding jQuery 1.6&#8242;s changes to <code>.attr()</code> and the addition of <code>.prop()</code>, one of my favorite new features nearly slipped under the radar.  The feature I&#8217;m referring to is that <code>$.map()</code> now works against plain JavaScript objects in addition to arrays.</p>
<p><code>$.map()</code> has always been a useful utility method, somewhat mimicking <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map" target="_blank">ECMAScript 5&#8242;s native Array.map() method</a>.  If you&#8217;ve been working with JavaScript long, you&#8217;re probably already comfortable with passing anonymous function callbacks around anyway, which makes higher order functions like map an intuitive way to write <a href="http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/">concise, expressive transformation code</a>.</p>
<p>With jQuery 1.6, now you can use the same approach when working with regular JavaScript objects. There are a variety of uses for this, but I want to focus on one real-world usage in this post: <strong>extracting an array of the keys contained within a JavaScript object</strong>.</p>
<h3>Keys to the kingdom (or at least to an object)</h3>
<p>The question of how to extract a collection of an object&#8217;s keys comes up often.  For example, given an object like this one:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> person <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Dave&quot;</span><span style="color: #339933;">,</span>
               website<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://DaveWard.com&quot;</span><span style="color: #339933;">,</span>
               twitter<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;@Encosia&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>An array of its distinct keys would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> personKeys <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'name'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'website'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'twitter'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That information is useful for a variety of applications, such as building a table header to represent an arbitrary object&#8217;s schema.  It&#8217;s not something you&#8217;ll use on a daily basis, but quite helpful when you do find a need for it.</p>
<p><a href="http://ecma262-5.com/ELS5_HTML.htm#Section_15.2.3.14" target="_blank">ECMAScript 5 actually exposes an Object.keys property</a> to provide exactly that information.  However, ECMAScript 5 is several years away from being cross-browser safe.  For example, <code>Object.keys</code> wasn&#8217;t implemented in Internet Explorer until version 9.  So, that new feature isn&#8217;t terribly useful for most real-world development (yet).</p>
<h3>Using $.map() to emulate Object.keys</h3>
<p>Until we reach the Utopian future of ubiquitous ECMAScript 5 support, jQuery 1.6&#8242;s enhanced map utility provides a syntactically sugary avenue for emulating <code>Object.keys</code> across all browsers.</p>
<p>As map applies its callback function to each property in an object, that function is provided different parameters than the item and index that <code>$.map()</code> has provided in the past. When map is used against an object, <strong>the callback function is passed each property&#8217;s key and value</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> key1<span style="color: #339933;">:</span> <span style="color: #3366CC;">'foo'</span><span style="color: #339933;">,</span> key2<span style="color: #339933;">:</span> <span style="color: #3366CC;">'bar'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Output:</span>
<span style="color: #006600; font-style: italic;">// key1 foo</span>
<span style="color: #006600; font-style: italic;">// key2 bar</span>
$.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>value<span style="color: #339933;">,</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Objects or not, <code>$.map</code> does still return an array consisting of each callback&#8217;s return value.  Now that we know how to reference each object property&#8217;s key name during the callback, building an array of an object&#8217;s keys is simple:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> person <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Dave&quot;</span><span style="color: #339933;">,</span>
               website<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://DaveWard.com&quot;</span><span style="color: #339933;">,</span>
               twitter<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;@Encosia&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// personKeys will contain this JavaScript array after execution:</span>
<span style="color: #006600; font-style: italic;">//  ['name', 'website', 'twitter']</span>
<span style="color: #003366; font-weight: bold;">var</span> personKeys <span style="color: #339933;">=</span> $.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span>person<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>value<span style="color: #339933;">,</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> key<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Nice and easy, isn&#8217;t it?</p>
<p>As always with higher order functions like map, there are iterative alternatives.  However, those iterative approaches only result in more code to accomplish the same task.  Use this functional approach and enjoy!</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/' rel='bookmark' title='Use jQuery to extract data from HTML lists and tables'>Use jQuery to extract data from HTML lists and tables</a></li>
<li><a href='http://encosia.com/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Use jQuery and ASP.NET AJAX to build a client side Repeater'>Use jQuery and ASP.NET AJAX to build a client side Repeater</a></li>
<li><a href='http://encosia.com/avoid-this-tricky-conflict-between-aspnet-ajax-and-jquery/' rel='bookmark' title='Avoid this tricky conflict between ASP.NET AJAX and jQuery'>Avoid this tricky conflict between ASP.NET AJAX and jQuery</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/">Using jQuery 1.6 to find an array of an object&#8217;s keys</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Use jQuery to extract data from HTML lists and tables</title>
		<link>http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/</link>
		<comments>http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 18:25:49 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1085</guid>
		<description><![CDATA[A question that I&#8217;ve been seeing more frequently these days is how to extract a JavaScript object from an HTML list or table, given no data or information other than the markup. It&#8217;s not ideal to work backwards from HTML, but sometimes you just don&#8217;t have a lot of choice in the matter. Whether you&#8217;re [...]
Related posts:<ol>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
<li><a href='http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/' rel='bookmark' title='Using jQuery 1.6 to find an array of an object&#8217;s keys'>Using jQuery 1.6 to find an array of an object&#8217;s keys</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>A question that I&#8217;ve been seeing more frequently these days is how to extract a JavaScript object from an HTML list or table, given no data or information other than the markup. It&#8217;s not ideal to work backwards from HTML, but <strong>sometimes you just don&#8217;t have a lot of choice in the matter</strong>.</p>
<p>Whether you&#8217;re enhancing legacy elements that have been generated on the server-side or want to parse the output of a third-party DHTML widget, there are a variety of situations where converting HTML to raw data is a legitimate need. You may have seen iterative solutions to this problem before. However, nested looping code gets messy fast, doesn&#8217;t feel much like idiomatic jQuery, and certainly isn&#8217;t as concise as you&#8217;d probably like.</p>
<p>Luckily, one of JavaScript&#8217;s lesser-known utility methods and jQuery&#8217;s implementation of it can improve the situation quite a bit. In this post, I&#8217;m going to show you how to use this method, jQuery&#8217;s cross-browser solution, and how to use it to extract data objects from arbitrary HTML lists and tables.</p>
<h3>Array.map()</h3>
<p>It turns out that there&#8217;s a tool perfectly suited to the task of coercing one data structure into another: <strong>map</strong>.</p>
<p><a href="http://en.wikipedia.org/wiki/Map_(higher-order_function)" rel="nofollow" target="_blank">Map is a higher-order function</a> that allows you to transform the contents of a collection by applying a function to each item, capturing the result, and building a new collection of those results.</p>
<p>Map is a perfect tool for translating a collection full of extraneous data into a tightly-focused collection of exactly the desired subset. Even better, <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map" target="_blank">JavaScript 1.6 even includes a native implementation of map</a>, which is exposed as a method on the Array prototype.</p>
<p>For example, this is how you could use JavaScript 1.6&#8242;s Array.map() to analyze an array of strings and create a new array containing each string&#8217;s length:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sites <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Encosia'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'jQuery'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'ASP.NET'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'StackOverflow'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// For each site in the array, apply this function </span>
<span style="color: #006600; font-style: italic;">//  and build an array of the results.</span>
<span style="color: #003366; font-weight: bold;">var</span> lengths <span style="color: #339933;">=</span> sites.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>site<span style="color: #339933;">,</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Use the length of each name as its value in the new array.</span>
  <span style="color: #000066; font-weight: bold;">return</span> site.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This outputs: [7, 6, 7, 13]</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>lengths<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is a very simple example, but you can probably already imagine applying that same technique to an array of list elements or table rows. The concise expressiveness of the map approach is great for paring away extraneous markup and extracting just underlying data.</p>
<h3>Mapping uncharted territory</h3>
<p>Unfortunately, JavaScript 1.6 and its map implementation is not something that you can count on being available in older browsers. Notably, Internet Explorer doesn&#8217;t provide an Array.map() implementation until IE9.</p>
<p>Though that is disappointing, map isn&#8217;t difficult to manually implement.  For example, this is <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map">a polyfill that the MDC recommends for patching Array.map() into older browsers</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">map</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>fun <span style="color: #009966; font-style: italic;">/*, thisp */</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;use strict&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span> <span style="color: #339933;">===</span> <span style="color: #000066; font-weight: bold;">void</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> TypeError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> t <span style="color: #339933;">=</span> Object<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> len <span style="color: #339933;">=</span> t.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> fun <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;function&quot;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> TypeError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> res <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span>len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> thisp <span style="color: #339933;">=</span> arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #000066; font-weight: bold;">in</span> t<span style="color: #009900;">&#41;</span>
        res<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> fun.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>thisp<span style="color: #339933;">,</span> t<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> t<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> res<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That&#8217;s a workable solution, but I doubt you&#8217;re very excited about the prospect of including all this code in your page. I know I wouldn&#8217;t be. </p>
<h4>jQuery has you covered</h4>
<p>If you&#8217;re already including jQuery in your pages, the good news is that jQuery has a built-in map implementation that works in every browser. In fact, jQuery provides two separate map methods: <a href="http://api.jquery.com/map/" target="_blank" rel="nofollow">one that&#8217;s specially suited to working with jQuery selections</a> and <a href="http://api.jquery.com/jQuery.map/" target="_blank" rel="nofollow">a general utility method</a> that&#8217;s more similar to the polyfill shown above.</p>
<p>For working with HTML, I&#8217;m going to focus on using the former: <code>.map()</code>.</p>
<p>To replicate the JavaScript 1.6 dependent example shown earlier, using jQuery&#8217;s implementation instead, the code would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sites <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Encosia'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'jQuery'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'ASP.NET'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'StackOverflow'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Same as before, using jQuery's map() implementation.</span>
<span style="color: #003366; font-weight: bold;">var</span> lengths <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>sites<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">,</span> site<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Use the length of each site name as its value in the new array.</span>
  <span style="color: #000066; font-weight: bold;">return</span> site.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This outputs: [7, 6, 7, 13]</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>lengths<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h4>Making &#8220;this&#8221; approach more concise</h3>
<p>To condense the code a bit, we can take advantage of the execution context within the callback function. During each callback, <code>this</code> holds the value of the array item currently being operated on. So, there&#8217;s no need to bother capturing the callback&#8217;s two input parameters:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> lengths <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>sites<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// &quot;this&quot; refers to the current array element as this callback is</span>
  <span style="color: #006600; font-style: italic;">//  applied to each array element.</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That isn&#8217;t a huge improvement, but every little bit helps and I&#8217;ll be using <code>this</code> in the examples throughout the rest of this post. So, I wanted to make sure what&#8217;s happening there is clear.</p>
<h4>Unwrapping the result of jQuery&#8217;s .map()</h4>
<p>The one quirk when using jQuery&#8217;s <code>.map()</code> method is that it sometimes returns a jQuery wrapped set; specifically, when you apply it to the result of a jQuery DOM selection. Even if your mapping function returns scalar values like strings and numbers, the end result of <code>.map()</code> will include the jQuery object prototype on each element.</p>
<p>That isn&#8217;t really a problem if you only intend to use that result immediately in your JavaScript code. However, the jQuery object prototype hanging off each element throws a wrench in the works if you try to use <code>JSON.stringify()</code> on the result of <code>.map()</code>. Since JSON serialization is such a common task when storing or transmitting JavaScript data, this quirk turns out to be a real issue.</p>
<p>The solution is to call <a href="http://api.jquery.com/get/">jQuery&#8217;s get() method</a> on those wrapped-array results, which boils them down to plain arrays.  When you see <code>.get()</code> tagged onto the end of the examples ahead, that&#8217;s why it&#8217;s there.</p>
<p>Now, let&#8217;s take a look at applying <code>.map()</code> to HTML and using it to extract data.</p>
<h3>Mapping the data within HTML unordered lists</h3>
<p>Using <code>.map()</code> against an unordered list is one of the most straightforward examples to start with. Imagine you had this simple HTML markup:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></span>Item 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></span>Item 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></span>Item 3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul&gt;</span></span></pre></div></div>

<p>To extract each of those items&#8217; displayed value, you could use <code>.map()</code> like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Returns ['Item 1', 'Item 2', 'Item 3']</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'li'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// For each &lt;li&gt; in the list, return its inner text and let .map()</span>
  <span style="color: #006600; font-style: italic;">//  build an array of those values.</span>
  <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Complicating things slightly, maybe the list items also have an HTML5 data- attribute that you need to collect in addition to their values:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li</span> data-<span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;123&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Item 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li</span> data-<span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;456&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Item 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li</span> data-<span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;789&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Item 3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul&gt;</span></span></pre></div></div>

<p>Using <code>.map()</code> to extract that more complex data is just as easy:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Returns [{id: 123, text: 'Item 1'}, </span>
<span style="color: #006600; font-style: italic;">//          {id: 456, text: 'Item 2'},</span>
<span style="color: #006600; font-style: italic;">//          {id: 789, text: 'Item 3'}]</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'li'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// $(this) is used more than once; cache it for performance.</span>
  <span style="color: #003366; font-weight: bold;">var</span> $item <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #006600; font-style: italic;">// Note: using .data() to read HTML5 data- attributes </span>
    <span style="color: #006600; font-style: italic;">//  requires jQuery 1.4.3+. Use attr() in older versions.</span>
    id<span style="color: #339933;">:</span> $item.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
    text<span style="color: #339933;">:</span> $item.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As you can see, <code>.map()</code> is a powerful tool for concisely pulling arbitrary bits of data together into a useful structure. You could certainly do this with a temp variable and for-loop, but <strong>it&#8217;s hard to beat the clean expressiveness this approach lends your code</strong>.</p>
<div class="aside">
<p>There&#8217;s a great JavaScript learning opportunity in the code above, but it&#8217;s on a bit of a tangent.  Rather than let this post run even longer, I wrote about that in a separate post.  If you&#8217;re interested in how an innocuous change to the location of one curly brace in the preceding code can transparently break it, that post is for you.</p>
<p>You can find that post here: <a href="http://encosia.com/2011/03/21/in-javascript-curly-brace-placement-matters-an-example/">In JavaScript, curly brace placement matters: An example</a>.</p>
</div>
<h3>Extracting data from HTML tables</h3>
<p>Working with the lists is good for a simple example, but what if we need to apply this technique to an HTML structure that&#8217;s more complex than an unordered list?</p>
<p>HTML tables are one of the most common targets for this technique. It&#8217;s not unusual to end up with a pre-rendered table that was generated off-page and to desire a client-side data structure representing that table&#8217;s data.</p>
<p>For example, here&#8217;s a tabular representation of the same data contained in the second list example:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myTable&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;thead&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;th&gt;</span></span>id<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/th&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;th&gt;</span></span>text<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/th&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/thead&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tbody&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>123<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>Item 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>456<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>Item 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>789<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>Item 3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tbody&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span></pre></div></div>

<p>If you wanted to boil that table down to exactly the same JavaScript object shown in the second list example, this <code>.map()</code> usage would do the trick:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Returns [{id: 123, text: 'Item 1'}, </span>
<span style="color: #006600; font-style: italic;">//          {id: 456, text: 'Item 2'},</span>
<span style="color: #006600; font-style: italic;">//          {id: 789, text: 'Item 3'}]</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myTable tbody tr'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// $(this) is used more than once; cache it for performance.</span>
  <span style="color: #003366; font-weight: bold;">var</span> $row <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// For each row that's &quot;mapped&quot;, return an object that</span>
  <span style="color: #006600; font-style: italic;">//  describes the first and second &lt;td&gt; in the row.</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
    id<span style="color: #339933;">:</span> $row.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':nth-child(1)'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    text<span style="color: #339933;">:</span> $row.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':nth-child(2)'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The key to making this approach work is using the <code>:nth-child</code> selector to index into each row and retrieve the contents of the cells we&#8217;re interested in. This is very similar to how we handled the unordered list earlier, but can be applied to arbitrarily large structures such as wide HTML tables.</p>
<p>If you use this approach, one thing to <strong>keep in mind is that <code>:nth-child</code> uses one-based indexing</strong>. So, you must use <code>:nth-child(1)</code> to select the first cell, not <code>:nth-child(0)</code> as you might expect.</p>
<h3>A general solution for tables</h3>
<p>Using hard coded <code>:nth-child</code> selectors works well enough in simple scenarios, but it&#8217;s brittle. If the table structure changes, relying on a certain table layout will break. Hard coding the selectors for each column also becomes tedious when dealing with wider tables that have many columns.</p>
<p>So, as you apply this technique to larger or less predictable tables, <strong>you may desire a more general solution for extracting the data</strong>. One way of doing that is using the table&#8217;s column heading cells to build a basic schema of the table&#8217;s data.</p>
<p>Assuming your table has a proper <code>&lt;thead&gt;</code>, this is how you could extract an array of its column headings to use as a schema for mapping the rest of the table&#8217;s data:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> columns <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myTable thead th'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// This assumes that your headings are suitable to be used as</span>
  <span style="color: #006600; font-style: italic;">//  JavaScript object keys. If the headings contain characters </span>
  <span style="color: #006600; font-style: italic;">//  that would be invalid, such as spaces or dashes, you should</span>
  <span style="color: #006600; font-style: italic;">//  use a regex here to strip those characters out.</span>
  <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>With that column list handy, we can determine which column <em>name</em> any cell in the table should be filed under, given nothing more than its index in the row. Now we can automate the process that previously required those <code>:nth-child</code> selectors:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> tableObject <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myTable tbody tr'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Find all of the table cells on this row.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Determine the cell's column name by comparing its index</span>
    <span style="color: #006600; font-style: italic;">//  within the row with the columns list we built previously.</span>
    <span style="color: #003366; font-weight: bold;">var</span> rowName <span style="color: #339933;">=</span> columns<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add a new property to the row object, using this cell's</span>
    <span style="color: #006600; font-style: italic;">//  column name as the key and the cell's text as the value.</span>
    row<span style="color: #009900;">&#91;</span>rowName<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Finally, return the row's object representation, to be included</span>
  <span style="color: #006600; font-style: italic;">//  in the array that $.map() ultimately returns.</span>
  <span style="color: #000066; font-weight: bold;">return</span> row<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Don't forget .get() to convert the jQuery set to a regular array.</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That&#8217;s it.</p>
<p>With all the comments, that looks like more work than it actually is.  Eleven lines of code for the entire ordeal isn&#8217;t bad considering that it will automatically handle the majority of tables you throw at it.</p>
<h3>Conclusion</h3>
<p>I&#8217;m going to stop here, before this gets any longer. I hope that you found this helpful and/or interesting.</p>
<p>Even if you don&#8217;t often convert HTML markup to JavaScript objects, do keep <code>.map()</code> in mind when you&#8217;re working with collections of any type.  When you need it, the notion of map is an extremely useful aspect of JavaScript&#8217;s functional nature, but often goes overlooked.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
<li><a href='http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/' rel='bookmark' title='Using jQuery 1.6 to find an array of an object&#8217;s keys'>Using jQuery 1.6 to find an array of an object&#8217;s keys</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/">Use jQuery to extract data from HTML lists and tables</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>A VSDoc for jQuery 1.5</title>
		<link>http://encosia.com/a-vsdoc-for-jquery-1-5/</link>
		<comments>http://encosia.com/a-vsdoc-for-jquery-1-5/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 19:46:09 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1088</guid>
		<description><![CDATA[I’ve noticed several people looking for a jQuery 1.5 VSDoc this week. After looking around myself, I didn&#8217;t see one anywhere either. So, I updated Damian Edwards’ VsDocBuilder for jQuery 1.5 and generated a new VSDoc. It doesn’t handle the new jqXHR and Deferred return types quite right, so you won’t get Intellisense for the [...]
Related posts:<ol>
<li><a href='http://encosia.com/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border: 1px solid #ccc;" alt="Using the jQuery 1.5 VSDoc to get Intellisense in Visual Studio" src="http://encosia.com/blog/wp-content/uploads/2011/02/jQuery-1.5-vsdoc-in-action.png" width="490" height="155" /></p>
<p>I’ve noticed several people looking for a jQuery 1.5 VSDoc this week. After looking around myself, I didn&#8217;t see one anywhere either. So, I updated <a href="http://damianedwards.wordpress.com/2011/01/27/jquery-vsdoc-file-generator/">Damian Edwards’ VsDocBuilder</a> for jQuery 1.5 and generated a new VSDoc.</p>
<p>It doesn’t handle the new jqXHR and Deferred return types quite right, so you won’t get Intellisense for the new chained <code>$.ajax()</code> callbacks. However, it should be better than nothing until a fully functioning version is released.</p>
<p><strike>You can download it here: jQuery-1.5.0-vsdoc.js</strike></p>
<p><strong>Update</strong>: Damian has just made a fully functional version of the 1.5 VSDoc available (that was quick): <a href="http://damianedwards.com/files/jquery/jquery-1.5-vsdoc.js" target="_blank">jquery-1.5-vsdoc.js</a>. You should use his instead of mine.</p>
<p><em>Important</em>: This new VSDoc makes use of &lt;para&gt; tags to display line breaks inside documentation tooltips.  To view them properly, you&#8217;ll need to be sure that you have <a href="http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed/" target="_blank" rel="nofollow">the JScript Editor Extensions</a> installed so that Visual Studio understands those new VSDoc tags.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/a-vsdoc-for-jquery-1-5/">A VSDoc for jQuery 1.5</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/a-vsdoc-for-jquery-1-5/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/a-vsdoc-for-jquery-1-5/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</title>
		<link>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/</link>
		<comments>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 16:24:57 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1086</guid>
		<description><![CDATA[jQuery 1.5&#8242;s complete overhaul of the AJAX API has led to several people contacting me recently, understandably nervous about how the rewrite will impact working with ASMX ScriptServices and ASPX page methods. Seeing the default calling syntax change to $.ajax(url, settings) was especially unsettling to many. I&#8217;m happy to report that the short answer is: [...]
Related posts:<ol>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>jQuery 1.5&#8242;s complete overhaul of the AJAX API has led to several people contacting me recently, understandably nervous about how the rewrite will impact working with ASMX ScriptServices and ASPX page methods.  Seeing the default calling syntax change to <code>$.ajax(url, settings)</code> was especially unsettling to many.</p>
<p>I&#8217;m happy to report that the short answer is: <strong>jQuery 1.5&#8242;s new AJAX module has almost no negative impact on any of the techniques you may have read about here</strong>.  The rewrite maintains very good compatibility for the <code>$.ajax(settings)</code> calling syntax and for now-deprecated features such as dataFilters.</p>
<p>One advanced dataFilter usage appears to be broken, but it&#8217;s something that you probably already stopped using with jQuery 1.4. To be clear, I&#8217;ll briefly enumerate all of the techniques I&#8217;ve re-tested and jQuery 1.5&#8242;s impact (or lack thereof) on each.</p>
<h3>ASMX ScriptServices and ASPX page methods</h3>
<p>The most common way of using jQuery to communicate with an ASP.NET WebForms application today is to use an ASMX ScriptService or ASPX page method. If you&#8217;re <a href="http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/">requesting an ASMX ScriptService using the approach I originally described</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/YourService.asmx/YourMethod&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;json&quot;</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">d</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That code will continue to work exactly as-is with jQuery 1.5. If you prefer <a href="http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/">page methods</a> instead, you&#8217;re in the clear too.</p>
<p><em>Note: You can simplify the contentType parameter to &#8220;application/json&#8221; when using any version. The ScriptService handler only checks that the header contains &#8220;application/json&#8221;, not for an exact string match. It&#8217;s a small improvement, but noticeably easier to remember and type.</em> </p>
<h3>DTOs and JSON.stringify()</h3>
<p>If you&#8217;re using jQuery and ASP.NET JSON endpoints to accomplish more complicated tasks, you may be <a href="http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/">using JSON.stringify() to simplify making requests that include data transfer objects</a>. Paired with corresponding complex types or collections on the server-side, this approach seems almost too good to be true:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> NewPerson <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
NewPerson.<span style="color: #660066;">FirstName</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#FirstName&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">LastName</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#LastName&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">Address</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Address&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">City</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#City&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">State</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#State&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">Zip</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Zip&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> DTO <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">'Person'</span> <span style="color: #339933;">:</span> NewPerson <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;PersonService.asmx/AddPerson&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> JSON.<span style="color: #660066;">stringify</span><span style="color: #009900;">&#40;</span>DTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;json&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>jQuery 1.5&#8242;s AJAX rewrite has not impacted that technique either.  If you provide a string value for its <code>data</code> parameter, jQuery will pass that string on to the server unmodified.</p>
<h3>dataFilters and &#8220;.d&#8221;</h3>
<p>With jQuery 1.5 fundamentally revamping <code>$.ajax()</code>&#8216;s extensibility model, the technique of <a href="http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/">using a dataFilter to normalize ASP.NET&#8217;s &#8220;.d&#8221; wrapper</a> is what I worried most about surviving the 1.5 transition. That approach looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajaxSetup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span><span style="color: #339933;">,</span>
  dataFilter<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">hasOwnProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'d'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg.<span style="color: #660066;">d</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'YourService.asmx/YourMethod'</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// You'll never have to worry about the response being </span>
    <span style="color: #006600; font-style: italic;">//  buried in response.d here.</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Though jQuery 1.5&#8242;s new <a href="http://api.jquery.com/extending-ajax/#Converters">converters</a> will probably enable a better solution, this dataFilter approach does continue to work in jQuery 1.5.</p>
<h3>dataFilters and JSON parsing</h3>
<p>While the simple dataFilter does work, if you&#8217;re <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">using a dataFilter to implement custom JSON parsing</a>, you may need to make a small change.  What I mean by that is code like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Your usual $.ajax() URL, data, dataType, etc.</span>
  dataFilter<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #339933;">&amp;&amp;</span> 
        <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">return</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> data <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The usefulness of that approach dates back to jQuery 1.3 and earlier, when jQuery exclusively used <code>eval()</code> for deserializing JSON responses.  At that time, it was helpful to manually override the deserialization process to take advantage of browser-native implementations of <code>JSON.parse()</code> when available.  Doing so yielded both performance and security gains.</p>
<p>In jQuery 1.4, this was no longer necessary because jQuery contained a similar bit of browser-native parser testing code itself.  However, the dataFilter approach above did continue to work in jQuery 1.4 $.ajax() requests, so long as the dataType for the request was either omitted or set to a value that didn&#8217;t trigger jQuery&#8217;s automatic JSON deserialization (e.g. &#8220;text&#8221; or &#8220;foo&#8221;).</p>
<p>As of jQuery 1.5, <strong>using this dataFilter approach for manually controlling deserialization will no longer work if the request&#8217;s dataType is set to &#8220;json&#8221; or even omitted</strong>.</p>
<p>Except for the most obscure of edge cases, the best solution is simply to drop this code.  It&#8217;s redundant if you&#8217;re using jQuery 1.4.0 or later.  Again though, you <em>can</em> continue using a dataFilter to handle the &#8220;.d&#8221; issue.</p>
<h3>Conclusion</h3>
<p>For the most part, upgrading to jQuery 1.5 is a non-issue when it comes to using <code>$.ajax()</code> with ASP.NET JSON endpoints. Considering the fundamental nature of the module&#8217;s rewrite, it really is commendable how well backwards compatibility has been maintained.</p>
<p>Once you&#8217;ve vetted your existing code for compatibility with jQuery 1.5, do be sure to check out the powerful new features that have been added to <code>$.ajax()</code> in this rewrite.  Its new extension points, <a href="http://api.jquery.com/extending-ajax/#Prefilters">prefilters</a>, <a href="http://api.jquery.com/extending-ajax/#Converters">converters</a>, and <a href="http://api.jquery.com/extending-ajax/#Transports">transports</a>, will offer finer-grained control than ever before.</p>
<p>Even more exciting is the AJAX rewrite&#8217;s inclusion of &#8220;deferreds&#8221;.  You can count on seeing more about that here soon, but right now I highly recommend taking a look at <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/">this post by Eric Hynds</a>.</p>
<p>If you&#8217;ve tested jQuery 1.5 in your own sites/projects, I&#8217;m curious if you&#8217;ve run into any issues I didn&#8217;t address.  Please do leave a comment if I&#8217;ve missed anything that caused you trouble in the upgrade.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/">jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Cripple the Google CDN&#8217;s caching with a single character</title>
		<link>http://encosia.com/cripple-the-google-cdns-caching-with-a-single-character/</link>
		<comments>http://encosia.com/cripple-the-google-cdns-caching-with-a-single-character/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 17:18:30 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1078</guid>
		<description><![CDATA[It&#8217;s no secret that I&#8217;m a proponent of using a shared CDN to host jQuery. As more and more sites take advantage of public CDNs for their jQuery reference, the cross-site caching benefit is becoming almost a given. However, there are a couple ways that even I recommend against using these public CDNs. With the [...]
Related posts:<ol>
<li><a href='http://encosia.com/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='3 reasons why you should let Google host jQuery for you'>3 reasons why you should let Google host jQuery for you</a></li>
<li><a href='http://encosia.com/6953-reasons-why-i-still-let-google-host-jquery-for-me/' rel='bookmark' title='6,953 reasons why I still let Google host jQuery for me'>6,953 reasons why I still let Google host jQuery for me</a></li>
<li><a href='http://encosia.com/do-you-know-about-this-undocumented-google-cdn-feature/' rel='bookmark' title='Do you know about this undocumented Google CDN feature?'>Do you know about this undocumented Google CDN feature?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret that I&#8217;m a proponent of <a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/" target="_blank">using a shared CDN to host jQuery</a>. As more and more sites take advantage of public CDNs for their jQuery reference, the cross-site caching benefit is becoming almost a given. However, there are a couple ways that even I recommend <em>against</em> using these public CDNs.</p>
<p>With the impending <a href="http://blog.jquery.com/2010/12/30/hotlinking-to-be-disabled-on-jan-31-2011/" target="_blank">policy change on hotlinking copies of jQuery hosted on jQuery.com</a>, I expect that at least several sites will be migrating their hotlinked script references to one of the public CDNs soon. So, I think this is a good time to address one CDN-related usage mistake that I&#8217;ve seen an uptick in lately.</p>
<h3>Firesheep and SSL</h3>
<p>By now, you&#8217;ve probably heard about last year&#8217;s release of <a href="http://codebutler.com/firesheep" rel="nofollow" target="_blank">Firesheep</a>, a Firefox addon that sniffs out HTTP session cookies transmitted in cleartext, and the turmoil that it caused. Seeing someone hijack a stranger&#8217;s Twitter or Facebook identity with a single click is enough to make anyone more conscious about the security of their browsing habits.</p>
<p>Traditionally, most sites have used encrypted connections for authentication and sensitive information, to avoid transmitting passwords or private data in cleartext, but they generally avoid forcing SSL connections on most other pages. This lack of site-wide support is usually attributed to the (perceived) server-side overhead of encrypting every connection and the tedious mixed content warnings that browsers display when HTTPS pages contain references to unencrypted content.</p>
<p>However, with SSL certificates available for cheaper than ever, Firesheep having raised so much awareness, and the prevalent use of unsecured WiFi networks in public settings, many sites have responded by offering SSL encryption for pages on their entire sites.</p>
<p>Unfortunately, this recent proliferation of SSL usage has at least one performance drawback that isn’t necessary obvious at first glance.</p>
<h3>HTTPS and mixed content</h3>
<p>To ensure airtight security, <strong>pages served via SSL should contain no references to content served through unencrypted connections</strong>. The reasoning behind this rule is sound. After all, the browser has no way of knowing whether an image contains a chart with sensitive financial data or if a JavaScript include contains a JSON collection detailing the user&#8217;s medical history.</p>
<p>Different browsers react to mixed HTTP and HTTPS content with varying degrees of severity, with Internet Explorer being the most hostile, but every browser displays some type of warning by default. If you&#8217;re curious about how your browser handles the situation, navigate to <a href="https://encosia.com" target="_blank">https://encosia.com</a>.</p>
<p>Visiting my site via HTTPS retrieves the page’s content via a legitimately secured connection, encrypted with a valid SSL certificate. The catch is that its HTML contains insecure references to content such as CSS and images, which triggers the dreaded mixed content warning. The result is especially painful in Internet Explorer:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/01/ie-mixed-content.png" width="492" height="232" /></p>
<p>It’s obvious why avoiding the mixed content warning is an absolute necessity for any serious public-facing site. </p>
<h3>An obvious solution</h3>
<p>In cases where a given page may potentially be served via either HTTP or HTTPS, path-relative URLs can be used to automatically choose the right protocol for on-site content. For example, references such as <code>/images/foo.png</code> and <code>/css/bar.css</code> will automatically adapt to the correct protocol based on what was used to load the underlying document containing them.</p>
<p>Utilizing off-site resources like advertisements, third-party widgets, and CDN hosted libraries can be a bit more frustrating though. Because their fully qualified URLs specify a protocol, it’s easy to run afoul of the mixed content rule when pages are available through both HTTP and HTTPS protocols. Even a single, innocuous HTTP reference is enough to completely break a page served via HTTPS.</p>
<p>Since the inverse case &#8211; secure references on an unsecured page &#8211; isn’t subject to any obvious penalties, a common solution is to simply use HTTPS exclusively when linking to off-site resources that support it. On the secure pages, the HTTPS reference avoids a mixed content warning, and it still appears to work fine on HTTP pages as well. On sites where a given page might be viewed using either HTTP or HTTPS, assuming HTTPS can be the quickest, easiest remedy to the mixed content problem.</p>
<p>Unfortunately, that approach is burdened by a significant performance drawback on unsecured pages, which may not be readily apparent.</p>
<h3>SSL == Super Slow Loading?</h3>
<p>Using the secure reference everywhere seems like a workable solution, but there&#8217;s a major problem with over-using SSL for cacheable, static resources (such as jQuery). For the same reasons that browsers require those assets to be encrypted in the first place, most browsers default to not caching files to disk if they’ve been retrieved via SSL.</p>
<p>Worse, even if the user has a locally cached copy of jQuery sitting on disk that was requested from Google’s CDN via HTTP, their browser will not utilize that local copy when it encounters an HTTPS reference to the same resource on the same server.</p>
<p>In other words, this URL:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js</pre></div></div>

<p>Is entirely different than the following one, as far as a browser is concerned, thus the two are not subject to <a href="http://encosia.com/2010/09/15/6953-reasons-why-i-still-let-google-host-jquery-for-me/" target="_blank">the sizable cross-caching benefit that comes with using Google’s CDN</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js</pre></div></div>

<p>The result is that using <strong>HTTPS references to Google’s CDN will result in under-optimized caching when used on regular HTTP pages</strong>. Though you must use secure reference on pages that are secure themselves, you should <em>avoid</em> HTTPS references on pages that don’t require them.</p>
<p><em>Update:</em> As several people have pointed out, the Google CDN does serve its assets with a Cache-Control header that allows most browsers to cache its copies of jQuery to disk. However, that doesn&#8217;t help mitigate the cross-site caching issue. A local copy that was originally requested via HTTP cannot be used as a cache hit when the browser later encounters an HTTPS reference to the same file (and vice versa). Two separate copies of the file will be stored and each treated as distinct resources.</p>
<h3>A better solution</h3>
<p>It&#8217;s not exactly light reading, but <a href="http://tools.ietf.org/html/rfc3986#section-4.2" target="_blank" rel="nofollow">section 4.2 of RFC 3986</a> provides for fully qualified URLs that omit protocol (the HTTP or HTTPS) altogether. When a URL’s protocol is omitted, the browser uses the underlying document&#8217;s protocol instead. </p>
<p>Put simply, these &#8220;protocol-less&#8221; URLs allow a reference like this to work in every browser you&#8217;ll try it in:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js</pre></div></div>

<p>It looks strange at first, but <strong>this &#8220;protocol-less&#8221; URL is the best way to reference third party content that&#8217;s available via both HTTP and HTTPS</strong>.</p>
<p>On a page loaded through regular, unencrypted HTTP, script references using that URL will be loaded via HTTP and be cached as normal. Likewise, on a secure page that was loaded via HTTPS, script references targeting that protocol-less URL will automatically load the script from Google&#8217;s CDN via HTTPS and avoid the mixed content warning.</p>
<p>Thus, <strong>using the protocol-less URL allows a single script reference to adapt itself to what&#8217;s most optimal</strong>: HTTP and it&#8217;s full caching support on HTTP pages, and HTTPS on secured pages so that your users aren&#8217;t confronted with a mixed content warning.</p>
<h3>Conclusion</h3>
<p>I probably could have boiled this post down to a couple of sentences, but I hope you found the underlying “why” useful. Just saying that SSL resources aren’t cached isn’t nearly as interesting as understanding why, and how that relates to the mixed content issue.</p>
<p>Perhaps a big part of the problem is that <a href="http://code.google.com/apis/libraries/devguide.html#jquery" target="_blank">the Google AJAX Libraries developer guide</a> was recently updated to list only HTTPS URLs. Anyone who copy/pastes one of those URLs into their script reference without knowing better will be impacted by the loss of disk caching and cross-site caching, which is unfortunate. If anyone reading this has the right contacts, <strong>it would be great if that page could be updated to display the protocol-less URL for all of those libraries instead</strong>.</p>
<p>I hope if you see someone using a fixed HTTPS reference to a resource like jQuery on the Google CDN, you’ll point them here and hopefully help speed up the web just a tiny bit for everyone.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='3 reasons why you should let Google host jQuery for you'>3 reasons why you should let Google host jQuery for you</a></li>
<li><a href='http://encosia.com/6953-reasons-why-i-still-let-google-host-jquery-for-me/' rel='bookmark' title='6,953 reasons why I still let Google host jQuery for me'>6,953 reasons why I still let Google host jQuery for me</a></li>
<li><a href='http://encosia.com/do-you-know-about-this-undocumented-google-cdn-feature/' rel='bookmark' title='Do you know about this undocumented Google CDN feature?'>Do you know about this undocumented Google CDN feature?</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/cripple-the-google-cdns-caching-with-a-single-character/">Cripple the Google CDN&#8217;s caching with a single character</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/cripple-the-google-cdns-caching-with-a-single-character/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/cripple-the-google-cdns-caching-with-a-single-character/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>jQuery Templates, composite rendering, and remote loading</title>
		<link>http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/</link>
		<comments>http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 18:40:27 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1069</guid>
		<description><![CDATA[In my last post about jQuery Templates, I showed you how to use template composition to build a template out of simple sub-templates. These composite templates are a great way to address the complexity that creeps into real-world UIs, as they inevitably grow and become more intricate. However, one feature missing from my last example [...]
Related posts:<ol>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/composition-with-jquery-templates-why-and-how/' rel='bookmark' title='Composition with jQuery Templates: Why and How'>Composition with jQuery Templates: Why and How</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In my last post about jQuery Templates, I showed you how to use template composition to build a template out of simple sub-templates. These composite templates are a great way to address the complexity that creeps into real-world UIs, as they inevitably grow and become more intricate. However, <strong>one feature missing from my last example was the ability to store those composite templates in external files and load them asynchronously for rendering</strong>.</p>
<p>I&#8217;ve described how to accomplish that with single templates in the past, using jQuery&#8217;s AJAX utilities and a particular usage of <code>tmpl()</code>. Unfortunately, remotely loading a group of composite templates from a single file is not quite as simple, and the technique I&#8217;ve described previously will not work.</p>
<p>Not to worry though, it&#8217;s still relatively easy.</p>
<p>In this post, I&#8217;ll show you how to move a group of composite templates to an external file, how to load and render them with jQuery Templates, and how to take advantage of an expected benefit to improve separation of concerns.</p>
<p><strong>Caution:</strong> <em>If you haven&#8217;t read my previous posts about <a href="http://encosia.com/2010/10/05/using-external-templates-with-jquery-templates/" target="_blank">remotely loading jQuery Templates definitions</a> and <a href="http://encosia.com/2010/11/10/composition-with-jquery-templates-why-and-how/" target="_blank">using {{tmpl}} to achieve template composition</a>, read them before continuing with this post.  I&#8217;m not going to cover that material again here, and this may not make much sense without those prerequisites.</em></p>
<h3>Moving the templates to an external file</h3>
<p>Breaking the invoice template apart helped make it more approachable and maintainable, but I don&#8217;t like leaving the template embedded in the page&#8217;s markup. The larger a single file becomes, the more difficult it is to understand and work with &#8211; especially over time.</p>
<p>Disentangling chunks of the presentation tier and moving them to separate files is a great way to attack the problem of bloated pages and views. We&#8217;ve been doing that since the beginning of the web, from seemingly-ancient techniques like <a href="http://en.wikipedia.org/wiki/Server_Side_Includes" rel="nofollow" target="_blank">SSI includes</a>, to file includes in scripting frameworks like ASP and PHP, to partial views in MVC frameworks. So, why stop now just because the templates are rendered in the browser?</p>
<p>Moving the previous example&#8217;s template definitions to a separate file is as simple as it sounds. Just take the invoice template and both its row templates, script wrappers included, and move them into a new file of your choosing. I&#8217;m going to move them to a file named <strong>_invoice.tmpl.htm</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Tip: It's safe to use HTML comments in the file --&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Invoice container template --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoiceTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoice&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  {{each lineItems}}
    {{tmpl($value) get_invoiceRowTemplateName(type)}}
  {{/each}}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Invoice row templates --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;serviceRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;service&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${service}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;itemRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;item&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${item}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${description}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${qty}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<h3>Naming the template file</h3>
<p>If you&#8217;re wondering why I chose that somewhat convoluted filename for the template, I&#8217;ll explain:</p>
<p>Ideally, I would like to call the template something like invoiceTemplate.tmpl, but most popular web servers refuse to serve files with non-standard extensions by default. You can circumvent that with a bit of manual configuration, but it&#8217;s not worth the unending hassle of extra configuration work on every server and/or site where you use this technique. So, .tmpl is out.</p>
<p>I really liked <a href="http://encosia.com/2010/10/05/using-external-templates-with-jquery-templates/#comment-40029">Nathan Smith&#8217;s suggestion for a naming compromise</a> on my previous post about remote loading, which boils down to this:</p>
<ul>
<li>Prefix the filename with an underscore. This denotes a partial view in many modern view engines and is a useful convention for indicating that the file is not a valid/complete HTML document.</li>
<li>Nathan suggested following _templateName with .tpl, to indicate that it&#8217;s a template. I&#8217;m going to tweak that slightly and use .tmpl, so it&#8217;s more clear that the template is intended for use with jQuery Templates.</li>
<li>The file should end in .htm, to be sure the file will be readily served up under almost any web server&#8217;s default configuration. Using .htm or another text/html extension also improves the odds that the template definitions will be served with appropriate compression and caching.</li>
</ul>
<p>The first two are just suggestions, of course. You can use any arbitrary naming scheme you prefer and the approach described in this post will still work fine.</p>
<p><strong>I do recommend sticking with an .htm or .html extension though</strong>. I (stubbornly) went through the configuration hassle of using .tpl <a href="http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/">when I was originally working with jTemplates&#8217; remote loading feature a couple years ago</a>, and eventually had to give up on it. The ongoing configuration hassles ultimately outweighed the benefit of a uniquely descriptive extension.</p>
<h3>Loading and rendering the template</h3>
<p>With the templates moved to an external file, we need a way to load and render them. As I mentioned earlier, the approach I&#8217;ve previously described for remote template loading isn&#8217;t viable in this scenario. Treating the external file as a simple template string only works if the file contains a <em>single</em> template definition and no extraneous markup. Our file fails on both counts.</p>
<p>Another disadvantage my previous approach is caching. When you render a string-based template, jQuery Templates doesn&#8217;t cache the compiled template. If you end up rendering the same template more than once per pageview, the string-based approach was slower than it could have been.</p>
<p>To solve both those issues, we can use jQuery to load the contents of the template file, inject all of it into the document, and then work with the templates as if they had been embedded in the page all along.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// The invoice object to render (see previous post).</span>
<span style="color: #003366; font-weight: bold;">var</span> invoice <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  invoiceItems<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'item'</span><span style="color: #339933;">,</span> 
      part<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99Designs'</span><span style="color: #339933;">,</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99 Designs Logo'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">450.00</span><span style="color: #339933;">,</span> qty<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'service'</span><span style="color: #339933;">,</span>
      service<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Web development and testing'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">25000.00</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'item'</span><span style="color: #339933;">,</span>
      part<span style="color: #339933;">:</span> <span style="color: #3366CC;">'LinodeMonthly'</span><span style="color: #339933;">,</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Monthly site hosting'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">40.00</span><span style="color: #339933;">,</span> qty<span style="color: #339933;">:</span> <span style="color: #CC0000;">12</span> <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Asynchronously load the template definition file.</span>
$.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'_invoice.tmpl.htm'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>templates<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Inject all those templates at the end of the document.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>templates<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Select the newly injected invoiceTemplate and use it</span>
  <span style="color: #006600; font-style: italic;">//  render the invoice data.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#invoiceTemplate'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">tmpl</span><span style="color: #009900;">&#40;</span>invoice<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Injecting the template definitions into the page&#8217;s markup allows you to render them with the same <code>$('#templateId').tmpl(data)</code> syntax that you&#8217;ve seen in most jQuery Templates examples.</p>
<h3>Bringing the row template resolver along for the ride</h3>
<p>One remaining annoyance is the now-orphaned row template name resolver, <code>get_invoiceRowTemplateName()</code> (covered in <a href="http://encosia.com/2010/11/10/composition-with-jquery-templates-why-and-how/">my composite template post</a>). Keeping that function with the rest of the page&#8217;s JavaScript does work, but I&#8217;m not happy with it. To get the full benefit of encapsulating the template in an external file, we should keep any dependent JavaScript code with the template itself.</p>
<p>That&#8217;s especially true if the template is used from more than one page.</p>
<p>As it turns out, accomplishing that is much easier than it may seem at first. All we need to do is move the resolver function right into _invoice.tmpl.htm:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Invoice container template --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoiceTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoice&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  {{each lineItems}}
    {{tmpl($value) get_invoiceRowTemplateName(type)}}
  {{/each}}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Invoice row templates --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;serviceRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;service&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${service}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;itemRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;item&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${item}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${description}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${qty}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- This function is used by the invoice container to determine --&gt;</span></span>
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!--  which row template to render for a given line item --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  function get_invoiceRowTemplateName(type) {
    // Return a template selector that matches our 
    //  convention of <span style="color: #009900;">&lt;type&gt;</span>RowTemplate.
    return '#' + type + 'RowTemplate';
  }
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<p>When you inject markup into the DOM, browsers will immediately parse and evaluate that markup just as they do during the initial page load &#8211; including any JavaScript code in the markup. Since browsers do this in the same single-thread that they execute JavaScript, <strong>it&#8217;s safe to assume that embedded functions are available immediately after the markup has been injected</strong>.</p>
<p>It seems almost too good to be true, like one of those handy techniques that works in every browser except some version of IE. However, embedding the supporting function inside the template file works in every browser I&#8217;ve tested, even including the full complement of JavaScript-enabled options on <a href="http://browsershots.org/" target="_blank" rel="nofollow">BrowserShots.org</a>.</p>
<h3>Conclusion</h3>
<p>I&#8217;ve been using this exact technique in production for about a month now. I initially came up with several approaches, but wanted to try them in real-world code before I recommended one. I&#8217;m happy to report that this has been working great for me so far. I hope you&#8217;ll find it helpful too.</p>
<p>One caveat is that you should be careful about loading and injecting the external template more than once. Injecting multiple copies of the template definitions over and over actually doesn&#8217;t break the rendering process in browsers I&#8217;ve tested, but it will unecessarily impact performance as the DOM grows larger with every new injection.</p>
<p>I&#8217;m going to cover that and another templating concurrency issue soon, but if you want a head start: test <code>$.template('#templateName')</code> to determine whether a particular template is already loaded and cached.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/composition-with-jquery-templates-why-and-how/' rel='bookmark' title='Composition with jQuery Templates: Why and How'>Composition with jQuery Templates: Why and How</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/">jQuery Templates, composite rendering, and remote loading</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
		<item>
		<title>Composition with jQuery Templates: Why and How</title>
		<link>http://encosia.com/composition-with-jquery-templates-why-and-how/</link>
		<comments>http://encosia.com/composition-with-jquery-templates-why-and-how/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 21:26:12 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1064</guid>
		<description><![CDATA[I doubt anyone was happier than I was to see that support for composite template rendering was added to jQuery Templates during the interim between the first community proposal and its recent release. If you&#8217;re a regular reader, you might remember that I personally lobbied for that functionality back in May, based on how I’ve [...]
Related posts:<ol>
<li><a href='http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/' rel='bookmark' title='jQuery Templates, composite rendering, and remote loading'>jQuery Templates, composite rendering, and remote loading</a></li>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I doubt anyone was happier than I was to see that support for composite template rendering was added to jQuery Templates during the interim between the first community proposal and its recent release. If you&#8217;re a regular reader, you might remember that <a href="http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/#template-composition" target="_blank">I personally lobbied for that functionality back in May</a>, based on how I’ve used <a href="http://jtemplates.tpython.com/doc/symbols/Include.html" target="_blank" rel="nofollow">jTemplates’ similar #include feature</a>.</p>
<p>Since then, a common question I’ve received amounts to: “Great, but why?”</p>
<p>I think that&#8217;s natural, because template composition is one of those things that can seem obscure until you put it to work for the first time. From that point onward, you’ll begin to see the structure of your client-side templates in a different light. Simplifying your templates into smaller logical parts and then combining those parts to create the desired end result is a powerful approach. It&#8217;s terrific for making large templates more approachable and maintainable over the lifetime of an application.</p>
<p>In this post, I want to show you an example of a scenario that template composition is well suited to, a couple ways that jQuery Templates&#8217; {{tmpl}} feature can be used to simplify that scenario, and a bonus advantage that the composition approach provides even after the template has been rendered.</p>
<h3>An example scenario: The invoice</h3>
<p>Imagine that you need to display an invoice for a company that resells taxable items and also sells services. Ideally, the invoice line items for those separate &#8220;types&#8221; should be displayed with different markup. To explore a simple example of that, let’s create a template to render the invoice for a fictional web development company.</p>
<p>Whether retrieved from a server-side endpoint or embedded in the page during initial rendering, the underlying data for that invoice might be structured something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> invoice <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  invoiceItems<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'item'</span><span style="color: #339933;">,</span> 
      part<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99Designs'</span><span style="color: #339933;">,</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99 Designs Logo'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">450.00</span><span style="color: #339933;">,</span> qty<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'service'</span><span style="color: #339933;">,</span>
      service<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Web development and testing'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">25000.00</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'item'</span><span style="color: #339933;">,</span>
      part<span style="color: #339933;">:</span> <span style="color: #3366CC;">'LinodeMonthly'</span><span style="color: #339933;">,</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Monthly site hosting'</span><span style="color: #339933;">,</span> 
      price<span style="color: #339933;">:</span> <span style="color: #CC0000;">40.00</span><span style="color: #339933;">,</span> qty<span style="color: #339933;">:</span> <span style="color: #CC0000;">12</span> <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Following from that data structure, our goal for the invoice’s markup might look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>99Designs<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>99 Designs Logo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>$450.00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Web development and testing<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>$25,000.00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>LinodeMonthly<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>Monthly hosting at Linode<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>$40.00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>12<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span></pre></div></div>

<p>Notice that the markup for service and item rows is structurally different, to better represent the underlying data. When that’s desirable, composing sub-templates is the way to go. As we’ll see next, the alternative is unappealing.</p>
<h3>The old fashioned way</h3>
<p>The key to our goal of rendering different markup for services and items is to render different template code depending on the line item&#8217;s <code>type</code> property.</p>
<p>Of course, it’s possible to achieve that without using template composition. The <code>{{if}}</code> template tag allows you to concoct just about any conditional rendering scheme that you can image. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;invoiceTemplate&quot;</span> type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;x-jquery-tmpl&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>table <span style="color: #003366; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;invoice&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span>each invoiceItems<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">if</span> type <span style="color: #339933;">==</span> <span style="color: #3366CC;">'service'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
      <span style="color: #339933;">&lt;</span>tr <span style="color: #003366; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;service&quot;</span><span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td colspan<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;2&quot;</span><span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span>service<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td colspan<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;2&quot;</span><span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span>price<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>          
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">else</span> type <span style="color: #339933;">==</span> <span style="color: #3366CC;">'item'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
      <span style="color: #339933;">&lt;</span>tr <span style="color: #003366; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;item&quot;</span><span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span>description<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span>price<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>$<span style="color: #009900;">&#123;</span>qty<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>          
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span><span style="color: #339933;">/</span><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span><span style="color: #339933;">/</span>each<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>That works, but it’s a mess.</p>
<p>Even with only two types of items, the template is already fairly difficult to read and digest. Just imagine if there were a dozen item types instead of only two. Bundling all the templates together would quickly become a maintenance nightmare.</p>
<p>Wouldn&#8217;t it be nice if we could separate the row templates and define them individually? The <code>{{tmpl}}</code> template tag allows us to do just that.</p>
<h3>Reorganizing the template for composition</h3>
<p>First, we need to separate the template into a container and individual row templates for each line item <code>type</code>. The container will be rendered once for every invoice, and the row templates as dictated by the underlying data.</p>
<p>In this case, the container template will simply begin and end our <code>&lt;table&gt;</code>. In a real-world template, this is where you might also include a <code>&lt;thead&gt;</code> with column headings.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoiceTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoice&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Composition magic goes here! --&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<p>The row templates are straightforward, extracted from the combined template we looked at in the last section:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;serviceRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;service&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${service}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td</span> <span style="color: #000066;">colspan</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;itemRowTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tr</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;item&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${item}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${description}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${price}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;td&gt;</span></span>${qty}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/tr&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<p>Note that the templates have IDs that correspond to the <code>type</code> they&#8217;re designed to render. That will come in handy a bit later.</p>
<h3>Template composition with jQuery Templates</h3>
<p>Now, it&#8217;s finally time to add that composition magic to the container template. jQuery Templates has a special template tag which provides for rendering and composing nested templates: <code>{{tmpl}}</code>.</p>
<p>The <code>{{tmpl}}</code> tag has several usages (<a href="http://api.jquery.com/template-tag-tmpl/" target="_blank" rel="nofollow">documentation</a>), but the one I want to focus on is the one that accepts a selector as its <em>template</em> parameter. When a selector is specified, jQuery Templates locates the indicated template, renders it, and then replaces the <code>{{tmpl}}</code> token with that rendered markup.</p>
<p>The <code>{{tmpl}}</code> command also accepts a parameter specifying what data the sub-template should be rendered with. Including the template selector, the command will look like this: <code>{{tmpl(dataItem) "#TemplateID"}}</code>.</p>
<p>Putting that all together, this container template will use each item&#8217;s <code>type</code> to render the item with the appropriate row template:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoiceTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoice&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    {{each invoiceItems}}
      {{if type == 'service'}}
        {{tmpl($value) '#serviceRowTemplate'}}
      {{else type == 'item'}}
        {{tmpl($value) '#itemRowTemplate'}}
      {{/if}}
    {{/each}}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<p>If you aren&#8217;t familiar with <code>{{each}}</code> and its $value pseudo variable, all you need to know is that it contains the current iteration&#8217;s data item. It&#8217;s the same value that you would normally capture as the second parameter to an $.each() callback. In fact, <code>{{each}}</code> can also be used in that fashion instead:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoiceTemplate&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x-jquery-tmpl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;invoice&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    {{each(i, item) invoiceItems}}
      {{if type == 'service'}}
        {{tmpl(item) '#serviceRowTemplate'}}
      {{else type == 'item'}}
        {{tmpl(item) '#itemRowTemplate'}}
      {{/if}}
    {{/each}}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></pre></div></div>

<p>I prefer using the pseudo variable since it&#8217;s more concise, but both are equivalent.</p>
<p>For now, we’re still stuck with the <code>{{if}}</code> to determine which row template to render, but getting the row templates out of that conditional block has cleaned things up quite a bit. Don’t worry if the conditional strikes you as a distasteful remnant of the original approach. We’ll fix that soon.</p>
<h3>Rendering the composite template</h3>
<p>Having defined the container template and its sub-templates, using jQuery Templates to render the entire group is just as easy as rendering a single template. Assuming the same <code>invoice</code> variable as seen before:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#invoiceTemplate'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">tmpl</span><span style="color: #009900;">&#40;</span>invoice<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As far as we know at the time we render the container, nothing has changed (and that&#8217;s part of the point), yet the refactored template is going to be quite a bit easier to understand and maintain.</p>
<h3>Unconditional rendering love</h3>
<p>Now that the templates are separated, things are a lot cleaner than before. However, that remnant <code>{{if}}</code> block is still a bit irritating. If you end up with more than just a couple item types, the conditional will require ongoing maintenance and cruft up the template badly.</p>
<p>Instead of that explicit testing and branching to pick the right template, we can clean things up by automatically searching for a row template that matches our naming convention of <em>type</em>RowTemplate. To do that, we just need to build a JavaScript function that takes a <code>type</code> parameter and returns the appropriate selector string:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> get_invoiceRowTemplateName<span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Return a template selector that matches our </span>
  <span style="color: #006600; font-style: italic;">//  convention of &lt;type&gt;RowTemplate.</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> type <span style="color: #339933;">+</span> <span style="color: #3366CC;">'RowTemplate'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Updating the container template to use our new function completely eliminates that <code>{{if}}</code> block:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;invoiceTemplate&quot;</span> type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;x-jquery-tmpl&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>table <span style="color: #003366; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;invoice&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span>each lineItems<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span>tmpl<span style="color: #009900;">&#40;</span>$value<span style="color: #009900;">&#41;</span> get_invoiceRowTemplateName<span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span><span style="color: #339933;">/</span>each<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Now, adapting to new item types is as simple as creating an appropriately named template. Convention over configuration, as they say.</p>
<h3>Bonus: Rendering additional line items</h3>
<p>Cleaning up the template is a good enough reason alone to use template composition, but the benefits extend beyond the initial rendering process. A nice side-effect of the compositional approach is that it&#8217;s easy to render additional rows even after the template has been rendered.</p>
<p>It&#8217;s easy to imagine that we might need to let users add new items to our invoice after it has been displayed. Assuming the invoice is already rendered, adding a matching row to it is as easy as this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> newItem <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'service'</span><span style="color: #339933;">,</span>
  service<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Service with a smile'</span><span style="color: #339933;">,</span>
  price<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.00</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Determine which template should be used to render the new item.</span>
<span style="color: #003366; font-weight: bold;">var</span> tmpl <span style="color: #339933;">=</span> get_invoiceRowTemplateName<span style="color: #009900;">&#40;</span>newItem.<span style="color: #660066;">type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Render that template, using the new item as data,</span>
<span style="color: #006600; font-style: italic;">//  and append that new row to the end of the existing invoice table.</span>
$<span style="color: #009900;">&#40;</span>tmpl<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">tmpl</span><span style="color: #009900;">&#40;</span>newItem<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#table.invoice'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That&#8217;s cleaner, easier, and faster than the common alternatives of cloning an existing row, building the HTML manually, or completely re-rendering the entire table with updated data.</p>
<p>Perhaps more importantly, it centralizes your presentation code. When changes only need to be made once, in a single location, you are guaranteed to see less bugs over time.</p>
<h3>Conclusion</h3>
<p>I&#8217;ve been using this compositional approach with jTemplates for a couple years now, and I cannot overstate how helpful it is when you&#8217;re working on real-world apps with large, complex client-side templates. I do hope you&#8217;ll give it a try in your own projects, because I know you won&#8217;t be disappointed.</p>
<p>Kudos to everyone who worked on jQuery Templates and helped {{tmpl}} see its way into the first release. I think it&#8217;s an excellent implementation of the feature &#8211; certainly easier to use and understand than jTemplates&#8217; #include.</p>
<p>An important piece of the puzzle that&#8217;s still missing at this point is a technique for storing these composite template groups in an external file and loading them asynchronously, as with <a href="http://encosia.com/2010/10/05/using-external-templates-with-jquery-templates/">single templates in my last post</a>. Unfortunately, the simplistic approach in my previous post doesn&#8217;t work with composite templates. However it&#8217;s still very easily doable. I&#8217;ll cover that next, so stay tuned.</p>
<p>What do you think? Are you using template composition already? If not, have I managed to entice you to give it a try?</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/jquery-templates-composite-rendering-and-remote-loading/' rel='bookmark' title='jQuery Templates, composite rendering, and remote loading'>jQuery Templates, composite rendering, and remote loading</a></li>
<li><a href='http://encosia.com/using-external-templates-with-jquery-templates/' rel='bookmark' title='Using external templates with jQuery Templates'>Using external templates with jQuery Templates</a></li>
<li><a href='http://encosia.com/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/composition-with-jquery-templates-why-and-how/">Composition with jQuery Templates: Why and How</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/composition-with-jquery-templates-why-and-how/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/composition-with-jquery-templates-why-and-how/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
	</channel>
</rss>

