<?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>Wed, 01 Sep 2010 15:51:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Hear me talk jQuery and ASP.NET on the jQuery Podcast</title>
		<link>http://encosia.com/2010/08/30/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/</link>
		<comments>http://encosia.com/2010/08/30/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 15:10:36 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1045</guid>
		<description><![CDATA[Last week, Ralph Whitbeck was kind enough to have me as a guest on episode #32 of the jQuery Podcast. We spoke about topics including: Research I’ve done on the public CDNs that host jQuery, and why it matters which one you choose Why you should never use a &#34;latest version&#34; reference to scripts on [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/08/30/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/">Hear me talk jQuery and ASP.NET on the jQuery Podcast</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/06/20/hear-me-talk-about-jquery-on-the-polymorphic-podcast/' rel='bookmark' title='Permanent Link: Hear me talk about jQuery on the Polymorphic Podcast'>Hear me talk about jQuery on the Polymorphic Podcast</a></li>
<li><a href='http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/' rel='bookmark' title='Permanent Link: Mastering jQuery now available at TekPub'>Mastering jQuery now available at TekPub</a></li>
<li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://podcast.jquery.com/2010/08/27/episode-32-dave-ward/" target="_blank"><img style="margin-left: 5px; float: right;" alt="The jQuery Podcast logo" align="left" src="http://encosia.com/blog/wp-content/uploads/2010/08/jquerypodcast.png" width="170" height="170" /></a>Last week, <a href="http://ralphwhitbeck.com/" target="_blank">Ralph Whitbeck</a> was kind enough to have me as a guest on episode #32 of the jQuery Podcast. We spoke about topics including:</p>
<ul>
<li>Research I’ve done on the public CDNs that host jQuery, and why it matters which one you choose</li>
<li>Why you should never use a &quot;latest version&quot; reference to scripts on those public CDNs </li>
<li>The drawbacks of always waiting on $(document).ready()</li>
<li>My video tutorial series, Mastering jQuery</li>
</ul>
<p>I really enjoyed talking with Ralph, and I think the episode turned out great. You can listen to it at: <a href="http://podcast.jquery.com/2010/08/27/episode-32-dave-ward/">http://podcast.jquery.com/2010/08/27/episode-32-dave-ward/</a></p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/08/30/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/">Hear me talk jQuery and ASP.NET on the jQuery Podcast</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/06/20/hear-me-talk-about-jquery-on-the-polymorphic-podcast/' rel='bookmark' title='Permanent Link: Hear me talk about jQuery on the Polymorphic Podcast'>Hear me talk about jQuery on the Polymorphic Podcast</a></li>
<li><a href='http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/' rel='bookmark' title='Permanent Link: Mastering jQuery now available at TekPub'>Mastering jQuery now available at TekPub</a></li>
<li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/08/30/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t let jQuery&#8217;s $(document).ready() slow you down</title>
		<link>http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/</link>
		<comments>http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 17:26:56 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1038</guid>
		<description><![CDATA[A couple examples of situations where jQuery's $(document).ready() may be unnecessarily slowing you down.<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/">Don&#8217;t let jQuery&#8217;s $(document).ready() slow you down</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/03/25/document-ready-and-pageload-are-not-the-same/' rel='bookmark' title='Permanent Link: $(document).ready() and pageLoad() are not the same!'>$(document).ready() and pageLoad() are not the same!</a></li>
<li><a href='http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='Permanent Link: 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/2008/08/20/easily-build-powerful-client-side-ajax-paging-using-jquery/' rel='bookmark' title='Permanent Link: Easily build powerful client-side AJAX paging, using jQuery'>Easily build powerful client-side AJAX paging, using jQuery</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>jQuery&#8217;s $(document).ready() event is something that you probably learned about in your earliest exposure to jQuery and then rarely thought about again.  The way it abstracts away DOM timing issues is like a warm security blanket for code running in a variety of cold, harsh browser windows.</p>
<p>Between that comforting insurance and the fact that deferring everything until $(document).ready() will never break your code, it&#8217;s understandable not to give much thought to its necessity. Wrapping $(document).ready() around initialization code becomes more habit than conscious decision.</p>
<p>However, <strong>what if $(document).ready() is slowing you down?</strong> In this post, I&#8217;m going show you specific instances where postponing startup code until the document&#8217;s ready event slows perceived page load time, could leave your UI needlessly unresponsive, and even causes initialization code to run slower than necessary.</p>
<h3>Example: live()</h3>
<p>One of the most popular uses for <a href="http://api.jquery.com/live/" rel="nofollow" target="_blank">jQuery’s live()</a> is to maintain event handlers on elements that are dynamically created and destroyed over time. Instead of juggling traditional bind() handlers in response to those changes, live()&#8217;s event delegation allows you to declare handlers once up-front. Whether targeted elements exist at declaration time, <em>or in the future</em>, one live() handler will apply to them all.</p>
<p>Imagine that we have an application with several <a href="http://api.jquery.com/slideToggle/" target="_blank" rel="nofollow">slideToggling</a> sidebar blocks which may be dynamically added and removed while the user interacts with the page.  You&#8217;ve probably seen live() used like this to simplify handling those future changes:</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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- The sidebar event delegation is not registered &quot;here&quot;... --&gt;</span></span>
    $(document).ready(function () {
      $('#Sidebar h3').live('click', function () {
        $(this).next().slideToggle();
      });
    });
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Sidebar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></span>Title 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Text 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></span>Title 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Text 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- ...but roughly down &quot;here&quot; --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<p>That usage is natural when you&#8217;re hedging against AJAX-driven changes in the future. The volatility that you&#8217;re concerned with won&#8217;t happen until after the page loads, so it&#8217;s intuitive to postpone worrying about them until after the document&#8217;s ready event.</p>
<p>However, what would happen if you treated your HTML document’s initial load process the same way as any other dynamic modifications?</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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- The event handler is wired up &quot;here&quot;; immediately --&gt;</span></span>
    $('#Sidebar h3').live('click', function () {
      $(this).next().slideToggle();
    });
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Sidebar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></span>Title 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- At this point, Title 1 is ready for action. --&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Text 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></span>Title 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Ditto for Title 2 at this point --&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Text 2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<p>Not only does that work just as well as postponing the live() declaration until the document’s ready event, but <strong>now the handlers are active during the page loading process</strong>. As the browser loads each &lt;h3&gt; element and adds it to the DOM, our click events are immediately ready to be handled.</p>
<h4>Benefit: A more responsive UI</h4>
<p>To see where the latter approach shines, imagine the page was very large and took several seconds to load, or that a script reference somewhere on the page was timing out. In scenarios like those, <strong>jQuery’s document ready event may not fire until considerably later than the targeted elements are visible to your users</strong>.</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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- The event handler is wired up &quot;here&quot;; immediately --&gt;</span></span>
    $('#Sidebar h3').live('click', function () {
      $(this).next().slideToggle();
    });
&nbsp;
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- This handler isn't active until... --&gt;</span></span>
    $(document).ready(function() {
      $('#Sidebar p').live('click', function() {
        // Important magic goes here.
      });
    });
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Sidebar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></span>Title 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Text 1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://twitter.com/fail-whale.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</span>
&nbsp;
  <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- ...way down here, *after* the script references times out. --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<p>Why hold live() back until the document is ready? It doesn’t matter if the selector matches any elements initially; they will immediately become active as they are rendered and appear on the page.</p>
<h4>Benefit: Improved performance</h4>
<p>A common criticism of using live() for event delegation is that it requires you to perform an initial selection of all of the elements that it targets. Since event delegation doesn’t require any initial setup on each individual element, this pre-selection is a wasteful performance drag when there are dozens or hundreds of elements targeted.</p>
<p>However, if you register your live() handlers before those elements exist on the page, there is no performance penalty whatsoever. The event delegation can be registered very quickly, yet still works exactly the same as if you had waited until the ready event.</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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Fast. Runs before any of the TRs exist. --&gt;</span></span>
    $('#MyTable tr').live('click', function () {
      $(this).toggleClass('highlight');
    });
&nbsp;
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Slow. Doesn't run until the table is rendered. --&gt;</span></span>
    $(document).ready(function() {
      $('#MyTable tr').live('click', function () {
        $(this).toggleClass('highlight');
      });
    });
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&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: #060; font-style: italic;">&lt;!-- Hundreds or thousands of rows 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;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<h3>Example: $.ajax()</h3>
<p>Another situation where $(document).ready() may be holding you back is when you make an AJAX request immediately as a page is loading. Displaying recent Twitter updates is a common example of that:</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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    $(document).ready(function() {
      <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- $.getJSON() request to retrieve Twitter updates. --&gt;</span></span>
    });
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
  <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- A typically large page here --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- The Twitter request doesn't *begin* until here. --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<p>Even though the $.getJSON() snippet is located at the beginning of the page, it isn&#8217;t executed until the entire page has loaded and the ready event has fired. <strong>Why wait until the page is loaded in order to begin the AJAX request?</strong></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;html&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&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: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>script&gt;</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>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- $.getJSON() request to retrieve Twitter updates. --&gt;</span></span>
    <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- The request begins immediately. --&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
  <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- A typically large page here --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span></pre></div></div>

<p>This is a nice improvement even when you&#8217;re making a request to a local endpoint, but is even more beneficial here because third-party requests circumvent the browser&#8217;s per-domain request limit. That third-party request to Twitter runs in parallel with the rest of the page&#8217;s normal loading timeline.</p>
<p>Better yet, since the dynamic script element injection used in a JSONP request is asynchronous, there&#8217;s no drawback to initiating the request early. Even if Twitter is slow or down (imagine that), the request won&#8217;t drag the page down.</p>
<h4>Benefit: Performance</h4>
<p>To show you a visualization of how the previous two approaches differ, I used my own site as a guinea pig.  First, I wrapped a $.getJSON() request to Twitter in $(document).ready() and placed it in the &lt;head&gt; of my site template.</p>
<p>This is how the site loads in that configuration, taken from Firebug&#8217;s Net tab:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2010/08/waiting-on-document-ready.png" width="490" height="275" style="border: 1px solid #ccc;" /></p>
<p>Now, here&#8217;s the same $.getJSON() request, located in the same position in the &lt;head&gt; of the page, but without the $(document).ready() wrapper:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2010/08/without-waiting-on-document-ready.png" width="490" height="275" style="border: 1px solid #ccc;" /></p>
<p><strong>We just pulled a bit of performance right out of thin air.</strong>  This isn&#8217;t simply perceived performance, which is nice enough, but a truly faster overall load time.</p>
<p><em>Note: You might notice that the ready event came later in the second example and be concerned that it was due to the early $.getJSON() request.  It wasn&#8217;t.  If you look closely, a blocking &lt;script&gt; reference to one of the page&#8217;s local scripts took unusually long in the second run, which pushed everything back about 700ms longer than usual.</em></p>
<h3>Conclusion</h3>
<p>I think the preceding examples are compelling, but I&#8217;m also not suggesting that this is appropriate in every case. Often, it’s best to move every bit of JavaScript to the bottom of your pages (e.g. a public-facing, non-application site like this one). When your scripts are located at the bottom of the page, it doesn’t matter whether you use $(document).ready() or not; everything is effectively running when the document ready event fires anyway.</p>
<p>However, when you’re building the type of script-heavy “application” that behooves your placing script references in the document’s &lt;head&gt;, keeping these ideas in mind can have a tangible impact on the performance of your application.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/">Don&#8217;t let jQuery&#8217;s $(document).ready() slow you down</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/03/25/document-ready-and-pageload-are-not-the-same/' rel='bookmark' title='Permanent Link: $(document).ready() and pageLoad() are not the same!'>$(document).ready() and pageLoad() are not the same!</a></li>
<li><a href='http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='Permanent Link: 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/2008/08/20/easily-build-powerful-client-side-ajax-paging-using-jquery/' rel='bookmark' title='Permanent Link: Easily build powerful client-side AJAX paging, using jQuery'>Easily build powerful client-side AJAX paging, using jQuery</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Sometimes, even jQuery can&#8217;t save you from yourself</title>
		<link>http://encosia.com/2010/07/08/sometimes-even-jquery-cant-save-you-from-yourself/</link>
		<comments>http://encosia.com/2010/07/08/sometimes-even-jquery-cant-save-you-from-yourself/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 04:05:06 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1020</guid>
		<description><![CDATA[This post describes a cross-browser problem I had with jQuery that turned out to be my own fault, including a runthrough of debugging process and the eventual solution.<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/07/08/sometimes-even-jquery-cant-save-you-from-yourself/">Sometimes, even jQuery can&#8217;t save you from yourself</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Permanent Link: 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/2009/06/09/11-keystrokes-that-made-my-jquery-selector-run-10x-faster/' rel='bookmark' title='Permanent Link: 11 keystrokes that made my jQuery selector run 10x faster'>11 keystrokes that made my jQuery selector run 10x faster</a></li>
<li><a href='http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='Permanent Link: 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 recently encountered what appeared to be a cross-browser issue with jQuery, which was both surprising and frustrating. After all, eliminating those cross-browser inconsistencies is no small part of jQuery’s fundamental appeal.</p>
<p>After some investigation, the source of the trouble actually stemmed from an oversight on my part. I doubt that many of you will have to deal with exactly the same situation, but the lessons I learned may apply to cross-browser jQuery problems you encounter in the future.</p>
<h3>Tables all the way down</h3>
<p>It all started with a relatively simple HTML table template being <a href="http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/">rendered on the client-side via jTemplates</a>. The rendered markup looked 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;thead&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;th&gt;</span></span>Part Number<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>Description<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>Quantity<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;/thead&gt;</span></span>
&nbsp;
  <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>Item1<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>Item1 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>4<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>
&nbsp;
    <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>Item2<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>Item2 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>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;/tbody&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span></pre></div></div>

<p>A series of these tables would be rendered in chronological order, one per invoice.</p>
<h3>The bit of jQuery in question</h3>
<p>Once those tables were rendered, the user often needed to trigger an action on <strong>the first row</strong> of <strong>the last table</strong>. The action itself isn&#8217;t relevant, but one important detail is that it blocked interaction with the rest of the page until its workflow was complete.</p>
<p>Glancing at the markup, the selector to accomplish that seemed simple enough:</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;">'table:last tr:first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">triggerSomeAction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Nice, simple, and it worked great. We tested it thoroughly, got user-approval, and I moved on to other features.</p>
<p>Unfortunately, that single line of jQuery would come back to haunt me later.</p>
<h3>IE failed me?  It&#8217;s always IE!</h3>
<p>Originally, I was fortunate enough that all this application’s users were using recent versions of Firefox. Since all my development took place in Firefox too (<a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/" target="_blank">you still can&#8217;t beat Firebug</a>), the application received very little cross-browser testing.</p>
<p>Over time, the application became a victim of its own success. It worked so well that other departments began to adopt it too; <strong>departments with Internet Explorer users</strong>. All of the IE users were using IE8, so that wasn&#8217;t as bad as it could have been, but it brought an interesting cross-browser problem to my attention.</p>
<p>The problem was that the bit of code which called triggerSomeAction() on the first row of the last table wasn&#8217;t working right in IE. Worse yet, <strong>it was still locking the interface though</strong>. IE users were unable to complete that bit of the workflow and remained locked out of the invoices once that action had been triggered.</p>
<p>I cursed IE, out of habit, and went to work debugging the issue.</p>
<h3>Nope, I had failed myself</h3>
<p>Tracing through the code, <strong>it seemed like the selector was finding the &lt;thead&gt; row instead of the first row of the table body</strong>. That didn’t make much sense at first, but then I inspected the rendered markup side-by-side in both Firebug and IE’s developer tools:</p>
<p><img style="border: 1px solid #000;" alt="Comparing the rendered DOM in Firebug and IE's Developer Tools" src="http://encosia.com/blog/wp-content/uploads/2010/07/composite.png" width="490" height="293" /></p>
<p>See the difference?</p>
<p>Firefox had been rendering the table’s markup exactly as given, even though <a href="http://www.w3.org/TR/html401/struct/tables.html#h-11.2.3" rel="nofollow" target="_blank">omitting a &lt;thead&gt;’s &lt;tr&gt; isn’t valid markup</a>, but <strong>IE tried to fix my mistake by inserting the missing &lt;tr&gt;</strong>. In fact, this behavior isn&#8217;t unique to IE. Chrome and Safari both do the same thing that IE does with that particular malformation.</p>
<p>Because jQuery’s selectors act on the DOM itself, not the raw HTML that was originally fed to the browser, this “help” was changing the result of my jQuery selector. Selecting <code>tr:first</code> was actually returning the row of &lt;th&gt; elements in every browser other than Firefox.</p>
<p>I stopped cursing IE and began cursing myself.</p>
<h3>The fix</h3>
<p>The fix was simple enough. I changed the selector to be more precise:</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;">'table:last tbody tr:first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">triggerSomeAction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That fixed the immediate problem.  Then, I corrected the template’s missing &lt;tr&gt; for good measure.</p>
<h3>What I learned</h3>
<p>Validating HTML has a reputation as something only obsessive purists do, but <strong>Validating you HTML is a useful tool</strong>. It’s <a href="http://en.wikipedia.org/wiki/Lint_(software)" rel="nofollow" target="_blank">lint</a> for your HTML. I’m often lax about validating internal-only sites, but doing that would have helped me avoid this problem before it happened.</p>
<p>If a jQuery selector seems inconsistent across browsers, <strong>inspect the DOM in those browsers</strong>. It’s not safe to assume that every browser will interpret your markup as its written. Thankfully, most browsers now include tools suitable for doing so.</p>
<p>If you think you&#8217;ve &#8220;found a problem&#8221; with a mature library like jQuery, <a href="http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html" target="_blank">blame yourself first</a>.  I should have known better than to <a href="http://twitter.com/Encosia/status/15447745980" target="_blank" rel="nofollow">think there was a problem with jQuery</a> in such a common scenario.</p>
<h3>And you?</h3>
<p>I hope that having watching my mistake unfold in slow-motion will help you if you run into a similar issue in the future.  Even better, maybe it will help you avoid the problem in the first place!</p>
<p>Do you have a similar story?  What are the cross-browser issues you&#8217;ve run into when using jQuery?</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/07/08/sometimes-even-jquery-cant-save-you-from-yourself/">Sometimes, even jQuery can&#8217;t save you from yourself</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Permanent Link: 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/2009/06/09/11-keystrokes-that-made-my-jquery-selector-run-10x-faster/' rel='bookmark' title='Permanent Link: 11 keystrokes that made my jQuery selector run 10x faster'>11 keystrokes that made my jQuery selector run 10x faster</a></li>
<li><a href='http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/' rel='bookmark' title='Permanent Link: A few thoughts on jQuery templating with jQuery.tmpl'>A few thoughts on jQuery templating with jQuery.tmpl</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/07/08/sometimes-even-jquery-cant-save-you-from-yourself/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>A few thoughts on jQuery templating with jQuery.tmpl</title>
		<link>http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/</link>
		<comments>http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/#comments</comments>
		<pubDate>Mon, 03 May 2010 05:57:00 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=991</guid>
		<description><![CDATA[I spent some quality time with Dave Reed’s latest revision of John Resig&#8217;s jQuery.tmpl plugin recently, migrating a small project from jTemplates. Since both the jQuery team and Microsoft team have requested feedback on jQuery.tmpl, I decided to write about my experience using it (as I am wont to do with these templating proposals). Overall, [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/">A few thoughts on jQuery templating with jQuery.tmpl</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/07/23/sneak-peak-aspnet-ajax-4-client-side-templating/' rel='bookmark' title='Permanent Link: A sneak peak at ASP.NET AJAX 4.0&#8242;s client-side templating'>A sneak peak at ASP.NET AJAX 4.0&#8242;s client-side templating</a></li>
<li><a href='http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Permanent Link: 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/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Permanent Link: Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I spent some quality time with <a href="http://github.com/nje/jquery-tmpl" target="_blank">Dave Reed’s latest revision of John Resig&#8217;s jQuery.tmpl plugin</a> recently, migrating a small project from jTemplates. Since both the jQuery team and Microsoft team have requested feedback on jQuery.tmpl, I decided to write about my experience using it (<a href="http://encosia.com/2008/07/23/sneak-peak-aspnet-ajax-4-client-side-templating/">as I am wont to do with these templating proposals</a>).</p>
<p>Overall, jQuery.tmpl is a great step in the right direction. It’s small, it’s simple, and it’s fast. Overloading append() to allow the append(Template, Data) syntax is phenomenal. <strong>That approach feels more like idiomatic jQuery than anything else I’ve used</strong>, including jTemplates.</p>
<p>However, if this template rendering engine is going to succeed broadly, I feel there’s one important feature still missing. Additionally, there are a couple ancillary features that <em>are</em> present in the current proposal, but should be protected.</p>
<h3>Composition</h3>
<p>One area where jTemplates still comes out on top is template composition – also known as nested templates. Specifically, this refers to the ability for templates to contain references to other templates, and the ability to render that entire group as a whole.</p>
<p>The need for template composition may be hard to see in simple examples, but <strong>most non-trivial scenarios benefit from template composition</strong>. <a href="http://twitter.com/InfinitiesLoop/status/13254392072" rel="nofollow" target="_blank">Dave mentioned the example</a> of having a person template that embeds a separate template for displaying information on one or more phone entries about those person records.</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2010/05/heterogeneous-item-templates.png" style="margin-left: 5px;" align="right" />That’s a good example, but take it one more step to understand where composition really shines. Consider the possibility that each of those phone records has a type (e.g. Mobile, Home, or Work) and that each type must be presented with different markup.</p>
<p>Template composition provides a clean solution to this problem. By creating separate templates for each type and then rendering the correct amalgamation of those templates, the template code remains simple (but is powerful).</p>
<h3>A composition workaround in jQuery.tmpl</h3>
<p>Currently, something resembling nested item templates are technically possible via the <em>each</em> keyword in jQuery.tmpl, but it’s not pretty. This example from <a href="http://github.com/nje/jquery-tmpl/blob/master/demo.html" rel="nofollow" target="_blank">the jQuery.tmpl demo</a> illustrates that approach:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Data</span>
cities<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;Boston, MA&quot;</span><span style="color: #339933;">,</span>
          <span style="color: #3366CC;">&quot;San Francisco, CA&quot;</span> <span style="color: #009900;">&#93;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Template</span>
Cities<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#123;</span>each<span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span>city<span style="color: #009900;">&#41;</span> cities<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>$<span style="color: #009900;">&#123;</span>city<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></pre></div></div>

<p>Even for this most simple case, the syntax is rough. Not the sort of readable simplicity that we’ve come to expect from jQuery. </p>
<p>More importantly, extending that to conditionally render different fragments of markup would be much more difficult.</p>
<h3>A cleaner workaround (but it’s a trap!)</h3>
<p><a href="http://github.com/nje/jquery-tmpl/blob/master/demo.html" rel="nofollow" target="_blank">The jQuery.tmpl demo</a> also contains this seemingly elegant alternative:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Data</span>
cityJoin<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;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">cities</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;, &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
cities<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
  <span style="color: #3366CC;">&quot;Boston, MA&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;San Francisco, CA&quot;</span>
<span style="color: #009900;">&#93;</span></pre></div></div>

<p>By embedding a function in the data, referencing that object key in a template returns the <em>result</em> of the cityJoin function. Thus, jQuery.tmpl renders the function’s result, not the function declaration’s actual text.</p>
<p>That technique dramatically simplifies the template itself:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Template</span>
Cities<span style="color: #339933;">:</span> $<span style="color: #009900;">&#123;</span>cityJoin<span style="color: #009900;">&#125;</span></pre></div></div>

<p>While that approach does succeed in avoiding the messy template code that <em>each</em> requires, it tightly couples concerns which should not be.</p>
<p>When this is put into practical use, the data object will usually be requested from the server-side. <strong>Would my business logic or data repository tier need to inject the joining function?</strong> I don’t think I could bring myself to do that.</p>
<p>Further, it doesn’t really address the real-world scenarios I’ve encountered. A callback function to format data won’t feasibly scale to rendering heterogeneous chunks of markup. Effectively, it’s the same as the <em>each</em> solution, with the pain point shuffled around a bit.</p>
<h3>How I think it should work</h3>
<p>As long as there’s <em>some</em> way to name and render sub-templates, <strong>I don’t care how exactly it works</strong>.</p>
<p>I wasn’t crazy about jTemplates’ {#include} syntax at first, but it’s okay once you get used to it. Most any syntax shouldn’t be difficult to learn and acclimate to.</p>
<p>Since jQuery.tmpl already provides for caching the templates in jQuery.templates, all that’s really necessary is a method for rendering those named templates within other templates.</p>
<h3>A concrete example</h3>
<p>This example simplified a bit, but is functionally similar to client work I come across regularly. To be clear, <strong>this is something I’m currently using today, not something I’m just theorizing as a good idea</strong>.</p>
<p>I want to be able to take data that isn&#8217;t necessarily homogeneously structured:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>InvoiceItems<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
  <span style="color: #009900;">&#123;</span> ItemType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Product'</span><span style="color: #339933;">,</span>
    PartNumber<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99-Designs-Logo'</span><span style="color: #339933;">,</span>
    Description<span style="color: #339933;">:</span> <span style="color: #3366CC;">'99 Designs Logo design'</span><span style="color: #339933;">,</span>
    TotalCost<span style="color: #339933;">:</span> <span style="color: #CC0000;">450</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#123;</span> ItemType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Service'</span><span style="color: #339933;">,</span>
    DescriptionOfWork<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Website development&quot;</span><span style="color: #339933;">,</span>
    TotalCost<span style="color: #339933;">:</span> <span style="color: #CC0000;">5000</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#123;</span> ItemType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Service'</span><span style="color: #339933;">,</span>
    DescriptionOfWork<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Deployment and testing&quot;</span><span style="color: #339933;">,</span>
    TotalCost<span style="color: #339933;">:</span> <span style="color: #CC0000;">300</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>And use a set of templates like this to render that data (did I get the <em>each</em> syntax right in #Invoice?):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{#ServiceItem}
<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>{$DescriptionOfWork}<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>{$TotalCost}<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>
&nbsp;
{#ProductItem}
<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>{$PartNumber}<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>{$TotalCost}<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>
&nbsp;
{#Invoice}
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table&gt;</span></span>
  <span style="color: #009900;">&lt;-- Fancy thead here --<span style="color: #000000; font-weight: bold;">&gt;</span></span>
  {{each(i, InvoiceItem) InvoiceItems}}
    {{if $InvoiceItem.ItemType === 'Service'}}
      {{render('ServiceItem', InvoiceItem)}}
    {{else}}
      {{render('ProductItem', InvoiceItem)}}
    {{/if}}
  {{/each}}
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/table&gt;</span></span></pre></div></div>

<p>Scenarios just like that one are common in my current work with jTemplates. Imagine trying to implement that with <em>each</em> or an embedded callback function.</p>
<p>Now imagine you wanted to conditionally render those same row templates as sub-items in more than one master template (e.g. maybe there’s also a credit memo template similar to the invoice, but not identical). The burden of maintaining an application like that quickly compounds without template composition.</p>
<p>Again, the exact syntax doesn’t matter. Any implementation that provides the functionality would be a win.</p>
<h3>External templates</h3>
<p><strong>I’ve never understood the desire to cruft up a page with inline templates</strong>. Whether they’re hidden through CSS or embedded within a text/html type script element, cluttering my markup with templates feels sloppy.</p>
<p>jTemplates introduced me to the idea of storing templates externally, and then asynchronously loading them only as necessary (<a href="http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/">example</a>). I adopted that approach at nearly the same time I began using jTemplates and haven’t looked back since.</p>
<p>My affinity for remotely template loading caused me to lobby for remote templates both in the DataView and more recently in jQuery.tmpl. However, what I hadn’t considered is that it’s already easy to load external templates with jQuery’s built in AJAX functionality. With the template loaded into a string variable, the append(TemplateString, Data) syntax connects the dots perfectly.</p>
<p>All of that is simply to say: <strong>Please do leave the append(TemplateString, Data) syntax intact</strong>. As long as we can provide templates via string variable, built in remote template loading isn’t necessary.</p>
<h3>On the need for in-template logic</h3>
<p>I’ve heard some dissention on the issue of conditional logic within templates. </p>
<p>Philosophically, I agree; mingling logic into your presentation/view is dangerous. It’s always a slippery slope, at best. However, the pragmatist in me ultimately cannot agree with the hard-line approach of banishing it completely.</p>
<p><img title="Conditional rendering example" alt="A screenshot of conditionally rendering invoice display names depending on their invoice number" align="left" style="margin: 4px 10px 5px 0;" src="http://encosia.com/blog/wp-content/uploads/2010/05/conditionalrendering.png" width="143" height="358" />A project I&#8217;m working on is a good example. My client-side code must display a collection of invoices sourced from a legacy backend, each with an upgrade number. Upgrade 0 must be displayed as “Original Invoice”, but the rest should be displayed as “Upgrade n”.</p>
<p>A conditional in the template makes quick work of the problem (this is jTemplates syntax, not jQuery.tmpl):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>#if $T.<span style="color: #660066;">Upgrade</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#125;</span>
  Original Invoice
<span style="color: #009900;">&#123;</span>#else<span style="color: #009900;">&#125;</span>
  Upgrade #<span style="color: #009900;">&#123;</span>$T.<span style="color: #660066;">Upgrade</span><span style="color: #009900;">&#125;</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></pre></div></div>

<p>Since it’s purely presentational logic, it belongs in the template as much as it does anywhere. <strong>Please do keep that functionality available</strong>, even if it does have potential for abuse.</p>
<p>In addition to the currently available conditional keywords <em>if</em> and <em>else</em>, <strong>elseif and switch would both be nice additions</strong>.</p>
<h3>Conclusion</h3>
<p>Overall, I’m excited about the potential of seeing jQuery.tmpl integrated into jQuery core, or even made available as an “official” plugin. As much as I like jTemplates, support and documentation for it is spotty at best.</p>
<p>Ultimately, <strong>we will all benefit from standardizing on an official templating solution rolled into the jQuery core</strong>, rather than each of us using our obscure favorite.</p>
<p>I&#8217;m curious what you think.  Am I the only one using template composition?  Anyone want to make a convincing case against conditional logic in templates?</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/">A few thoughts on jQuery templating with jQuery.tmpl</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/07/23/sneak-peak-aspnet-ajax-4-client-side-templating/' rel='bookmark' title='Permanent Link: A sneak peak at ASP.NET AJAX 4.0&#8242;s client-side templating'>A sneak peak at ASP.NET AJAX 4.0&#8242;s client-side templating</a></li>
<li><a href='http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/' rel='bookmark' title='Permanent Link: 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/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Permanent Link: Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/05/03/a-few-thoughts-on-jquery-templating-with-jquery-tmpl/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>5 Steps Toward jQuery Mastery</title>
		<link>http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/</link>
		<comments>http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 06:55:22 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=975</guid>
		<description><![CDATA[Five quick tips that I found valuable while learning jQuery in depth.  I learned them the hard way so you don't have to!<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/">5 Steps Toward jQuery Mastery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/2009/06/09/11-keystrokes-that-made-my-jquery-selector-run-10x-faster/' rel='bookmark' title='Permanent Link: 11 keystrokes that made my jQuery selector run 10x faster'>11 keystrokes that made my jQuery selector run 10x faster</a></li>
<li><a href='http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: Updated: See how I used Firebug to learn jQuery'>Updated: See how I used Firebug to learn jQuery</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="aside">
<p><strong>I am plagiarizing myself!</strong></p>
<p>I originally wrote this article for <a href="http://mosesofegypt.net/" target="_blank">my friend Moses</a> (of Egypt) to be published in the .Network magazine’s inaugural issue, which coincided with this year’s <a href="http://www.cairocodecamp.com/" target="_blank">Cairo Code Camp</a>. Since the article turned out well and there was no corresponding online version, we agreed it would be a good idea to republish it online here too.</p>
</div>
<p>Most of us get our first taste of jQuery by implementing a simple animation effect or using a plugin for a specific purpose. This is natural because, like JavaScript itself, jQuery lends itself to beginning with the basics and building from there.</p>
<p>As you branch out from the trivial and begin using jQuery for more complex solutions, it’s important that you stay vigilant for new ways to approach those more involved problems. <strong>What works well enough for a dozen lines of code may not work for hundreds</strong>, and the unforgiving cross-platform environment that comes along with developing for web browsers only magnifies any trouble you run into.</p>
<p>With that in mind, I want to share a few tips with you that I found valuable as my work with jQuery became more complex.</p>
<h3>Use Firebug to experiment interactively</h3>
<p>If I could suggest only one thing to you, it would be to use Firebug’s console to prototype your ideas in real time. <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">Nothing matches the command line’s immediate feedback when you’re learning</a>. Rather than go through the hassle of editing a JavaScript file, saving it, and then reloading it in the browser, testing at the console allows you to eliminate those intermediate steps and focus on the task at hand.</p>
<p>In particular, the console is invaluable when testing complex combinations of selectors and traversal methods. Simply execute a jQuery statement at the console, with your page loaded in the browser, and you will instantly see the array of matching elements that are returned. If that result set isn’t correct, press the up-arrow key to retrieve the last command entered, refine the statement, and test it again.</p>
<p>That tight feedback loop is phenomenal for quickly learning the jQuery API without leaving the familiar backdrop of your existing markup.</p>
<p>Additionally, one lesser-known feature of Firebug’s console is how it works in conjunction with Firebug’s debugger. When execution is paused, switching to the console tab allows you to interrogate and manipulate the state of the DOM as it was at the time execution was halted. As you step through JavaScript code in the debugger, <strong>the execution context of the console remains in sync with the debugger’s</strong>.</p>
<h3>Cache selector results</h3>
<p>jQuery’s concise syntax makes it easy to forget just how much work the Sizzle selector engine is doing on your behalf. As powerful as the terse selectors are, it’s important not to needlessly duplicate the work that they abstract – especially when using selectors without browser-native backing methods (e.g. <em>a[href^=http], tr:odd, p:contains(Encosia),</em> etc).</p>
<p>To avoid wasteful re-querying, <i>always</i> cache the results of a jQuery selector in a variable if that result set will be used more than once. Once stored in a variable, the result of a selector may be used in exactly the same manner as the original selector itself. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Wasteful duplication of a slow selector</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input[id$=name]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Type your name here'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input[id$=name]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">select</span><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;">// Nearly twice as fast</span>
<span style="color: #003366; font-weight: bold;">var</span> $name <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input[id$=name]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$name.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Type your name here'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$name.<span style="color: #660066;">select</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Prefixing the cache variable with a dollar sign is not functionally significant, but helps to clearly indicate that the variable contains a jQuery wrapped set. <a href="http://www.joelonsoftware.com/articles/Wrong.html" target="_blank">The topic of Hungarian notation is a contentious one</a>, but I’ve found the dollar sign prefix beneficial as complexity increases. </p>
<h3>Don’t use jQuery unless there’s a good reason to</h3>
<p>Perhaps one of the most elusive keys to jQuery mastery is knowing when <i>not</i> to use it. Once you’re proficient with jQuery, it seems natural to use it everywhere. However, that tendency may easily mislead you into writing less concise code that runs slower than necessary.</p>
<p>For instance, this egregious example is one that you will see often:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Typical jQuery over-use</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'button'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</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: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Button clicked: '</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;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</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>In the context of that callback function, <i>this</i> is a reference to the DOM element that raised the click event – often referred to as the <strong>execution context</strong>. Rather than using the DOM element to create a jQuery object, with all of the overhead that goes along with that, why not use the DOM element itself?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Not only faster, but more concise.</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'button'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</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: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Button clicked: '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</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>Another similar misuse is using jQuery as a document.getElementById shortcut. Though jQuery’s ID selector does leverage document.getElementById, it only does so after parsing the selector and then creates a jQuery object to wrap the element. Not only is there more overhead in that process, but starting with a jQuery object by default guides you toward this mistake of overusing jQuery when it isn’t necessary.</p>
<h3>Learn advanced selectors, filters, and traversals</h3>
<p>A great way to improve your jQuery code is to learn its selectors, filters, and traversal methods in depth. <strong>If you find yourself iterating through a selection and manually filtering it for a desired set, there is usually a better way</strong>. Double and triple check that there isn’t a combination of selectors, filters, and/or traversals available to accomplish the same end result.</p>
<p>Not only does using the library’s idioms make your code more concise and expressive, but you will automatically benefit from ongoing performance improvements to jQuery’s Sizzle selector engine that come with each new release. It’s hard to beat having an entire team working to improve your code for you, but that’s exactly what happens when you use jQuery syntax that’s as idiomatic as possible.</p>
<p>A less-frequently documented aspect of learning advanced selectors is that you should be conscious of how to work in concert with jQuery to optimize them. Because <strong>the Sizzle engine evaluates selectors from right-to-left</strong>, being as specific as possible in the rightmost portion of selectors will improve performance.</p>
<p>Selectors that descend from an ID are one notable exception to the right-to-left rule. Sizzle is specially optimized for that case:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Breaks the right-to-left specificity guideline:</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#RegistrationForm input.required'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// jQuery automatically optimizes the previous selector</span>
<span style="color: #006600; font-style: italic;">//  as if you had written it using the ID as a context:</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input.required'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'#RegistrationForm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Use CDN hosting when available</h3>
<p>When you’re developing and testing locally, it’s easy to underestimate the impact that WAN latency will have on your site. Today’s website is often accessed by a geographically diverse set of users that it is impossible to optimally serve all of them from a single datacenter. Serving static resources, such as jQuery, from content delivery networks <a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/">is one effective solution to mitigate that problem</a>.<b></b></p>
<p>Not only do these CDNs provide a faster, more consistent experience to geographically dispersed users, but they also open up the potential for users to visit your site with a primed cache. Since everyone using these public CDNs reference the same URL, a single browser-cached copy of a given asset may be shared between any number of sites visited by a given user.</p>
<p>Even better, because these CDNs serve their content with <a href="http://developer.yahoo.com/performance/rules.html#expires">a far future Expires header</a>, browsers immediately use a locally-cached version of that file if it’s available. They don’t even have to check with the server for a 304 “Not Modified” response, <strong>eliminating the extra HTTP request altogether</strong>.</p>
<p>Assets freely available on public CDNs include <b><a target="_blank" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery">jQuery</a></b> itself, <b>jQuery UI</b>, <a href="http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/"><b>all 14 jQuery UI ThemeRoller themes</b></a>, and the <b><a target="_blank" href="http://www.asp.net/ajaxlibrary/CDNjQueryValidate16.ashx">jQuery validation</a></b> plugin.</p>
<h3>Conclusion</h3>
<p>I hope that you’ll find these ideas useful on your road to jQuery mastery. Though jQuery’s clear, intuitive syntax may appear simplistic on the surface, the library is immensely powerful. The key to unlocking jQuery’s full potential is to never stop experimenting and learning new aspects of it.</p>
<p>In the spirit of that continued road toward mastery, consider taking the next step by watching my TekPub series: <a href="http://tekpub.com/view/jquery/1">Mastering jQuery</a>.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/">5 Steps Toward jQuery Mastery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/2009/06/09/11-keystrokes-that-made-my-jquery-selector-run-10x-faster/' rel='bookmark' title='Permanent Link: 11 keystrokes that made my jQuery selector run 10x faster'>11 keystrokes that made my jQuery selector run 10x faster</a></li>
<li><a href='http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: Updated: See how I used Firebug to learn jQuery'>Updated: See how I used Firebug to learn jQuery</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>How you can force the Ajax Script Loader to use jQuery 1.4</title>
		<link>http://encosia.com/2010/01/15/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/</link>
		<comments>http://encosia.com/2010/01/15/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 05:24:57 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=962</guid>
		<description><![CDATA[If you’ve already begun using Microsoft’s new Ajax Script Loader with a CDN-hosted version of jQuery, today’s release of jQuery 1.4 may have left you wondering how to upgrade. Personally, I didn’t want to wait on a new version of Start.js, nor did I want to abandon the script loader now that I’ve become accustomed [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/01/15/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>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: 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/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/' rel='bookmark' title='Permanent Link: Updated your web.config, but Sys is still undefined?'>Updated your web.config, but Sys is still undefined?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you’ve already begun using Microsoft’s new <a href="http://www.asp.net/ajaxLibrary/Ajax%20Script%20Loader.ashx" target="_blank">Ajax Script Loader</a> with a CDN-hosted version of jQuery, today’s release of jQuery 1.4 may have left you wondering how to upgrade. Personally, I didn’t want to wait on a new version of Start.js, nor did I want to abandon the script loader now that I’ve become accustomed to its benefits.</p>
<p>No doubt, an upcoming ASP.NET Ajax Library iteration will update Start.js’ jQuery definition to reference jQuery 1.4.x. Regardless, <strong>knowing how to patch the script loader on your own terms is something that will be of recurring usefulness</strong>.</p>
<p>Luckily, <a href="http://weblogs.asp.net/bleroy/archive/2009/11/23/enabling-the-asp-net-ajax-script-loader-for-your-own-scripts.aspx" target="_blank">the script loader is open and extensible</a> enough that it’s possible to change which script versions are used. So, I want to briefly show you <strong>how the script loader defines JavaScript includes</strong> and how you can <strong>patch those definitions without modifying Start.js</strong> itself.</p>
<h3>Using the script loader to inject jQuery</h3>
<p>If you aren’t familiar with the script loader itself or with using it to asynchronously request jQuery, I recommend checking out <a href="http://www.asp.net/ajaxlibrary/Ajax%20Script%20Loader.ashx" target="_blank">its documentation and examples on the new ASP.NET Ajax Wiki</a>.</p>
<p>To use it most basically, simply include a reference to Start.js either locally or on the Microsoft CDN, and then use this JavaScript to instruct the script loader to inject jQuery into the page:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This callback runs later, after jQuery</span>
<span style="color: #006600; font-style: italic;">//  has been asynchronously loaded.</span>
Sys.<span style="color: #660066;">onReady</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>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</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>Monitoring the request in Firebug illuminates what that Sys.require statement triggered in the background:</p>
<p><img style="border: #333 1px solid;" alt="Observing the script loader&#39;s default jQuery injection behavior" src="http://encosia.com/blog/wp-content/uploads/2010/01/script-loader-default.png" width="490" height="142" /></p>
<p>As you can see, the end result is pretty straightforward. The primary benefit of this asynchronous loading technique is that <strong>scripts loaded through the script loader are non-blocking and may be loaded in parallel</strong>. By contrast, JavaScript includes referenced through HTML script elements block all rendering and further requests until they are parsed and executed. <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/" target="_blank">The difference is often significant</a>.</p>
<p>Now, if only it were injecting jQuery 1.4 instead of 1.3.2.</p>
<h3>Understanding how Sys.scripts.jQuery is defined</h3>
<p>The Sys.scripts.jQuery parameter to the script loader is actually just a JavaScript object that defines a few parameters about the include. Here is how that is defined in Start.js (edited slightly for readability here):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> path <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">location</span>.<span style="color: #660066;">protocol</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;https&quot;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot;https&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http&quot;</span><span style="color: #009900;">&#41;</span> 
           <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;://ajax.microsoft.com/ajax/&quot;</span><span style="color: #339933;">;</span>
&nbsp;
loader.<span style="color: #660066;">defineScripts</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>
 <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;jQuery&quot;</span><span style="color: #339933;">,</span>
   releaseUrl<span style="color: #339933;">:</span> path <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;jquery/jquery-1.3.2.min.js&quot;</span><span style="color: #339933;">,</span>
   debugUrl<span style="color: #339933;">:</span> path <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;jquery/jquery-1.3.2.js&quot;</span><span style="color: #339933;">,</span>
   isLoaded<span style="color: #339933;">:</span> <span style="color: #339933;">!!</span>window.<span style="color: #660066;">jQuery</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If you’re using a local copy of Start.js, one option is to modify this jQuery script definition inside Start.js itself. However, I discourage that alternative. Not only would it require constant, manual maintenance after every new release, but it isn’t an option when using <a href="http://www.asp.net/ajaxLibrary/cdn.ashx" target="_blank">the Microsoft Ajax CDN’s</a> copy of Start.js.</p>
<h3>Defining a new target for it</h3>
<p>Another option is to <strong>simply modify the Sys.scripts.jQuery object itself</strong>. Letting Start.js initialize the definition with jQuery 1.3.2’s path doesn’t hurt anything as long as we redefine it before calling Sys.require.</p>
<p>Inspecting the Sys.scripts collection in Firebug reveals how straightforward that modification will be:</p>
<p><img style="border: #333 1px solid;" alt="Inspecting Sys.scripts.jQuery in Firebug" src="http://encosia.com/blog/wp-content/uploads/2010/01/Sys.scripts.jQuery-inspection.png" width="490" height="124" /></p>
<p>Thanks to to <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/" target="_blank">the power of interactively interrogating the object in Firebug</a>, it becomes clear that updating the releaseUrl and debugUrl properties of that object should be all that is necessary.</p>
<h3>Updating the example to use jQuery 1.4</h3>
<p>Because jQuery 1.4 isn’t available on the Microsoft CDN yet, I’m going to target <a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/">Google’s AJAX Libraries CDN for jQuery</a> instead. Once Microsoft’s CDN is updated with jQuery 1.4.x, this approach will work for either CDN.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// These re-definitions must be executed after </span>
<span style="color: #006600; font-style: italic;">//  Start.js, but before Sys.require.</span>
<span style="color: #003366; font-weight: bold;">var</span> CDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.googleapis.com/ajax/libs&quot;</span><span style="color: #339933;">;</span>
&nbsp;
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> CDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">debugUrl</span>   <span style="color: #339933;">=</span> CDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This callback runs later, after jQuery</span>
<span style="color: #006600; font-style: italic;">//  has been asynchronously loaded.</span>
Sys.<span style="color: #660066;">onReady</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>
  console.<span style="color: #660066;">log</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</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>That’s all there is to it. Reviewing the requests in Firebug again, you can see that the same Sys.require statement is indeed now loading jQuery 1.4 from Google’s CDN:</p>
<p><img style="border: #333 1px solid;" alt="Observing the script loader&#39;s behavior after modifying Sys.scripts.jQuery" src="http://encosia.com/blog/wp-content/uploads/2010/01/script-loader-modified.png" width="490" /></p>
<h3>Bonus: jQuery Validate 1.6</h3>
<p>As I write this, Start.js’ definition for Sys.scripts.jQueryValidate is still targeting version 1.5.5 of the plugin, but <a href="http://www.asp.net/ajaxLibrary/CDNjQueryValidate16.ashx" target="_blank">1.6 is the current version</a>.</p>
<p>Using what&#8217;s been covered in this post, pointing the script loader at the newest version of jQuery Validate is no problem:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> MSCDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.microsoft.com/ajax&quot;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> GoogCDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.googleapis.com/ajax/libs&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Please forgive my ugly formatting to make this fit. Do not try </span>
<span style="color: #006600; font-style: italic;">//  this at home (unless your editor is only 492px too).</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> 
  GoogCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">debugUrl</span> <span style="color: #339933;">=</span> 
  GoogCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> 
  MSCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jQuery.Validate/1.6/jQuery.Validate.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span>.<span style="color: #660066;">debugUrl</span> <span style="color: #339933;">=</span> 
  MSCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jQuery.Validate/1.6/jQuery.Validate.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery and jQuery Validate in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #339933;">,</span> Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span><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;">// This callback runs later, after both jQuery</span>
<span style="color: #006600; font-style: italic;">//  and jQuery Validate have been loaded.</span>
Sys.<span style="color: #660066;">onReady</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>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</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>The jQuery Validate situation is a good example of why knowing how to update these script definitions yourself is worthwhile. Because the script loader was designed to be so flexible, there’s no need to wait on a new release of Start.js or give up its benefits.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2010/01/15/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>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: 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/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/' rel='bookmark' title='Permanent Link: Updated your web.config, but Sys is still undefined?'>Updated your web.config, but Sys is still undefined?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2010/01/15/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Mastering jQuery now available at TekPub</title>
		<link>http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/</link>
		<comments>http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 14:52:42 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=951</guid>
		<description><![CDATA[If you haven’t been following the progress of Rob Conery and James Avery’s new venture, TekPub, you’ve been missing out on some great instructional videos. I especially like that they trend slightly Alt.NET, giving you more balanced information than is sometimes available from “official” .NET screencasts. For the past few weeks, I’ve been working with [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/">Mastering jQuery now available at TekPub</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
<li><a href='http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/' rel='bookmark' title='Permanent Link: Emulate ASP.NET validation groups with jQuery validation'>Emulate ASP.NET validation groups with jQuery validation</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank"><img border="0" alt="Mastering jQuery" src="http://encosia.com/blog/wp-content/uploads/2009/12/tekpub-mastering-jquery.jpg" width="492" height="242" /></a></p>
<p>If you haven’t been following the progress of Rob Conery and James Avery’s new venture, <a href="http://tekpub.com" target="_blank">TekPub</a>, you’ve been missing out on some great instructional videos. I especially like that they trend slightly Alt.NET, giving you more balanced information than is sometimes available from “official” .NET screencasts.</p>
<p>For the past few weeks, I’ve been working with James to record a series of episodes for TekPub myself: <strong>Mastering jQuery</strong>.</p>
<blockquote><p>Mastering jQuery walks through the basics of using jQuery, the revolutionary JavaScript framework that makes writing client-side code fun and easy, and then dives into the details of writing AJAX enabled ASP.NET MVC and ASP.NET Web Forms applications. We will also cover popular plugins and extending jQuery in future episodes.</p></blockquote>
<p>Today, the first video in that series is available: <a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank">Getting Started with jQuery</a>.</p>
<blockquote><p>In this episode we cover the basics of getting started with jQuery. We start with a basic HTML page and show how to include jQuery, how to write your first code, and explain all of the moving pieces and how they work.</p></blockquote>
<p>If you’ve been following my site and working with jQuery already, the first episode may sound elementary, but there’s going to be something for everyone before the series is finished. By the third episode, we’re already into topics like making <strong>AJAX calls to MVC controller actions</strong> and <strong>progressively enhancing an entry form</strong> with the jQuery form plugin.</p>
<p>I hope you&#8217;ll head over to TekPub, and <a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank">have a look for yourself</a>.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/">Mastering jQuery now available at TekPub</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
<li><a href='http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/' rel='bookmark' title='Permanent Link: Emulate ASP.NET validation groups with jQuery validation'>Emulate ASP.NET validation groups with jQuery validation</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/12/16/mastering-jquery-now-available-at-tekpub/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Emulate ASP.NET validation groups with jQuery validation</title>
		<link>http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/</link>
		<comments>http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:51:37 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=948</guid>
		<description><![CDATA[In my most recent post, I demonstrated a workaround to allow using the jQuery validation plugin with WebForms pages. The basic idea was to trigger validation only on submissions that occurred within a single logical form, instead of catching submissions anywhere on WebForms’ all-encompassing physical form. This approach worked fine for a single logical form, [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/">Emulate ASP.NET validation groups with jQuery validation</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/' rel='bookmark' title='Permanent Link: Using jQuery validation with ASP.NET WebForms'>Using jQuery validation with ASP.NET WebForms</a></li>
<li><a href='http://encosia.com/2008/10/11/using-jquery-to-display-a-modal-updatepanel-confirmation/' rel='bookmark' title='Permanent Link: Using jQuery to display a modal UpdatePanel confirmation'>Using jQuery to display a modal UpdatePanel confirmation</a></li>
<li><a href='http://encosia.com/2007/11/15/exploring-one-of-ms-ajaxs-often-overlooked-features/' rel='bookmark' title='Permanent Link: Exploring one of MS AJAX&#8217;s often overlooked features.'>Exploring one of MS AJAX&#8217;s often overlooked features.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In my most recent post, I demonstrated a workaround to allow <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">using the jQuery validation plugin with WebForms pages</a>. The basic idea was to trigger validation only on submissions that occurred within a single logical form, instead of catching submissions anywhere on WebForms’ all-encompassing physical form.</p>
<p>This approach worked fine for a single logical form, but wasn&#8217;t robust enough when handling validation for multiple logical forms on a single page. Additionally, it did not properly handle the enter key, allowing users to (perhaps accidentally) slip past validation if they simply hit the enter key within a TextBox.</p>
<p>In this post, we will continue by refining the solution from last time. So, if you haven’t read the previous post, familiarize yourself with it first. Specifically, this post will cover how to <strong>implement an analogue of WebForms’ ValidationGroup</strong>, use that to <strong>independently validate multiple form regions</strong>, <strong>handle the enter key</strong>, and <strong>refactor the final solution</strong> to minimize duplicated code.</p>
<h3>ValidationGroups</h3>
<p>In WebForms, we have the concept of a <strong><a href="http://msdn.microsoft.com/en-us/library/ms227424.aspx" rel="nofollow" target="_blank">ValidationGroup</a></strong> to mitigate the issues that come with wrapping the entire page in a single form element. Whether right or wrong in principle, this scheme does a pretty good job of keeping the ASP.NET Validation controls from getting their wires crossed on complex forms.</p>
<p>However, using ASP.NET’s ValidationGroups requires that you use the WebForms validation controls, which generates quite a bit of cruft in your markup and injects two additional script references on your page.</p>
<p><img style="border: 1px solid #000;" alt="An example of some of the client-side code the ASP.NET Validators generates" src="http://encosia.com/blog/wp-content/uploads/2009/11/WebForms-validator-output.png" width="490" height="111" /></p>
<p>If you’re like me, trying to trend away from client-heavy WebForms pages <strong>these side-effects are prohibitive</strong>.</p>
<h3>Emulating Validation Groups</h3>
<p>Though its implementation renders a bit messy on the client-side, the WebForms paradigm of a ValidationGroup is exactly what we need for segregating our physical form element into logical forms. In fact, I’m going to use the same nomenclature in this example (ValidationGroup and CausesValidation).</p>
<p>Using CSS classes as flags is a great way to emulate that concept in plain (X)HTML markup. Especially when using jQuery, CSS “flags” are a great way to tag elements with arbitrary attributes, that are easy to find with simple DOM selectors later. Taking the form shown in my previous post and tagging its fieldsets with a validationGroup class, we end up with this 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;fieldset</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;validationGroup&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;legend&gt;</span></span>Returning customer?  Login here<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Username and Password labels and inputs here --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset&gt;</span></span></pre></div></div>

<p>Not a very large change, but it allows us to keep these logical forms separate, both when performing validation and when initially setting up their validation triggers.</p>
<h3>Creating a CausesValidation counterpart</h3>
<p>ValidationGroups may control the organization of logical forms, but it’s the controls marked with the CausesValidation property that drive validation of those forms. In similar fashion, we need a way to indicate which elements should trigger our own emulation of WebForms’ grouped validation.</p>
<p>Sticking with the same naming scheme and CSS flagging technique, it makes sense to tag our Button controls with a .causesValidation class:</p>

<div class="wp_syntax"><div class="code"><pre class="asp" style="font-family:monospace;">&lt;fieldset class=&quot;validationGroup&quot;&gt;
  &lt;legend&gt;Returning customer?  Login here&lt;/legend&gt;
&nbsp;
  <span style="color: #060; font-style: italic;">&lt;!-- Username and Password labels and inputs here --&gt;</span>
&nbsp;
  &lt;asp:Button runat=&quot;server&quot; ID=&quot;Login&quot; Text=&quot;Login&quot; 
              CssClass=&quot;causesValidation&quot; /&gt;
&lt;/fieldset&gt;</pre></div></div>

<p>Now we just need to wire up functionality to make those causesValidation flags actually do something.</p>
<h3>Acting on the validationGroup flag</h3>
<p>With the markup modified to allow selective targeting of the validation groups, the next step is implementing validation functionality that leverages that targeting. Using jQuery’s powerful CSS-based selectors, that isn’t difficult:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</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: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</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;">// Search for controls marked with the causesValidation flag </span>
  <span style="color: #006600; font-style: italic;">//  that are contained anywhere within elements marked as </span>
  <span style="color: #006600; font-style: italic;">//  validationGroups, and wire their click event up.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup .causesValidation'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Ascend from the button that triggered this click event </span>
    <span style="color: #006600; font-style: italic;">//  until we find a container element flagged with </span>
    <span style="color: #006600; font-style: italic;">//  .validationGroup and store a reference to that element.</span>
    <span style="color: #003366; font-weight: bold;">var</span> $group <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;">parents</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Descending from that .validationGroup element, find any input</span>
    <span style="color: #006600; font-style: italic;">//  elements within it, iterate over them, and run validation on </span>
    <span style="color: #006600; font-style: italic;">//  each of them.</span>
    $group.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input'</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: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</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: #339933;">!</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</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: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
      evt.<span style="color: #660066;">preventDefault</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>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>Note: For more explanation of any uncommented code above, be sure to see <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">the previous post in this series</a>. Those parts are explained in detail there.</em></p>
<p>This sets up a click event handler on any element flagged with the causesValidation class; the two Button controls in our case. When those raise click events, we start at the triggering element and use <a href="http://docs.jquery.com/Traversing/parents#expr" target="_blank">the parents() traversal method</a> to search upward for the nearest parent flagged as a validationGroup.</p>
<p>In this example, that will find a reference to the fieldset which contains the Button control that triggers the click event (e.g. if the user clicks the Login Button, then $group will store a reference to the first fieldset element).</p>
<p>With that reference to the the logical form requiring validation, <a href="http://docs.jquery.com/Traversing/find#expr" target="_blank">jQuery’s find() traversal method</a> allows us to select a set of all the input elements within just that region of the page. Note that this will also include the Button control that triggered the event, but since the valid() method returns <em>true</em> for elements that don’t have validation rules configured, this doesn’t cause a problem.</p>
<p>From there, it’s straightforward to iterate over the appropriate input elements and validate each independently, using <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">the valid() trick covered in the last post</a>.</p>
<h3>Handling the enter key</h3>
<p>At this point, everything works pretty well, so long as the user <em>clicks</em> on the Button controls to submit the logical forms. Unfortunately, things fall apart if the user triggers form submission by pressing enter in one of the form fields.</p>
<p>One way to fix that would be to handle the form’s onsubmit event, determine if an element flagged with the causesValidation class triggered the submission, and then run through our validation first. That’s perfectly valid, but <strong>I avoid that because it tends to clash with other functionality that handles the event</strong>; <a href="http://jquery.malsup.com/form/" target="_blank">the jQuery form plugin</a> for example.</p>
<p>The alternative that I prefer is to handle a validated field’s onkeydown event. That way, if the element does need to trigger validation, it can do so early, and get out of the way quickly otherwise.</p>
<p>Using jQuery’s cross-browser normalized event object, testing for the enter key is not difficult at all. When handling keyboard related events, one property of that object is <strong>keyCode</strong>. This property will contain the ASCII character code of the key which triggered the event. In the case of the enter key, that keyCode is <strong>13</strong>.</p>
<p>That in mind, this is a first iteration of adding enter key handling to our existing validation code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Select any input[type=text] elements within a validation group</span>
<span style="color: #006600; font-style: italic;">//  and attach keydown handlers to all of them.</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup :text'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keydown</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Only execute validation if the key pressed was enter.</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">13</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Validation code goes 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>Whether the form is submitted by clicking a button or hitting the enter key within one of our validation groups’ text fields, the appropriate inputs will be validated, error messages displayed if necessary, and <strong>submission will only continue if the form is valid</strong>.</p>
<h3>Refactoring to eliminate duplication</h3>
<p>After adding the keydown handler, everything works great, but it’s no good to have that validation code duplicated for both the click and keydown handlers. By passing around a reference to the jQuery event object, we can reuse the same validation code for both event types and make the code much more concise:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</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;">// Initialize validation on the entire ASP.NET form.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// This prevents validation from running on every</span>
    <span style="color: #006600; font-style: italic;">//  form submission by default.</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</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;">// Search for controls marked with the causesValidation flag </span>
  <span style="color: #006600; font-style: italic;">//  that are contained anywhere within elements marked as </span>
  <span style="color: #006600; font-style: italic;">//  validationGroups, and wire their click event up.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup .causesValidation'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span>ValidateAndSubmit<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Select any input[type=text] elements within a validation group</span>
  <span style="color: #006600; font-style: italic;">//  and attach keydown handlers to all of them.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup :text'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keydown</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Only execute validation if the key pressed was enter.</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">13</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      ValidateAndSubmit<span style="color: #009900;">&#40;</span>evt<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>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ValidateAndSubmit<span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Ascend from the button that triggered this click event </span>
  <span style="color: #006600; font-style: italic;">//  until we find a container element flagged with </span>
  <span style="color: #006600; font-style: italic;">//  .validationGroup and store a reference to that element.</span>
  <span style="color: #003366; font-weight: bold;">var</span> $group <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">currentTarget</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parents</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Descending from that .validationGroup element, find any input</span>
  <span style="color: #006600; font-style: italic;">//  elements within it, iterate over them, and run validation on </span>
  <span style="color: #006600; font-style: italic;">//  each of them.</span>
  $group.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input'</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: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</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: #339933;">!</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</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;">// If any fields failed validation, prevent the button's click </span>
  <span style="color: #006600; font-style: italic;">//  event from triggering form submission.</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
    evt.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>First, the validation code is refactored into a separate function: <strong>Validate</strong>.</p>
<p>Since it needs the ability to conditionally call preventDefault in order to stop form submission, the function accepts the event handlers’ jQuery event object as a parameter.</p>
<p>In fact, because $(this) is a reasonable place to begin the parents() traversal for either event that may call the method, very little refactoring is necessary.</p>
<p>The one thing that may seem strange is that the Validate function is being passed as a click handler without any parameters. <strong>The reason that this works is because the Validate function is defined with the same signature that jQuery expects</strong>. Because of that alignment, Validate will automatically be provided with the same event object that we’ve been using in anonymous callback functions thus far.</p>
<h3>Calculated readability</h3>
<p>Note that I attached keydown handlers to <em>all</em> of the text inputs within a validation group, <strong>regardless of whether or not they are actually validated fields</strong>. Similarly, you may have noticed that the click handler finds every input element within its validation group, even if those inputs aren’t marked for validation. This may seem like an oversight, but it’s an intended readability compromise.</p>
<p>You <em>could</em> modify the selector to be more precise, selecting only fields flagged with validation classes (e.g. <em>required</em>, <em>email</em>, <em>number</em>, etc). However, this gets messy when you consider <a href="http://docs.jquery.com/Plugins/Validation#List_of_built-in_Validation_methods" rel="nofollow" target="_blank">the wide variety of classes that are valid for tagging elements with jQuery validation functionality</a>.</p>
<p>Rather than be precisely specific, I rely on the fact that <strong>jQuery validation’s valid() method returns <em>true</em> for elements which are not configured for validation</strong>. So, even if we do end up checking the validation status of a few irrelevant input fields, it won’t adversely impact the outcome of the validation process.</p>
<p>There are performance penalties to performing validation on these unnecessary elements, but it is negligible for a reasonably sized form. The ancillary inputs would have to number in the thousands before the penalty were noticeable, at which no one will probably ever successfully complete it anyway!</p>
<h3>Conclusion</h3>
<p>There are even more enhancements to be had, but I think this brings the solution to a point that it’s useful. With multiple logical forms handled and the perennially pesky enter key tamed, the majority of use cases should be covered.</p>
<p>The most troublesome issue still remaining is that <strong>care should be taken to avoid nesting container elements with the validationGroup class on them</strong>. Otherwise, the Validate() function will search “too high” and possibly hinge validation on input fields that are not intended. It’s an edge case (fixable if necessary), but something to keep in mind.</p>
<p>Another edge case is that, unlike the ASP.NET Validators, <strong>these validation groups can’t overlap</strong>. For my own use, this has never been an issue. I’m curious if that’s a real-world problem for any of you.</p>
<p>Finally, an entirely different approach well worth considering is <a href="http://john.rummell.info/john/blog/" target="_blank">John Rummell</a>’s <a href="http://xvalwebforms.codeplex.com/" rel="nofollow" target="_blank">xVal for Webforms</a>. Using Data Annotations to specify validation rules is gaining a lot of popularity, so it’s worth investigating options like this one. At the minimum, it will help you be more familiar with how validation is handled in ASP.NET MVC.</p>
<p>Hope that helps. Be sure to take a look at the source download to see everything pulled together and one extra usability feature that I didn’t have time to cover.</p>
<h3>Source</h3>
<p><a href="http://encosia.com/source/WebForms-jq-validation-p2.zip" title="WebForms-jq-validation-p2.zip"><img src="http://encosia.com/blog/wp-content/uploads/2009/11/download-WebForms-jq-validation-p2.png" width="492" height="46" alt="Download WebForms-jq-validation-p2.zip" /></a></p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/">Emulate ASP.NET validation groups with jQuery validation</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/' rel='bookmark' title='Permanent Link: Using jQuery validation with ASP.NET WebForms'>Using jQuery validation with ASP.NET WebForms</a></li>
<li><a href='http://encosia.com/2008/10/11/using-jquery-to-display-a-modal-updatepanel-confirmation/' rel='bookmark' title='Permanent Link: Using jQuery to display a modal UpdatePanel confirmation'>Using jQuery to display a modal UpdatePanel confirmation</a></li>
<li><a href='http://encosia.com/2007/11/15/exploring-one-of-ms-ajaxs-often-overlooked-features/' rel='bookmark' title='Permanent Link: Exploring one of MS AJAX&#8217;s often overlooked features.'>Exploring one of MS AJAX&#8217;s often overlooked features.</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Using jQuery validation with ASP.NET WebForms</title>
		<link>http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/</link>
		<comments>http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 09:57:24 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=939</guid>
		<description><![CDATA[You’ve probably noticed that Jörn Zaefferer’s jQuery validation plugin has been gaining momentum in the ASP.NET community lately. Between Microsoft’s implied endorsement via ASP.NET MVC 2.0 integration and the plugin’s recent inclusion on the Microsoft AJAX CDN, adoption is only increasing. Unfortunately for those who don’t or can’t use ASP.NET MVC yet, using the validation [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/">Using jQuery validation with ASP.NET WebForms</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/10/04/using-jquery-to-enhance-aspnet-ajax-progress-indication/' rel='bookmark' title='Permanent Link: Using jQuery to enhance ASP.NET AJAX progress indication'>Using jQuery to enhance ASP.NET AJAX progress indication</a></li>
<li><a href='http://encosia.com/2008/10/31/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Permanent Link: 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/2008/10/19/7-of-my-favorite-jquery-plugins-for-use-with-aspnet/' rel='bookmark' title='Permanent Link: 7 of my favorite jQuery plugins for use with ASP.NET'>7 of my favorite jQuery plugins for use with ASP.NET</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border: 1px solid #333;" title="Validation Sticker" border="0" alt="Validation Sticker" src="http://encosia.com/blog/wp-content/uploads/2009/11/validation-sticker.jpg" width="490" height="138" /></p>
<p>You’ve probably noticed that Jörn Zaefferer’s <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/" target="_blank">jQuery validation plugin</a> has been gaining momentum in the ASP.NET community lately. Between Microsoft’s implied endorsement via <a href="http://haacked.com/archive/2009/10/01/asp.net-mvc-preview-2-released.aspx" target="_blank">ASP.NET MVC 2.0 integration</a> and <a href="http://www.asp.net/ajax/CDN/#5" target="_blank">the plugin’s recent inclusion on the Microsoft AJAX CDN</a>, adoption is only increasing. Unfortunately for those who don’t or can’t use ASP.NET MVC yet, using the validation plugin within WebForms applications can be tricky.</p>
<p>Because the WebForms Postback model requires that the entire page be contained within a single form element, form submissions that shouldn’t trigger validation are likely. ASP.NET’s built-in validation controls solve this with ValidationGroups and the CausesValidation property, but that doesn’t help if you’d prefer to use the jQuery validation plugin.</p>
<p>However, there <em>are</em> a couple relatively easy workarounds that make it possible to use the jQuery validation plugin on WebForms pages, without re-architecting the page or its forms. In this post, I’ll show you <strong>why the WebForms page structure is a problem</strong>, how to <strong>make jQuery validation work with it</strong>, and <strong>an example of implementing those workarounds</strong>.</p>
<p><em>Note: I want to preface this by saying that you should never rely entirely on client-side validation. The jQuery validation plugin can be a great replacement for the client-side part of the ASP.NET Validators, but it is not a complete replacement on its own. Use responsibly!</em></p>
<h3>&lt;form&gt; over function</h3>
<p>When it comes to using jQuery validation, <strong>the trouble with WebForms is that it requires all of the ASP.NET controls on a page to be contained within a single form element</strong>. That doesn’t lead to any problems in simple demos, but things are more complicated when it comes to real-world pages. They often require multiple logical forms on the same page, and that’s where the problems start.</p>
<p>For example, consider the common scenario of having both a login form and a customer information form on the same page. We’ve probably all seen something like this before:</p>

<div class="wp_syntax"><div class="code"><pre class="asp" style="font-family:monospace;"><span style="color: #060; font-weight: bold;">&lt;</span>form id<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;form1&quot;</span> runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>Returning customer<span style="color: #060; font-weight: bold;">?</span>  Login here<span style="color: #060; font-weight: bold;">&lt;/</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Username&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Email<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Username&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Password<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span> TextMode<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>Button runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Login&quot;</span> Text<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Login&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;/</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
  <span style="color: #060; font-weight: bold;">&lt;</span>fieldset id<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;BillingInfo&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>New customer<span style="color: #060; font-weight: bold;">?</span>  Provide the following<span style="color: #060; font-weight: bold;">&lt;/</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;FirstName&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>First Name<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;FirstName&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;LastName&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Last Name<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;LastName&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Address&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Address<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Address&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;City&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>City<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;City&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;State&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>State<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;State&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Zip&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Zip<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Zip&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>Button runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Order&quot;</span> Text<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Submit Order&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;/</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
<span style="color: #060; font-weight: bold;">&lt;/</span>form<span style="color: #060; font-weight: bold;">&gt;</span></pre></div></div>

<p>In most web frameworks, you would divide both logical forms into separate form elements, but WebForms requires both to remain joined within its single form element. This means that  <strong>clicking either of the Button controls will submit both logical forms together.</strong></p>
<p>Once applied to a form through <a href="http://docs.jquery.com/Plugins/Validation#Example" rel="nofollow" target="_blank">its default usage</a>, the jQuery validation plugin will attempt to validate all of the elements on that form <em>any time it is submitted</em>. That automation is usually handy, but it means <strong>users trying to submit our login form will be denied due to validation failing on the unrelated fields below</strong>.</p>
<p><img style="border: 1px solid #333;" src="http://encosia.com/blog/wp-content/uploads/2009/11/cross-validation-issue.jpg" width="490" height="416" /></p>
<p>Since using separate form elements containing WebForms controls isn’t realistic, we need to tackle this on the client-side and find a way to make jQuery validation more WebForms-friendly.</p>
<h3>Taming jQuery validation</h3>
<p>To remedy this problem, we first need to prevent the jQuery validation plugin from automatically triggering on every form submission. The initializer’s <strong>onsubmit</strong> property allows us to do just that:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</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;">// Initialize validation on the entire ASP.NET form</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// This prevents validation from running on every</span>
    <span style="color: #006600; font-style: italic;">//  form submission by default.</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</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>That fixes our problem of the login form triggering unwanted validation in the form below, but it creates another issue. Now, <em>neither</em> of the forms will validate when submitted.</p>
<h3>Taking control with on-demand validation</h3>
<p>Instead of relying on the plugin to automatically validate form submissions, you may also use a less widely known method for triggering the validation on-demand. When added to a page, one of the new methods that jQuery validation exposes on the jQuery object is <strong>valid()</strong>.</p>
<p>When <a href="http://docs.jquery.com/Plugins/Validation/valid" rel="nofollow" target="_blank">valid()</a> is called on the jQuery object returned from selecting a “validated” form element, it will trigger validation on every field within the form and return a Boolean value indicating whether or not the form is valid.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</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: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Order&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Validate the form and retain the result.</span>
    <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><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;">// If the form didn't validate, prevent the</span>
    <span style="color: #006600; font-style: italic;">//  form submission.</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
      evt.<span style="color: #660066;">preventDefault</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>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>At first glance, this code might look incomplete to you. We care about more than just preventing form submissions when the form fails validation; we must also indicate the validation errors to the user.</p>
<p>Fortunately, <strong>the valid() method has the very useful side effect of displaying the plugin’s configured validation errors</strong> for any fields it finds to fail validation.</p>
<p>From the user’s perspective, this implementation is the same as the original one using the default usage. This method just happens to also have the added benefit of actually allowing returning users to log in.</p>
<h3>To be continued…</h3>
<p>This solution is a good start, but has (at least) two flaws.</p>
<p>First, it doesn’t handle keyboard triggered form submissions. <strong>What happens if the user hits the enter key in one of the TextBoxes</strong>?</p>
<p>Second, <strong>what if we want to also validate the login form</strong>? If validation rules are added to that form’s fields, we’ll have exactly the opposite problem as what we started with. Valid submissions in the lower form will be prevented by validation failures on the upper form.</p>
<p>For solutions to both of those problems, be sure to read my followup post: <a href="http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/">Emulate ASP.NET WebForms validation groups with jQuery validation</a>.</p>
<h3>Download the Source</h3>
<p><a href="/source/WebForms-jq-validation.zip"><img src="http://encosia.com/blog/wp-content/uploads/2009/11/download-webforms-jq-validation.png" width="492" height="46" alt="Download WebForms-jq-validation.zip" /></a></p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/">Using jQuery validation with ASP.NET WebForms</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/10/04/using-jquery-to-enhance-aspnet-ajax-progress-indication/' rel='bookmark' title='Permanent Link: Using jQuery to enhance ASP.NET AJAX progress indication'>Using jQuery to enhance ASP.NET AJAX progress indication</a></li>
<li><a href='http://encosia.com/2008/10/31/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Permanent Link: 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/2008/10/19/7-of-my-favorite-jquery-plugins-for-use-with-aspnet/' rel='bookmark' title='Permanent Link: 7 of my favorite jQuery plugins for use with ASP.NET'>7 of my favorite jQuery plugins for use with ASP.NET</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Do you know about this undocumented Google CDN feature?</title>
		<link>http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/</link>
		<comments>http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 03:26:41 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=912</guid>
		<description><![CDATA[By now, you probably already know that Google hosts jQuery on its AJAX APIs CDN, free of charge. As I’ve discussed here in the past, I’m a big fan of using their CDN to achieve decreased latency, increased parallelism, and better caching. If you’ve explored the AJAX APIs documentation a bit, you may know that [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/">Do you know about this undocumented Google CDN feature?</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='Permanent Link: 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/2008/08/13/how-to-easily-enhance-your-existing-tables-with-simple-css/' rel='bookmark' title='Permanent Link: How to easily enhance your existing tables with simple CSS'>How to easily enhance your existing tables with simple CSS</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>By now, you probably already know that Google hosts jQuery on its AJAX APIs CDN, free of charge. As I’ve discussed here in the past, I’m a big fan of <a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/" target="_blank">using their CDN to achieve <strong>decreased latency</strong>, <strong>increased parallelism</strong>, and <strong>better caching</strong></a>.</p>
<p>If you’ve explored the AJAX APIs documentation a bit, you may know that <a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jqueryUI" target="_blank">jQuery UI is also hosted on Google’s CDN</a>. Unfortunately, since jQuery UI plugins depend on a <a href="http://jqueryui.com/themeroller/" target="_blank">ThemeRoller</a> theme, using a CDN for jQuery UI isn’t as easy as with jQuery itself.</p>
<p>Or, is it?</p>
<h3>My &lt;head&gt; is in the cloud</h3>
<p>While poking around a couple months ago, I stumbled upon something that I’ve found extremely useful: <a href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css" target="_blank">An entire jQuery UI theme hosted on Google’s CDN</a>!</p>
<p>Not only is the theme’s CSS stylesheet there, but <strong>all 14 of the theme’s images are hosted in the correct relative location too</strong>. That means you can apply the entire theme to a page with a single CSS reference and no local files.</p>
<p>Even better, while JavaScript and CSS includes are unable to take full advantage of the increased parallelism a CDN offers, the theme’s images <em>do</em>. This makes loading the theme from Google’s CDN particularly effective.</p>
<h3>Using it</h3>
<p>Using this on your own pages couldn’t be easier. There are no files to download, no paths to worry about, and no configuration is required. Just a reference to <a href="http://code.google.com/apis/ajaxlibs/documentation/#jquery" rel="nofollow" target="_blank">jQuery</a>, <a href="http://code.google.com/apis/ajaxlibs/documentation/#jqueryUI" rel="nofollow" target="_blank">jQuery UI</a>, and the ThemeRoller theme you want to use will is all you need.</p>
<p>For example, if you wanted to build a quick demo of the jQuery UI Tabs plugin, use these references in the head of your page:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #0bd;">&lt;!DOCTYPE html&gt;</span>
<span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">head</span>&gt;</span>
  <span style="color: #808080; font-style: italic;">&lt;!-- To avoid horizontal scrolling in this code listing. --&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">base</span> <span style="color: #006;">href</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;http://ajax.googleapis.com/&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">&lt;!-- Reference the theme's stylesheet on the Google CDN --&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">link</span> <span style="color: #006;">href</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css&quot;</span></span>
<span style="color: #090;">        <span style="color: #006;">type</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;text/css&quot;</span> <span style="color: #006;">rel</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;Stylesheet&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">&lt;!-- Reference jQuery and jQuery UI from the CDN. Remember</span>
<span style="color: #808080; font-style: italic;">       that the order of these two elements is important --&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">script</span> <span style="color: #006;">src</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;/ajax/libs/jquery/1.3.2/jquery.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">script</span>&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">script</span> <span style="color: #006;">src</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">script</span>&gt;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">&lt;!-- Initialize the tabs when the document is ready --&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">script</span> <span style="color: #006;">type</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;text/javascript&quot;</span>&gt;</span>
    $(document).ready(function() {
      // See the jQuery UI Tabs documentation for
      //  more information about how this works.
      $('#tabs').tabs();
    });
  <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">head</span>&gt;</span></pre></div></div>

<p><em>Note: You shouldn’t use the &lt;base&gt; tag like this in your pages. It affects all links on the page, not just those in the &lt;head&gt;. I’m just using it here to avoid horizontal scrolling (the bane of my existence when posting code here).</em></p>
<p>Then, just a bit of corresponding markup in the body of the document (<a href="http://jqueryui.com/demos/tabs/" target="_blank">see the jQuery UI Tabs documentation</a> for specifics):</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">body</span>&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">div</span> <span style="color: #006;">id</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;tabs&quot;</span>&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">ul</span>&gt;</span>
      <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000; font-weight: bold;">a</span> <span style="color: #006;">href</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;#tab-1&quot;</span>&gt;</span>Tab 1<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000; font-weight: bold;">a</span> <span style="color: #006;">href</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;#tab-2&quot;</span>&gt;</span>Tab 2<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000; font-weight: bold;">a</span> <span style="color: #006;">href</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;#tab-3&quot;</span>&gt;</span>Tab 3<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">li</span>&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">ul</span>&gt;</span>
&nbsp;
    <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">div</span> <span style="color: #006;">id</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;tab-1&quot;</span>&gt;</span>
      <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">p</span>&gt;</span>These tabs were created with JavaScript, CSS, and 
        images hosted on Google's AJAX APIs CDN.<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">p</span>&gt;</span>
&nbsp;
      <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">p</span>&gt;</span>Thanks, Google!<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">p</span>&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">div</span>&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">div</span> <span style="color: #006;">id</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;tab-2&quot;</span>&gt;</span>
      <span style="color: #808080; font-style: italic;">&lt;!-- Tab 2's content goes here. --&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">div</span>&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #000; font-weight: bold;">div</span> <span style="color: #006;">id</span><span style="color: #66cc66;">=</span><span style="color: #f00;">&quot;tab-3&quot;</span>&gt;</span>
      <span style="color: #808080; font-style: italic;">&lt;!-- Tab 3's content goes here. --&gt;</span>
    <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">div</span>&gt;</span>
  <span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">div</span>&gt;</span>
<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #090;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000; font-weight: bold;">html</span>&gt;</span></pre></div></div>

<p>That HTML (without a single file or image hosted locally) results in this:</p>
<p><img alt="tabs-example" src="http://encosia.com/blog/wp-content/uploads/2009/10/tabs-example.png" width="492" height="206" /></p>
<p>Don’t like the theme in my example? Don’t worry, because <strong>all 24 of the standard ThemeRoller presets are also hosted on the CDN</strong>. See the end of this post for a full listing.</p>
<h3>Nothing’s perfect</h3>
<p>There are a couple of potential issues when using these CDN hosted themes.</p>
<p>First, <strong>these themes aren’t minified</strong>. Minification shaves about 20% off the size of an average ThemeRoller theme’s CSS, which is definitely worthwhile. Hopefully, minified versions will be available at some point (assuming I didn’t miss ones that may already be hiding there somewhere). In the meantime, Google does properly gzip compress them though, which makes the difference less significant.</p>
<p>Second, if you normally customize ThemeRoller’s CSS or images manually, this probably isn’t for you. Lacking control over the base CSS style is something that you can work around, but isn’t worth the complexity and extra HTTP requests.</p>
<p>However, <strong>you can still reference the CDN’s images from custom CSS</strong>, by using absolute paths.</p>
<h3>Conclusion</h3>
<p>Overall, this seemingly small feature has been surprisingly useful in my day-to-day development. While it’s technically not very difficult to download and set up local ThemeRoller themes, there’s more friction to it than I care for. <strong>Boiling the entire process down to a single CSS reference removes all of that friction</strong>.</p>
<p>Even if you don’t like the idea of relying on a CDN hosted theme for production sites, <strong>this is great for prototyping</strong>. <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">Anything that makes prototyping faster is a big win</a>, because it allows you to try more ideas in the same amount of time.</p>
<p>What do you think? Does this sound useful to you? Are you comfortable leaning on Google’s CDN for your entire jQuery UI theme? Would you use this in production?</p>
<h3 id="fullListing">Full Theme Listing</h3>
<p><strong>The URLs below reference jQuery UI v1.7.2 themes</strong>.  If 1.7.2 isn&#8217;t the latest version at the time that you&#8217;re reading this, you should be able to replace 1.7.2 in the URL with the current version and find a current theme hosted on the CDN.</p>
<p>Click any of the thumbnails to view that theme on ThemeRoller.</p>
<p>Click any of the input fields to select the full URL to the theme&#8217;s CDN hosted CSS file, ready for copy/pasting into your page.</p>
<p><noscript>Attention RSS Readers:  You will probably need to view this full post in your browser to see the input fields. <a href="http://encosia.com/912#fullListing" target="_blank">Click here to open the post and skip directly at this point in the post</a>.</noscript></p>
<table width="492">
<tr>
<td align="center"><strong>UI Lightness</strong></td>
<td align="center"><strong>UI Darkness</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Trebuchet+MS,+Tahoma,+Verdana,+Arial,+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=4px&#038;bgColorHeader=f6a828&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=35&#038;borderColorHeader=e78f08&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=eeeeee&#038;bgTextureContent=03_highlight_soft.png&#038;bgImgOpacityContent=100&#038;borderColorContent=dddddd&#038;fcContent=333333&#038;iconColorContent=222222&#038;bgColorDefault=f6f6f6&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=100&#038;borderColorDefault=cccccc&#038;fcDefault=1c94c4&#038;iconColorDefault=ef8c08&#038;bgColorHover=fdf5ce&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=100&#038;borderColorHover=fbcb09&#038;fcHover=c77405&#038;iconColorHover=ef8c08&#038;bgColorActive=ffffff&#038;bgTextureActive=02_glass.png&#038;bgImgOpacityActive=65&#038;borderColorActive=fbd850&#038;fcActive=eb8f00&#038;iconColorActive=ef8c08&#038;bgColorHighlight=ffe45c&#038;bgTextureHighlight=03_highlight_soft.png&#038;bgImgOpacityHighlight=75&#038;borderColorHighlight=fed22f&#038;fcHighlight=363636&#038;iconColorHighlight=228ef1&#038;bgColorError=b81900&#038;bgTextureError=08_diagonals_thick.png&#038;bgImgOpacityError=18&#038;borderColorError=cd0a0a&#038;fcError=ffffff&#038;iconColorError=ffd27a&#038;bgColorOverlay=666666&#038;bgTextureOverlay=08_diagonals_thick.png&#038;bgImgOpacityOverlay=20&#038;opacityOverlay=50&#038;bgColorShadow=000000&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=10&#038;opacityShadow=20&#038;thicknessShadow=5px&#038;offsetTopShadow=-5px&#038;offsetLeftShadow=-5px&#038;cornerRadiusShadow=5px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/ui-lightness-thumb.PNG" width="194" height="178" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/#ffDefault=Segoe+UI%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=333333&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=25&#038;borderColorHeader=333333&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=000000&#038;bgTextureContent=05_inset_soft.png&#038;bgImgOpacityContent=25&#038;borderColorContent=666666&#038;fcContent=ffffff&#038;iconColorContent=cccccc&#038;bgColorDefault=555555&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=20&#038;borderColorDefault=666666&#038;fcDefault=eeeeee&#038;iconColorDefault=cccccc&#038;bgColorHover=0078a3&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=40&#038;borderColorHover=59b4d4&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=f58400&#038;bgTextureActive=05_inset_soft.png&#038;bgImgOpacityActive=30&#038;borderColorActive=ffaf0f&#038;fcActive=ffffff&#038;iconColorActive=222222&#038;bgColorHighlight=eeeeee&#038;bgTextureHighlight=03_highlight_soft.png&#038;bgImgOpacityHighlight=80&#038;borderColorHighlight=cccccc&#038;fcHighlight=2e7db2&#038;iconColorHighlight=4b8e0b&#038;bgColorError=ffc73d&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=40&#038;borderColorError=ffb73d&#038;fcError=111111&#038;iconColorError=a83300&#038;bgColorOverlay=5c5c5c&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=50&#038;opacityOverlay=80&#038;bgColorShadow=cccccc&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=30&#038;opacityShadow=60&#038;thicknessShadow=7px&#038;offsetTopShadow=-7px&#038;offsetLeftShadow=-7px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/ui-darkness-thumb.png" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-darkness/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Smoothness</strong></td>
<td align="center"><strong>Start</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=4px&#038;bgColorHeader=cccccc&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=75&#038;borderColorHeader=aaaaaa&#038;fcHeader=222222&#038;iconColorHeader=222222&#038;bgColorContent=ffffff&#038;bgTextureContent=01_flat.png&#038;bgImgOpacityContent=75&#038;borderColorContent=aaaaaa&#038;fcContent=222222&#038;iconColorContent=222222&#038;bgColorDefault=e6e6e6&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=75&#038;borderColorDefault=d3d3d3&#038;fcDefault=555555&#038;iconColorDefault=888888&#038;bgColorHover=dadada&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=75&#038;borderColorHover=999999&#038;fcHover=212121&#038;iconColorHover=454545&#038;bgColorActive=ffffff&#038;bgTextureActive=02_glass.png&#038;bgImgOpacityActive=65&#038;borderColorActive=aaaaaa&#038;fcActive=212121&#038;iconColorActive=454545&#038;bgColorHighlight=fbf9ee&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=fcefa1&#038;fcHighlight=363636&#038;iconColorHighlight=2e83ff&#038;bgColorError=fef1ec&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=95&#038;borderColorError=cd0a0a&#038;fcError=cd0a0a&#038;iconColorError=cd0a0a&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/smoothness-thumb.PNG" width="194" height="160" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=5px&#038;bgColorHeader=2191c0&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=75&#038;borderColorHeader=4297d7&#038;fcHeader=eaf5f7&#038;iconColorHeader=d8e7f3&#038;bgColorContent=fcfdfd&#038;bgTextureContent=06_inset_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=a6c9e2&#038;fcContent=222222&#038;iconColorContent=0078ae&#038;bgColorDefault=0078ae&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=45&#038;borderColorDefault=77d5f7&#038;fcDefault=ffffff&#038;iconColorDefault=e0fdff&#038;bgColorHover=79c9ec&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=75&#038;borderColorHover=448dae&#038;fcHover=026890&#038;iconColorHover=056b93&#038;bgColorActive=6eac2c&#038;bgTextureActive=12_gloss_wave.png&#038;bgImgOpacityActive=50&#038;borderColorActive=acdd4a&#038;fcActive=ffffff&#038;iconColorActive=f5e175&#038;bgColorHighlight=f8da4e&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=fcd113&#038;fcHighlight=915608&#038;iconColorHighlight=f7a50d&#038;bgColorError=e14f1c&#038;bgTextureError=12_gloss_wave.png&#038;bgImgOpacityError=45&#038;borderColorError=cd0a0a&#038;fcError=ffffff&#038;iconColorError=fcd113&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=75&#038;opacityOverlay=30&#038;bgColorShadow=999999&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=55&#038;opacityShadow=45&#038;thicknessShadow=0px&#038;offsetTopShadow=5px&#038;offsetLeftShadow=5px&#038;cornerRadiusShadow=5px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/start-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/smoothness/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Redmond</strong></td>
<td align="center"><strong>Sunny</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Lucida+Grande,+Lucida+Sans,+Arial,+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=5px&#038;bgColorHeader=5c9ccc&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=55&#038;borderColorHeader=4297d7&#038;fcHeader=ffffff&#038;iconColorHeader=d8e7f3&#038;bgColorContent=fcfdfd&#038;bgTextureContent=06_inset_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=a6c9e2&#038;fcContent=222222&#038;iconColorContent=469bdd&#038;bgColorDefault=dfeffc&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=85&#038;borderColorDefault=c5dbec&#038;fcDefault=2e6e9e&#038;iconColorDefault=6da8d5&#038;bgColorHover=d0e5f5&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=75&#038;borderColorHover=79b7e7&#038;fcHover=1d5987&#038;iconColorHover=217bc0&#038;bgColorActive=f5f8f9&#038;bgTextureActive=06_inset_hard.png&#038;bgImgOpacityActive=100&#038;borderColorActive=79b7e7&#038;fcActive=e17009&#038;iconColorActive=f9bd01&#038;bgColorHighlight=fbec88&#038;bgTextureHighlight=01_flat.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=fad42e&#038;fcHighlight=363636&#038;iconColorHighlight=2e83ff&#038;bgColorError=fef1ec&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=95&#038;borderColorError=cd0a0a&#038;fcError=cd0a0a&#038;iconColorError=cd0a0a&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/redmond-thumb.PNG" width="194" height="154" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Segoe+UI%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=8px&#038;bgColorHeader=817865&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=45&#038;borderColorHeader=494437&#038;fcHeader=ffffff&#038;iconColorHeader=fadc7a&#038;bgColorContent=feeebd&#038;bgTextureContent=03_highlight_soft.png&#038;bgImgOpacityContent=100&#038;borderColorContent=8e846b&#038;fcContent=383838&#038;iconColorContent=d19405&#038;bgColorDefault=fece2f&#038;bgTextureDefault=12_gloss_wave.png&#038;bgImgOpacityDefault=60&#038;borderColorDefault=d19405&#038;fcDefault=4c3000&#038;iconColorDefault=3d3d3d&#038;bgColorHover=ffdd57&#038;bgTextureHover=12_gloss_wave.png&#038;bgImgOpacityHover=70&#038;borderColorHover=a45b13&#038;fcHover=381f00&#038;iconColorHover=bd7b00&#038;bgColorActive=ffffff&#038;bgTextureActive=05_inset_soft.png&#038;bgImgOpacityActive=30&#038;borderColorActive=655e4e&#038;fcActive=0074c7&#038;iconColorActive=eb990f&#038;bgColorHighlight=fff9e5&#038;bgTextureHighlight=12_gloss_wave.png&#038;bgImgOpacityHighlight=90&#038;borderColorHighlight=eeb420&#038;fcHighlight=1f1f1f&#038;iconColorHighlight=ed9f26&#038;bgColorError=d34d17&#038;bgTextureError=07_diagonals_medium.png&#038;bgImgOpacityError=20&#038;borderColorError=ffb73d&#038;fcError=ffffff&#038;iconColorError=ffe180&#038;bgColorOverlay=5c5c5c&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=50&#038;opacityOverlay=80&#038;bgColorShadow=cccccc&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=30&#038;opacityShadow=60&#038;thicknessShadow=7px&#038;offsetTopShadow=-7px&#038;offsetLeftShadow=-7px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/sunny-thumb.png" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/sunny/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Overcast</strong></td>
<td align="center"><strong>Le Frog</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Trebuchet+MS%2C+Helvetica%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=dddddd&#038;bgTextureHeader=02_glass.png&#038;bgImgOpacityHeader=35&#038;borderColorHeader=bbbbbb&#038;fcHeader=444444&#038;iconColorHeader=999999&#038;bgColorContent=c9c9c9&#038;bgTextureContent=05_inset_soft.png&#038;bgImgOpacityContent=50&#038;borderColorContent=aaaaaa&#038;fcContent=333333&#038;iconColorContent=999999&#038;bgColorDefault=eeeeee&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=60&#038;borderColorDefault=cccccc&#038;fcDefault=3383bb&#038;iconColorDefault=70b2e1&#038;bgColorHover=f8f8f8&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=100&#038;borderColorHover=bbbbbb&#038;fcHover=599fcf&#038;iconColorHover=3383bb&#038;bgColorActive=999999&#038;bgTextureActive=06_inset_hard.png&#038;bgImgOpacityActive=75&#038;borderColorActive=999999&#038;fcActive=ffffff&#038;iconColorActive=454545&#038;bgColorHighlight=eeeeee&#038;bgTextureHighlight=01_flat.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=ffffff&#038;fcHighlight=444444&#038;iconColorHighlight=3383bb&#038;bgColorError=c0402a&#038;bgTextureError=01_flat.png&#038;bgImgOpacityError=55&#038;borderColorError=c0402a&#038;fcError=ffffff&#038;iconColorError=fbc856&#038;bgColorOverlay=eeeeee&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=80&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=60&#038;thicknessShadow=4px&#038;offsetTopShadow=-4px&#038;offsetLeftShadow=-4px&#038;cornerRadiusShadow=0pxdow%3D0px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/overcast-thumb.PNG" width="194" height="178" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Lucida+Grande%2C+Lucida+Sans%2C+Arial%2C+sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=10px&#038;bgColorHeader=3a8104&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=33&#038;borderColorHeader=3f7506&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=285c00&#038;bgTextureContent=05_inset_soft.png&#038;bgImgOpacityContent=10&#038;borderColorContent=72b42d&#038;fcContent=ffffff&#038;iconColorContent=72b42d&#038;bgColorDefault=4ca20b&#038;bgTextureDefault=03_highlight_soft.png&#038;bgImgOpacityDefault=60&#038;borderColorDefault=45930b&#038;fcDefault=ffffff&#038;iconColorDefault=ffffff&#038;bgColorHover=4eb305&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=50&#038;borderColorHover=8bd83b&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=285c00&#038;bgTextureActive=04_highlight_hard.png&#038;bgImgOpacityActive=30&#038;borderColorActive=72b42d&#038;fcActive=ffffff&#038;iconColorActive=ffffff&#038;bgColorHighlight=fbf5d0&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=f9dd34&#038;fcHighlight=363636&#038;iconColorHighlight=4eb305&#038;bgColorError=ffdc2e&#038;bgTextureError=08_diagonals_thick.png&#038;bgImgOpacityError=95&#038;borderColorError=fad000&#038;fcError=2b2b2b&#038;iconColorError=cd0a0a&#038;bgColorOverlay=444444&#038;bgTextureOverlay=08_diagonals_thick.png&#038;bgImgOpacityOverlay=15&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=07_diagonals_small.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=30&#038;thicknessShadow=0px&#038;offsetTopShadow=4px&#038;offsetLeftShadow=4px&#038;cornerRadiusShadow=4px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/le-frog-thumb.PNG" width="194" height="169" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/overcast/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/le-frog/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Flick</strong></td>
<td align="center"><strong>Pepper Grinder</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Helvetica%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=2px&#038;bgColorHeader=dddddd&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=50&#038;borderColorHeader=dddddd&#038;fcHeader=444444&#038;iconColorHeader=0073ea&#038;bgColorContent=ffffff&#038;bgTextureContent=01_flat.png&#038;bgImgOpacityContent=75&#038;borderColorContent=dddddd&#038;fcContent=444444&#038;iconColorContent=ff0084&#038;bgColorDefault=f6f6f6&#038;bgTextureDefault=03_highlight_soft.png&#038;bgImgOpacityDefault=100&#038;borderColorDefault=dddddd&#038;fcDefault=0073ea&#038;iconColorDefault=666666&#038;bgColorHover=0073ea&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=25&#038;borderColorHover=0073ea&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=ffffff&#038;bgTextureActive=02_glass.png&#038;bgImgOpacityActive=65&#038;borderColorActive=dddddd&#038;fcActive=ff0084&#038;iconColorActive=454545&#038;bgColorHighlight=ffffff&#038;bgTextureHighlight=01_flat.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=cccccc&#038;fcHighlight=444444&#038;iconColorHighlight=0073ea&#038;bgColorError=ffffff&#038;bgTextureError=01_flat.png&#038;bgImgOpacityError=55&#038;borderColorError=ff0084&#038;fcError=222222&#038;iconColorError=ff0084&#038;bgColorOverlay=eeeeee&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=80&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=60&#038;thicknessShadow=4px&#038;offsetTopShadow=-4px&#038;offsetLeftShadow=-4px&#038;cornerRadiusShadow=0px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/flick-thumb.PNG" width="194" height="160" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Trebuchet+MS%2C+Tahoma%2C+Verdana%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=ffffff&#038;bgTextureHeader=23_fine_grain.png&#038;bgImgOpacityHeader=15&#038;borderColorHeader=d4d1bf&#038;fcHeader=453821&#038;iconColorHeader=b83400&#038;bgColorContent=eceadf&#038;bgTextureContent=23_fine_grain.png&#038;bgImgOpacityContent=10&#038;borderColorContent=d9d6c4&#038;fcContent=1f1f1f&#038;iconColorContent=222222&#038;bgColorDefault=f8f7f6&#038;bgTextureDefault=23_fine_grain.png&#038;bgImgOpacityDefault=10&#038;borderColorDefault=cbc7bd&#038;fcDefault=654b24&#038;iconColorDefault=b83400&#038;bgColorHover=654b24&#038;bgTextureHover=23_fine_grain.png&#038;bgImgOpacityHover=65&#038;borderColorHover=654b24&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=eceadf&#038;bgTextureActive=23_fine_grain.png&#038;bgImgOpacityActive=15&#038;borderColorActive=d9d6c4&#038;fcActive=140f06&#038;iconColorActive=8c291d&#038;bgColorHighlight=f7f3de&#038;bgTextureHighlight=23_fine_grain.png&#038;bgImgOpacityHighlight=15&#038;borderColorHighlight=b2a266&#038;fcHighlight=3a3427&#038;iconColorHighlight=3572ac&#038;bgColorError=b83400&#038;bgTextureError=23_fine_grain.png&#038;bgImgOpacityError=68&#038;borderColorError=681818&#038;fcError=ffffff&#038;iconColorError=fbdb93&#038;bgColorOverlay=6e4f1c&#038;bgTextureOverlay=16_diagonal_maze.png&#038;bgImgOpacityOverlay=20&#038;opacityOverlay=60&#038;bgColorShadow=000000&#038;bgTextureShadow=16_diagonal_maze.png&#038;bgImgOpacityShadow=40&#038;opacityShadow=60&#038;thicknessShadow=5px&#038;offsetTopShadow=0&#038;offsetLeftShadow=-10px&#038;cornerRadiusShadow=18px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/pepper-grinder-thumb.PNG" width="194" height="178" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/flick/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/pepper-grinder/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Eggplant</strong></td>
<td align="center"><strong>Dark Hive</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Lucida+Grande%2C+Lucida+Sans%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=30273a&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=25&#038;borderColorHeader=231d2b&#038;fcHeader=ffffff&#038;iconColorHeader=a8a3ae&#038;bgColorContent=3d3644&#038;bgTextureContent=12_gloss_wave.png&#038;bgImgOpacityContent=30&#038;borderColorContent=7e7783&#038;fcContent=ffffff&#038;iconColorContent=ffffff&#038;bgColorDefault=dcd9de&#038;bgTextureDefault=03_highlight_soft.png&#038;bgImgOpacityDefault=100&#038;borderColorDefault=dcd9de&#038;fcDefault=665874&#038;iconColorDefault=8d78a5&#038;bgColorHover=eae6ea&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=100&#038;borderColorHover=d1c5d8&#038;fcHover=734d99&#038;iconColorHover=734d99&#038;bgColorActive=5f5964&#038;bgTextureActive=03_highlight_soft.png&#038;bgImgOpacityActive=45&#038;borderColorActive=7e7783&#038;fcActive=ffffff&#038;iconColorActive=454545&#038;bgColorHighlight=fafafa&#038;bgTextureHighlight=01_flat.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=ffdb1f&#038;fcHighlight=333333&#038;iconColorHighlight=8d78a5&#038;bgColorError=994d53&#038;bgTextureError=01_flat.png&#038;bgImgOpacityError=55&#038;borderColorError=994d53&#038;fcError=ffffff&#038;iconColorError=ebccce&#038;bgColorOverlay=eeeeee&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=80&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=60&#038;thicknessShadow=4px&#038;offsetTopShadow=-4px&#038;offsetLeftShadow=-4px&#038;cornerRadiusShadow=0px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/eggplant-thumb.PNG" width="194" height="154" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Verdana%2C+Arial%2C+sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=444444&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=44&#038;borderColorHeader=333333&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=000000&#038;bgTextureContent=14_loop.png&#038;bgImgOpacityContent=25&#038;borderColorContent=555555&#038;fcContent=ffffff&#038;iconColorContent=cccccc&#038;bgColorDefault=222222&#038;bgTextureDefault=03_highlight_soft.png&#038;bgImgOpacityDefault=35&#038;borderColorDefault=444444&#038;fcDefault=eeeeee&#038;iconColorDefault=cccccc&#038;bgColorHover=003147&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=33&#038;borderColorHover=0b93d5&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=0972a5&#038;bgTextureActive=04_highlight_hard.png&#038;bgImgOpacityActive=20&#038;borderColorActive=26b3f7&#038;fcActive=ffffff&#038;iconColorActive=222222&#038;bgColorHighlight=eeeeee&#038;bgTextureHighlight=03_highlight_soft.png&#038;bgImgOpacityHighlight=80&#038;borderColorHighlight=cccccc&#038;fcHighlight=2e7db2&#038;iconColorHighlight=4b8e0b&#038;bgColorError=ffc73d&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=40&#038;borderColorError=ffb73d&#038;fcError=111111&#038;iconColorError=a83300&#038;bgColorOverlay=5c5c5c&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=50&#038;opacityOverlay=80&#038;bgColorShadow=cccccc&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=30&#038;opacityShadow=60&#038;thicknessShadow=7px&#038;offsetTopShadow=-7px&#038;offsetLeftShadow=-7px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/dark-hive-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/eggplant/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/dark-hive/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Cupertino</strong></td>
<td align="center"><strong>South Street</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Lucida+Grande%2C+Lucida+Sans%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=deedf7&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=100&#038;borderColorHeader=aed0ea&#038;fcHeader=222222&#038;iconColorHeader=72a7cf&#038;bgColorContent=f2f5f7&#038;bgTextureContent=04_highlight_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=dddddd&#038;fcContent=362b36&#038;iconColorContent=72a7cf&#038;bgColorDefault=d7ebf9&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=80&#038;borderColorDefault=aed0ea&#038;fcDefault=2779aa&#038;iconColorDefault=3d80b3&#038;bgColorHover=e4f1fb&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=100&#038;borderColorHover=74b2e2&#038;fcHover=0070a3&#038;iconColorHover=2694e8&#038;bgColorActive=3baae3&#038;bgTextureActive=02_glass.png&#038;bgImgOpacityActive=50&#038;borderColorActive=2694e8&#038;fcActive=ffffff&#038;iconColorActive=ffffff&#038;bgColorHighlight=ffef8f&#038;bgTextureHighlight=03_highlight_soft.png&#038;bgImgOpacityHighlight=25&#038;borderColorHighlight=f9dd34&#038;fcHighlight=363636&#038;iconColorHighlight=2e83ff&#038;bgColorError=cd0a0a&#038;bgTextureError=01_flat.png&#038;bgImgOpacityError=15&#038;borderColorError=cd0a0a&#038;fcError=ffffff&#038;iconColorError=ffffff&#038;bgColorOverlay=eeeeee&#038;bgTextureOverlay=08_diagonals_thick.png&#038;bgImgOpacityOverlay=90&#038;opacityOverlay=80&#038;bgColorShadow=000000&#038;bgTextureShadow=04_highlight_hard.png&#038;bgImgOpacityShadow=70&#038;opacityShadow=30&#038;thicknessShadow=7px&#038;offsetTopShadow=-7px&#038;offsetLeftShadow=-7px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/cupertino-thumb.PNG" width="194" height="154" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=segoe+ui%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=ece8da&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=100&#038;borderColorHeader=d4ccb0&#038;fcHeader=433f38&#038;iconColorHeader=847e71&#038;bgColorContent=f5f3e5&#038;bgTextureContent=04_highlight_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=dfd9c3&#038;fcContent=312e25&#038;iconColorContent=808080&#038;bgColorDefault=459e00&#038;bgTextureDefault=04_highlight_hard.png&#038;bgImgOpacityDefault=15&#038;borderColorDefault=327E04&#038;fcDefault=ffffff&#038;iconColorDefault=eeeeee&#038;bgColorHover=67b021&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=25&#038;borderColorHover=327E04&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=fafaf4&#038;bgTextureActive=04_highlight_hard.png&#038;bgImgOpacityActive=100&#038;borderColorActive=d4ccb0&#038;fcActive=459e00&#038;iconColorActive=8DC262&#038;bgColorHighlight=fcf0ba&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=e8e1b5&#038;fcHighlight=363636&#038;iconColorHighlight=8DC262&#038;bgColorError=ffedad&#038;bgTextureError=03_highlight_soft.png&#038;bgImgOpacityError=95&#038;borderColorError=e3a345&#038;fcError=cd5c0a&#038;iconColorError=cd0a0a&#038;bgColorOverlay=2b2922&#038;bgTextureOverlay=05_inset_soft.png&#038;bgImgOpacityOverlay=15&#038;opacityOverlay=90&#038;bgColorShadow=cccccc&#038;bgTextureShadow=04_highlight_hard.png&#038;bgImgOpacityShadow=95&#038;opacityShadow=20&#038;thicknessShadow=12px&#038;offsetTopShadow=-12px&#038;offsetLeftShadow=-12px&#038;cornerRadiusShadow=10px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/south-street-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/cupertino/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/south-street/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Blitzer</strong></td>
<td align="center"><strong>Humanity</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Arial,sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=cc0000&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=15&#038;borderColorHeader=e3a1a1&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=ffffff&#038;bgTextureContent=01_flat.png&#038;bgImgOpacityContent=75&#038;borderColorContent=eeeeee&#038;fcContent=333333&#038;iconColorContent=cc0000&#038;bgColorDefault=eeeeee&#038;bgTextureDefault=04_highlight_hard.png&#038;bgImgOpacityDefault=100&#038;borderColorDefault=d8dcdf&#038;fcDefault=004276&#038;iconColorDefault=cc0000&#038;bgColorHover=f6f6f6&#038;bgTextureHover=04_highlight_hard.png&#038;bgImgOpacityHover=100&#038;borderColorHover=cdd5da&#038;fcHover=111111&#038;iconColorHover=cc0000&#038;bgColorActive=ffffff&#038;bgTextureActive=01_flat.png&#038;bgImgOpacityActive=65&#038;borderColorActive=eeeeee&#038;fcActive=cc0000&#038;iconColorActive=cc0000&#038;bgColorHighlight=fbf8ee&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=fcd3a1&#038;fcHighlight=444444&#038;iconColorHighlight=004276&#038;bgColorError=f3d8d8&#038;bgTextureError=08_diagonals_thick.png&#038;bgImgOpacityError=75&#038;borderColorError=cc0000&#038;fcError=2e2e2e&#038;iconColorError=cc0000&#038;bgColorOverlay=a6a6a6&#038;bgTextureOverlay=09_dots_small.png&#038;bgImgOpacityOverlay=65&#038;opacityOverlay=40&#038;bgColorShadow=333333&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=10&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/blitzer-thumb.PNG" width="194" height="160" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?tr=ffDefault=Helvetica,Arial,sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=cb842e&#038;bgTextureHeader=02_glass.png&#038;bgImgOpacityHeader=25&#038;borderColorHeader=d49768&#038;fcHeader=ffffff&#038;iconColorHeader=ffffff&#038;bgColorContent=f4f0ec&#038;bgTextureContent=05_inset_soft.png&#038;bgImgOpacityContent=100&#038;borderColorContent=e0cfc2&#038;fcContent=1e1b1d&#038;iconColorContent=c47a23&#038;bgColorDefault=ede4d4&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=70&#038;borderColorDefault=cdc3b7&#038;fcDefault=3f3731&#038;iconColorDefault=f08000&#038;bgColorHover=f5f0e5&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=100&#038;borderColorHover=f5ad66&#038;fcHover=a46313&#038;iconColorHover=f08000&#038;bgColorActive=f4f0ec&#038;bgTextureActive=04_highlight_hard.png&#038;bgImgOpacityActive=100&#038;borderColorActive=e0cfc2&#038;fcActive=b85700&#038;iconColorActive=f35f07&#038;bgColorHighlight=f5f5b5&#038;bgTextureHighlight=04_highlight_hard.png&#038;bgImgOpacityHighlight=75&#038;borderColorHighlight=d9bb73&#038;fcHighlight=060200&#038;iconColorHighlight=cb672b&#038;bgColorError=fee4bd&#038;bgTextureError=04_highlight_hard.png&#038;bgImgOpacityError=65&#038;borderColorError=f8893f&#038;fcError=592003&#038;iconColorError=ff7519&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=75&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=75&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/humanity-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/blitzer/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/humanity/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Hot Sneaks</strong></td>
<td align="center"><strong>Excite Bike</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Gill+Sans,Arial,sans-serif&#038;fwDefault=bold&#038;fsDefault=1.2em&#038;cornerRadius=4px&#038;bgColorHeader=35414f&#038;bgTextureHeader=09_dots_small.png&#038;bgImgOpacityHeader=35&#038;borderColorHeader=2c4359&#038;fcHeader=e1e463&#038;iconColorHeader=e1e463&#038;bgColorContent=ffffff&#038;bgTextureContent=01_flat.png&#038;bgImgOpacityContent=75&#038;borderColorContent=aaaaaa&#038;fcContent=2c4359&#038;iconColorContent=c02669&#038;bgColorDefault=93c3cd&#038;bgTextureDefault=07_diagonals_small.png&#038;bgImgOpacityDefault=50&#038;borderColorDefault=93c3cd&#038;fcDefault=333333&#038;iconColorDefault=ffffff&#038;bgColorHover=ccd232&#038;bgTextureHover=07_diagonals_small.png&#038;bgImgOpacityHover=75&#038;borderColorHover=999999&#038;fcHover=212121&#038;iconColorHover=454545&#038;bgColorActive=db4865&#038;bgTextureActive=07_diagonals_small.png&#038;bgImgOpacityActive=40&#038;borderColorActive=ff6b7f&#038;fcActive=ffffff&#038;iconColorActive=ffffff&#038;bgColorHighlight=ffff38&#038;bgTextureHighlight=10_dots_medium.png&#038;bgImgOpacityHighlight=80&#038;borderColorHighlight=b4d100&#038;fcHighlight=363636&#038;iconColorHighlight=88a206&#038;bgColorError=ff3853&#038;bgTextureError=07_diagonals_small.png&#038;bgImgOpacityError=50&#038;borderColorError=ff6b7f&#038;fcError=ffffff&#038;iconColorError=ffeb33&#038;bgColorOverlay=f7f7ba&#038;bgTextureOverlay=11_white_lines.png&#038;bgImgOpacityOverlay=85&#038;opacityOverlay=80&#038;bgColorShadow=ba9217&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=75&#038;opacityShadow=20&#038;thicknessShadow=10px&#038;offsetTopShadow=8px&#038;offsetLeftShadow=8px&#038;cornerRadiusShadow=5px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/hot-sneaks-thumb.PNG" width="194" height="164" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=segoe+ui,+Arial,+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=3px&#038;bgColorHeader=f9f9f9&#038;bgTextureHeader=03_highlight_soft.png&#038;bgImgOpacityHeader=100&#038;borderColorHeader=cccccc&#038;fcHeader=e69700&#038;iconColorHeader=5fa5e3&#038;bgColorContent=eeeeee&#038;bgTextureContent=06_inset_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=aaaaaa&#038;fcContent=222222&#038;iconColorContent=0a82eb&#038;bgColorDefault=1484e6&#038;bgTextureDefault=08_diagonals_thick.png&#038;bgImgOpacityDefault=22&#038;borderColorDefault=ffffff&#038;fcDefault=ffffff&#038;iconColorDefault=fcdd4a&#038;bgColorHover=2293f7&#038;bgTextureHover=08_diagonals_thick.png&#038;bgImgOpacityHover=26&#038;borderColorHover=2293f7&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=e69700&#038;bgTextureActive=08_diagonals_thick.png&#038;bgImgOpacityActive=20&#038;borderColorActive=e69700&#038;fcActive=ffffff&#038;iconColorActive=ffffff&#038;bgColorHighlight=c5ddfc&#038;bgTextureHighlight=07_diagonals_small.png&#038;bgImgOpacityHighlight=25&#038;borderColorHighlight=ffffff&#038;fcHighlight=333333&#038;iconColorHighlight=0b54d5&#038;bgColorError=e69700&#038;bgTextureError=08_diagonals_thick.png&#038;bgImgOpacityError=20&#038;borderColorError=e69700&#038;fcError=ffffff&#038;iconColorError=ffffff&#038;bgColorOverlay=e6b900&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=30&#038;bgColorShadow=e69700&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=20&#038;thicknessShadow=0px&#038;offsetTopShadow=6px&#038;offsetLeftShadow=6px&#038;cornerRadiusShadow=3px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/excite-bike-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/hot-sneaks/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/excite-bike/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Vader</strong></td>
<td align="center"><strong>Dot Luv</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?tr&#038;ffDefault=Helvetica,+Arial,+sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1&#038;fsDefaultUnit=em&#038;cornerRadius=5&#038;cornerRadiusUnit=px&#038;bgColorHeader=888888&#038;bgTextureHeader=04_highlight_hard.png&#038;bgImgOpacityHeader=15&#038;borderColorHeader=404040&#038;fcHeader=ffffff&#038;iconColorHeader=cccccc&#038;bgColorContent=121212&#038;bgTextureContent=12_gloss_wave.png&#038;bgImgOpacityContent=16&#038;borderColorContent=404040&#038;fcContent=eeeeee&#038;iconColorContent=bbbbbb&#038;bgColorDefault=adadad&#038;bgTextureDefault=03_highlight_soft.png&#038;bgImgOpacityDefault=35&#038;borderColorDefault=cccccc&#038;fcDefault=333333&#038;iconColorDefault=666666&#038;bgColorHover=dddddd&#038;bgTextureHover=03_highlight_soft.png&#038;bgImgOpacityHover=60&#038;borderColorHover=dddddd&#038;fcHover=000000&#038;iconColorHover=c98000&#038;bgColorActive=121212&#038;bgTextureActive=05_inset_soft.png&#038;bgImgOpacityActive=15&#038;borderColorActive=000000&#038;fcActive=ffffff&#038;iconColorActive=f29a00&#038;bgColorHighlight=555555&#038;bgTextureHighlight=04_highlight_hard.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=404040&#038;fcHighlight=cccccc&#038;iconColorHighlight=aaaaaa&#038;bgColorError=fef1ec&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=95&#038;borderColorError=cd0a0a&#038;fcError=cd0a0a&#038;iconColorError=cd0a0a" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/vader-thumb.PNG" width="194" height="165" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Arial,+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.3em&#038;cornerRadius=4px&#038;bgColorHeader=0b3e6f&#038;bgTextureHeader=08_diagonals_thick.png&#038;bgImgOpacityHeader=15&#038;borderColorHeader=0b3e6f&#038;fcHeader=f6f6f6&#038;iconColorHeader=98d2fb&#038;bgColorContent=111111&#038;bgTextureContent=12_gloss_wave.png&#038;bgImgOpacityContent=20&#038;borderColorContent=000000&#038;fcContent=d9d9d9&#038;iconColorContent=9ccdfc&#038;bgColorDefault=333333&#038;bgTextureDefault=09_dots_small.png&#038;bgImgOpacityDefault=20&#038;borderColorDefault=333333&#038;fcDefault=ffffff&#038;iconColorDefault=9ccdfc&#038;bgColorHover=00498f&#038;bgTextureHover=09_dots_small.png&#038;bgImgOpacityHover=40&#038;borderColorHover=222222&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=292929&#038;bgTextureActive=01_flat.png&#038;bgImgOpacityActive=40&#038;borderColorActive=096ac8&#038;fcActive=75abff&#038;iconColorActive=00498f&#038;bgColorHighlight=0b58a2&#038;bgTextureHighlight=10_dots_medium.png&#038;bgImgOpacityHighlight=30&#038;borderColorHighlight=052f57&#038;fcHighlight=ffffff&#038;iconColorHighlight=ffffff&#038;bgColorError=a32d00&#038;bgTextureError=09_dots_small.png&#038;bgImgOpacityError=30&#038;borderColorError=cd0a0a&#038;fcError=ffffff&#038;iconColorError=ffffff&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/dot-luv-thumb.PNG" width="194" height="162" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/vader/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/dot-luv-grinder/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Mint Choc</strong></td>
<td align="center"><strong>Black Tie</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Segoe+UI%2C+Helvetica%2C+Arial%2C+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=4px&#038;bgColorHeader=453326&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=25&#038;borderColorHeader=695649&#038;fcHeader=e3ddc9&#038;iconColorHeader=e3ddc9&#038;bgColorContent=201913&#038;bgTextureContent=05_inset_soft.png&#038;bgImgOpacityContent=10&#038;borderColorContent=9c947c&#038;fcContent=ffffff&#038;iconColorContent=222222&#038;bgColorDefault=1c160d&#038;bgTextureDefault=12_gloss_wave.png&#038;bgImgOpacityDefault=20&#038;borderColorDefault=695444&#038;fcDefault=9bcc60&#038;iconColorDefault=9bcc60&#038;bgColorHover=44372c&#038;bgTextureHover=12_gloss_wave.png&#038;bgImgOpacityHover=30&#038;borderColorHover=9c947c&#038;fcHover=baec7e&#038;iconColorHover=add978&#038;bgColorActive=201913&#038;bgTextureActive=03_highlight_soft.png&#038;bgImgOpacityActive=20&#038;borderColorActive=9c947c&#038;fcActive=e3ddc9&#038;iconColorActive=e3ddc9&#038;bgColorHighlight=619226&#038;bgTextureHighlight=03_highlight_soft.png&#038;bgImgOpacityHighlight=20&#038;borderColorHighlight=add978&#038;fcHighlight=ffffff&#038;iconColorHighlight=ffffff&#038;bgColorError=5f391b&#038;bgTextureError=02_glass.png&#038;bgImgOpacityError=15&#038;borderColorError=5f391b&#038;fcError=ffffff&#038;iconColorError=f1fd86&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=01_flat.png&#038;bgImgOpacityOverlay=0&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/mint-choc-thumb.PNG" width="194" height="160" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Verdana,+Arial,+sans-serif&#038;fwDefault=normal&#038;fsDefault=1.1em&#038;cornerRadius=4px&#038;bgColorHeader=333333&#038;bgTextureHeader=08_diagonals_thick.png&#038;bgImgOpacityHeader=8&#038;borderColorHeader=a3a3a3&#038;fcHeader=eeeeee&#038;iconColorHeader=bbbbbb&#038;bgColorContent=f9f9f9&#038;bgTextureContent=04_highlight_hard.png&#038;bgImgOpacityContent=100&#038;borderColorContent=cccccc&#038;fcContent=222222&#038;iconColorContent=222222&#038;bgColorDefault=111111&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=40&#038;borderColorDefault=777777&#038;fcDefault=e3e3e3&#038;iconColorDefault=ededed&#038;bgColorHover=1c1c1c&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=55&#038;borderColorHover=000000&#038;fcHover=ffffff&#038;iconColorHover=ffffff&#038;bgColorActive=ffffff&#038;bgTextureActive=01_flat.png&#038;bgImgOpacityActive=65&#038;borderColorActive=cccccc&#038;fcActive=222222&#038;iconColorActive=222222&#038;bgColorHighlight=ffeb80&#038;bgTextureHighlight=06_inset_hard.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=ffde2e&#038;fcHighlight=363636&#038;iconColorHighlight=4ca300&#038;bgColorError=cd0a0a&#038;bgTextureError=06_inset_hard.png&#038;bgImgOpacityError=45&#038;borderColorError=9e0505&#038;fcError=ffffff&#038;iconColorError=ffcf29&#038;bgColorOverlay=aaaaaa&#038;bgTextureOverlay=04_highlight_hard.png&#038;bgImgOpacityOverlay=40&#038;opacityOverlay=30&#038;bgColorShadow=aaaaaa&#038;bgTextureShadow=03_highlight_soft.png&#038;bgImgOpacityShadow=50&#038;opacityShadow=20&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=8px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/black-tie-thumb.PNG" width="194" height="160" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/mint-choc/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/black-tie/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td align="center"><strong>Trontastic</strong></td>
<td align="center"><strong>Swanky Purse</strong></td>
<tr valign="top">
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Segoe+UI,+Helvetica,+Arial,+sans-serif&#038;fwDefault=bold&#038;fsDefault=1.1em&#038;cornerRadius=6px&#038;bgColorHeader=9fda58&#038;bgTextureHeader=12_gloss_wave.png&#038;bgImgOpacityHeader=85&#038;borderColorHeader=000000&#038;fcHeader=222222&#038;iconColorHeader=1f1f1f&#038;bgColorContent=000000&#038;bgTextureContent=12_gloss_wave.png&#038;bgImgOpacityContent=55&#038;borderColorContent=4a4a4a&#038;fcContent=ffffff&#038;iconColorContent=9fda58&#038;bgColorDefault=0a0a0a&#038;bgTextureDefault=02_glass.png&#038;bgImgOpacityDefault=40&#038;borderColorDefault=1b1613&#038;fcDefault=b8ec79&#038;iconColorDefault=b8ec79&#038;bgColorHover=000000&#038;bgTextureHover=02_glass.png&#038;bgImgOpacityHover=60&#038;borderColorHover=000000&#038;fcHover=96f226&#038;iconColorHover=b8ec79&#038;bgColorActive=4c4c4c&#038;bgTextureActive=01_flat.png&#038;bgImgOpacityActive=0&#038;borderColorActive=696969&#038;fcActive=ffffff&#038;iconColorActive=ffffff&#038;bgColorHighlight=f1fbe5&#038;bgTextureHighlight=02_glass.png&#038;bgImgOpacityHighlight=55&#038;borderColorHighlight=8cce3b&#038;fcHighlight=030303&#038;iconColorHighlight=000000&#038;bgColorError=f6ecd5&#038;bgTextureError=12_gloss_wave.png&#038;bgImgOpacityError=95&#038;borderColorError=f1ac88&#038;fcError=74736d&#038;iconColorError=cd0a0a&#038;bgColorOverlay=262626&#038;bgTextureOverlay=07_diagonals_small.png&#038;bgImgOpacityOverlay=50&#038;opacityOverlay=30&#038;bgColorShadow=303030&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=0&#038;opacityShadow=50&#038;thicknessShadow=6px&#038;offsetTopShadow=-6px&#038;offsetLeftShadow=-6px&#038;cornerRadiusShadow=12px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/trontastic-thumb.PNG" width="194" height="160" /></a></td>
<td align="center"><a href="http://jqueryui.com/themeroller/?ffDefault=Georgia%2C+Verdana%2CArial%2Csans-serif&#038;fwDefault=bold&#038;fsDefault=1.2em&#038;cornerRadius=5px&#038;bgColorHeader=261803&#038;bgTextureHeader=13_diamond.png&#038;bgImgOpacityHeader=8&#038;borderColorHeader=baaa5a&#038;fcHeader=eacd86&#038;iconColorHeader=e9cd86&#038;bgColorContent=443113&#038;bgTextureContent=13_diamond.png&#038;bgImgOpacityContent=8&#038;borderColorContent=efec9f&#038;fcContent=efec9f&#038;iconColorContent=efec9f&#038;bgColorDefault=4f4221&#038;bgTextureDefault=13_diamond.png&#038;bgImgOpacityDefault=10&#038;borderColorDefault=362917&#038;fcDefault=f8eec9&#038;iconColorDefault=e8e2b5&#038;bgColorHover=675423&#038;bgTextureHover=13_diamond.png&#038;bgImgOpacityHover=25&#038;borderColorHover=362917&#038;fcHover=f8eec9&#038;iconColorHover=f2ec64&#038;bgColorActive=443113&#038;bgTextureActive=13_diamond.png&#038;bgImgOpacityActive=8&#038;borderColorActive=efec9f&#038;fcActive=f9f2bd&#038;iconColorActive=f9f2bd&#038;bgColorHighlight=d5ac5d&#038;bgTextureHighlight=13_diamond.png&#038;bgImgOpacityHighlight=25&#038;borderColorHighlight=362917&#038;fcHighlight=060200&#038;iconColorHighlight=070603&#038;bgColorError=fee4bd&#038;bgTextureError=04_highlight_hard.png&#038;bgImgOpacityError=65&#038;borderColorError=c26629&#038;fcError=803f1e&#038;iconColorError=ff7519&#038;bgColorOverlay=372806&#038;bgTextureOverlay=13_diamond.png&#038;bgImgOpacityOverlay=20&#038;opacityOverlay=80&#038;bgColorShadow=ddd4b0&#038;bgTextureShadow=01_flat.png&#038;bgImgOpacityShadow=75&#038;opacityShadow=30&#038;thicknessShadow=8px&#038;offsetTopShadow=-8px&#038;offsetLeftShadow=-8px&#038;cornerRadiusShadow=12px" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/10/swanky-purse-thumb.PNG" width="194" height="164" /></a></td>
</tr>
<tr>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/trontastic/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
<td align="center" height="40" valign="middle">
<input type="text" value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/swanky-purse/jquery-ui.css" onfocus="this.select();" style="width: 189px;" /></td>
</tr>
</table>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/">Do you know about this undocumented Google CDN feature?</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/' rel='bookmark' title='Permanent Link: 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/2008/08/13/how-to-easily-enhance-your-existing-tables-with-simple-css/' rel='bookmark' title='Permanent Link: How to easily enhance your existing tables with simple CSS'>How to easily enhance your existing tables with simple CSS</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/10/11/do-you-know-about-this-undocumented-google-cdn-feature/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>Updated: See how I used Firebug to learn jQuery</title>
		<link>http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/</link>
		<comments>http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 05:44:41 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=908</guid>
		<description><![CDATA[It was great to see all the positive responses to the screencast I recently recorded with Craig Shoemaker on how to use Firebug’s console to learn jQuery. That being my first screencast, I really appreciate all of your support. However, you almost unanimously commented that it was too difficult to read the commands typed at [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">Updated: See how I used Firebug to learn jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/2008/01/11/highslide-js-net-updated-v05/' rel='bookmark' title='Permanent Link: Highslide JS .NET Updated (v0.5)'>Highslide JS .NET Updated (v0.5)</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It was great to see all the positive responses to the screencast I recently recorded with Craig Shoemaker on how to use Firebug’s console to learn jQuery. That being my first screencast, I really appreciate all of your support.</p>
<p>However, you almost unanimously commented that it was too difficult to read the commands typed at the console, and you were right. So, Craig and I re-recorded the entire thing, paying extra attention to the legibility of the end result.</p>
<p>Craig also managed to edit the same content down to 9:59m this time, so you can watch it on YouTube if you prefer:</p>
<p><object width="492" height="389"><param name="movie" value="http://www.youtube.com/v/JB6MIV_lHI0&#038;hl=en&#038;fs=1&#038;rel=0&#038;ap=%2526fmt%3D18"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/JB6MIV_lHI0&#038;hl=en&#038;fs=1&#038;rel=0&#038;ap=%2526fmt%3D18" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="492" height="389"></embed></object></p>
<p>If the HQ version of the YouTube video still isn’t legible enough for you, <a href="http://weblogs.asp.net/craigshoemaker/archive/2009/09/18/updated-video-for-using-firebug-and-jquery-post.aspx" target="_blank">Craig also made a full resolution WMV available as well</a>.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">Updated: See how I used Firebug to learn jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='Permanent Link: See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/2008/01/11/highslide-js-net-updated-v05/' rel='bookmark' title='Permanent Link: Highslide JS .NET Updated (v0.5)'>Highslide JS .NET Updated (v0.5)</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>See how I used Firebug to learn jQuery</title>
		<link>http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/</link>
		<comments>http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 15:42:59 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/</guid>
		<description><![CDATA[UPDATE: We&#8217;ve recorded a higher quality version of this screencast. When I hear that someone’s having trouble learning JavaScript or jQuery, my first suggestion to them is always the same: install Firebug and experiment at the console. Whether you’re an experienced JavaScript developer or haven’t written a single line of client-side code, the interactive nature [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/">See how I used Firebug to learn jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2007/03/06/debug-and-explore-aspnet-ajax-with-firebug/' rel='bookmark' title='Permanent Link: Debug and explore AJAX with FireBug'>Debug and explore AJAX with FireBug</a></li>
<li><a href='http://encosia.com/2009/06/20/hear-me-talk-about-jquery-on-the-polymorphic-podcast/' rel='bookmark' title='Permanent Link: Hear me talk about jQuery on the Polymorphic Podcast'>Hear me talk about jQuery on the Polymorphic Podcast</a></li>
<li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:</strong> <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">We&#8217;ve recorded a higher quality version of this screencast</a>.</p>
<p>When I hear that someone’s having trouble learning JavaScript or jQuery, my first suggestion to them is always the same: <strong>install Firebug and experiment at the console</strong>. Whether you’re an experienced JavaScript developer or haven’t written a single line of client-side code, <a href="http://www.codinghorror.com/blog/archives/001216.html" target="_blank">the interactive nature of a command-line is one of the fastest ways to learn</a>.</p>
<p>To demonstrate just how effective Firebug’s console can be, <a href="http://weblogs.asp.net/craigshoemaker/archive/2009/08/04/using-firebug-and-jquery.aspx" target="_blank">Craig Shoemaker</a> and I recorded a short screencast on the topic. If you’re not taking advantage of this technique, be sure to take a minute (well, 16) and check it out:</p>
<p><strike><a title="http://polymorphicpodcast.com/podcast/video/firebug-and-jquery/" href="http://polymorphicpodcast.com/podcast/video/firebug-and-jquery/">http://polymorphicpodcast.com/podcast/video/firebug-and-jquery/</a></strike></p>
<p><a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/">http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/</a></p>
<p>Question: Would you like to see more screencasts similar to this one?</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/">See how I used Firebug to learn jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2007/03/06/debug-and-explore-aspnet-ajax-with-firebug/' rel='bookmark' title='Permanent Link: Debug and explore AJAX with FireBug'>Debug and explore AJAX with FireBug</a></li>
<li><a href='http://encosia.com/2009/06/20/hear-me-talk-about-jquery-on-the-polymorphic-podcast/' rel='bookmark' title='Permanent Link: Hear me talk about jQuery on the Polymorphic Podcast'>Hear me talk about jQuery on the Polymorphic Podcast</a></li>
<li><a href='http://encosia.com/2008/10/10/altnet-podcast-jquery-in-aspnet/' rel='bookmark' title='Permanent Link: Alt.NET Podcast &ndash; jQuery in ASP.NET'>Alt.NET Podcast &ndash; jQuery in ASP.NET</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/08/10/see-how-i-used-firebug-to-learn-jquery/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Simplify calling ASP.NET AJAX services from jQuery</title>
		<link>http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/</link>
		<comments>http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 17:11:37 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=888</guid>
		<description><![CDATA[As jQuery’s popularity in the .NET community has risen over the past year, one recurring theme I’ve seen is the desire to refactor away the details of using it to call ASP.NET AJAX services. Whether through helper function or specialized jQuery plugin, I’ve seen numerous methods proposed and/or in use. Personally, the syntax never bothered [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/">Simplify calling ASP.NET AJAX services from jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Permanent Link: 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/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Permanent Link: Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
<li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 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>As jQuery’s popularity in the .NET community has risen over the past year, one recurring theme I’ve seen is the desire to refactor away the details of using it to call ASP.NET AJAX services. Whether through helper function or specialized jQuery plugin, I’ve seen numerous methods proposed and/or in use.</p>
<p>Personally, the syntax never bothered me. The contentType parameter is ugly, but I have a Visual Studio code snippet for the $.ajax call and rarely think about it.</p>
<p>That came to an end earlier this year, when I started using dataFilter. I needed to <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">isolate my code from the “.d” issue</a>, and wanted to <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/" target="_blank">take advantage of browser-native JSON parsing</a> in Firefox 3.5 and IE8, which required a bulky dataFilter.</p>
<p>Repeating that entire callback function in every $.ajax call was not acceptable. So, I was happy to learn that jQuery provides an excellent solution for consolidating settings to be used in multiple instances of $.ajax.</p>
<p>In this post, I’ll show you <strong>how to use that consolidation feature</strong>, and exactly how I am now using that to <strong>more simply call ASP.NET AJAX services with jQuery</strong>.</p>
<h3>Configuring $.ajax’s default settings</h3>
<p>Rather than wrapping the $.ajax call in a plugin or helper function, jQuery provides a built-in solution that I think is a better alternative:&#160; <a href="http://docs.jquery.com/Ajax/jQuery.ajaxSetup" target="_blank">$.ajaxSetup</a>.</p>
<p>$.ajaxSetup accepts an array of settings that allows you to supply defaults for any of the parameters that you would set in an $.ajax call. Settings like <strong>contentType</strong>, <strong>type</strong>, and <strong>dataFilter</strong> are all fair game, for example.</p>
<p>Using this function, it’s easy to set jQuery’s $.ajax defaults to match <a href="http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/" target="_blank">the refined settings that we worked out together last year</a>:</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: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Because <strong>parameters to</strong> <strong>$.ajax override these defaults</strong>, presetting “data” to an empty JSON string is safe. Any $.ajax call that does specify a data parameter will function as expected, since the default will be ignored.</p>
<p>The particular issue caused by forgetting the empty data parameter can be difficult to track down, and only shows up after you’ve deployed your application to IIS. So, having the default as a safety net is recommended.</p>
<h3>Adding JSON parsing improvements</h3>
<p>Because $.ajaxSetup also supports setting a dataFilter, adding <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">the “.d” isolation</a> and <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/" target="_blank">browser-native JSON parsing</a> from my last two posts is easy:</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: #003366; font-weight: bold;">var</span> msg<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> <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>
      msg <span style="color: #339933;">=</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>
      msg <span style="color: #339933;">=</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>
&nbsp;
    <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></pre></div></div>

<p>This dataFilter processing is actually what pushed me to start using $.ajaxSetup in all of my own projects. It was one thing to accept multiple contentType and method declarations, but repeating the dataFilter for every $.ajax call was more than I could handle.</p>
<h3>Putting it to work</h3>
<p>With the ASP.NET AJAX defaults set in $.ajaxSetup, <strong>all that’s required to call a “ScriptService” or page method is the URL and a success callback</strong>:</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;">&quot;HelloWorld.asmx/Hello&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: #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, even the success callback is optional. For example, if you were periodically pinging a “heartbeat” service to keep the user’s session alive, $.ajax would only need the service&#8217;s URI.</p>
<p>This more concise syntax makes your service calls <em>far</em> more readable, especially for developers who aren’t familiar with the content-type required by ASP.NET AJAX. </p>
<h3>Caution: Sometimes it works too well</h3>
<p>While this is a handy way to simplify calls to ASP.NET AJAX services, do understand that <strong>$.ajaxSetup applies to all of jQuery’s AJAX derivatives</strong>. Setting the default HTTP method and content-type may also impact code and plugins that use jQuery’s built-in communication functionality (e.g. $.getJSON, $.post, etc).</p>
<p>For example, I often <a href="http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/" target="_blank">use jTemplates as a client-side templating solution</a>. Because its processTemplateURL routine relies on $.ajax to retrieve remote template files, setting the ASP.NET AJAX content-type and POST method in $.ajaxSetup breaks that functionality of jTemplates.</p>
<p>Fixing that problem wasn’t difficult, but it also wasn’t immediately obvious what had caused the issue in the first place. In my experience using this technique, the undesirable side effects are rare enough that it’s not a serious concern, but do be aware of the potential.</p>
<h3>Conclusion</h3>
<p>I’ve been using this in production for several months now, with great results. Users have noticed the increased speed that came with browser-native JSON parsing, the “.d” isolation has reduced regression errors due to some code we run on both 2.0 and 3.5 servers, and <strong>it requires less effort on my part to do all that</strong>.</p>
<p>What do you think? Is this helpful?</p>
<p>Would a Visual Studio template with this rolled in be something you would use?</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/">Simplify calling ASP.NET AJAX services from jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Permanent Link: 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/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Permanent Link: Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
<li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 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>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/feed/</wfw:commentRss>
		<slash:comments>65</slash:comments>
		</item>
		<item>
		<title>Improving jQuery’s JSON performance and security</title>
		<link>http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/</link>
		<comments>http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 13:00:02 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=886</guid>
		<description><![CDATA[When you’re working with JSON, performance and security are often opposing, yet equally important concerns. One of these areas of contention is handling the JSON strings returned by a server. Most JavaScript libraries do a great job of abstracting away the details, but the underlying process has long been a frustrating exercise in compromise. On [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">Improving jQuery’s JSON performance and security</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/' rel='bookmark' title='Permanent Link: Never worry about ASP.NET AJAX&#8217;s .d again'>Never worry about ASP.NET AJAX&#8217;s .d again</a></li>
<li><a href='http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Permanent Link: Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
<li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 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>When you’re working with JSON, <strong>performance</strong> and <strong>security</strong> are often opposing, yet equally important concerns. One of these areas of contention is handling the JSON strings returned by a server. Most JavaScript libraries do a great job of abstracting away the details, but the underlying process has long been a frustrating exercise in compromise.</p>
<p>On one hand, eval() is the fastest widely available method, <a href="http://yuiblog.com/blog/2007/04/10/json-and-browser-security/" target="_blank">but it is not safe</a>.</p>
<p>On the other hand, textual JSON parsers written in JavaScript may be much safer, but are <strong>dramatically slower</strong>. In client-side situations, <a href="http://encosia.com/2009/06/09/11-keystrokes-that-made-my-jquery-selector-run-10x-faster/" target="_blank">where milliseconds count</a>, such a large performance overhead is typically too prohibitive to accept.</p>
<p>Recently, an exciting new alternative has emerged: <strong>browser-native JSON parsing</strong>. Integrating JSON parsing as part of the browser’s implementation of JavaScript allows for using the more secure parsing method, <em>and</em> even provides performance faster than eval() offers.</p>
<p>To take advantage of that, this post will show you how to <strong>detect whether or not a browser supports native JSON parsing</strong>, and how to <strong>force jQuery to use browser-native parsing</strong> in its $.ajax calls when it is available.</p>
<h3>Native JSON parsing in the browser</h3>
<p>Previously known as ECMAScript 3.1, ECMAScript “Fifth Edition” (the specification that JavaScript implements) formally codifies a native JSON parsing feature. The spec’s API exactly mirrors that of <a href="http://www.json.org/js.html" target="_blank">Crockford’s implementations of JSON.parse and JSON.stringify in json2.js</a>, easing the transition to browser-native functionality.</p>
<p>This native JSON parsing brings marked improvements in terms of <strong>both security and performance</strong>. Not only does the native routine use textual parsing to avoid the risk of executing malicious code embedded within JSON, but it is also <em>fast.</em></p>
<p>At the time of this writing, three major browsers <em>already</em> include support for native JSON parsing: <strong>IE8</strong>, <strong>Firefox 3.5</strong>, and <strong>Chrome 3</strong>.</p>
<p>Safari 4 does not currently support the standard, but its underlying engine (WebKit) <a href="https://bugs.webkit.org/show_bug.cgi?id=20031" rel="nofollow" target="_blank">has recently implemented it</a>. Hopefully the feature will make its way to Safari soon.</p>
<h3>Detecting native JSON support</h3>
<p>Determining whether or not native JSON parsing is available within a given browser is the first problem we need to solve. To do this, we ultimately need to know if the <strong>JSON.parse</strong> function is defined.</p>
<p>We can’t test for JSON.parse directly because attempting to reference it will throw a JavaScript error if the underlying JSON object doesn’t exist. So, first we need to inspect the type of that underlying object itself:</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: #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;">'object'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  <span style="color: #006600; font-style: italic;">// native JSON may be available.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If we find that the JSON object does exist, it’s likely that native JSON parsing is available. However, it’s a best to double check the JSON.parse function as well:</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: #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: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// native JSON parsing is available.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Because JavaScript performs <a href="http://en.wikipedia.org/wiki/Short-circuit_evaluation" rel="nofollow" target="_blank">short-circuit evaluation</a>, it’s safe to clean this up by combining both tests in a single conditional, as long as they&#8217;re in this order:</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: #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;">'object'</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: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Native JSON parsing is available.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Curious whether your browser supports native JSON parsing? Using the JavaScript above, I have determined that: <strong><script type="text/javascript">if (typeof(JSON) === 'object') { if (typeof(JSON.parse) === 'function') { document.write('It does!'); } } else { document.write('It does not.'); }</script></strong></p>
<p><noscript>You appear to have JavaScript disabled or are reading this in an RSS reader.  In order to view the status of your browser&#8217;s native JSON capability, <a target="_blank" href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">please view this post in a browser with JavaScript enabled</a>.</noscript></p>
<h3>Extending jQuery to use native JSON parsing</h3>
<p>In my previous post, I demonstrated how to <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">use jQuery’s dataFilter to transform a JSON response</a> before it is returned to the $.ajax() success handler. In the process, we also preempted jQuery’s default method for deserializing JSON data.</p>
<p>The focus at that time was implementing the same method for JSON parsing that jQuery uses by default, so eval() was still used. However, we can also use the same dataFilter mechanism to force browser-native JSON parsing instead.</p>
<p>Using our JSON parsing detection code and a dataFilter callback, upgrading jQuery to use browser-native parsing is simple:</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>Because jQuery only attempts to deserialize JSON responses if their type is string, and because the dataFilter callback executes <em>before</em> jQuery would normally perform that deserialization, this technique preempts jQuery’s JSON evaluation completely. In the worst case, it will simply revert back to the same eval() method that jQuery internally uses by default anyway.</p>
<p><em>Note: It’s important to keep in mind that the dataFilter will run regardless of what type is actually returned from the server. You should only use this when you’re sure that you’re receiving a JSON string.</em></p>
<h3>Conclusion</h3>
<p>If you’ve been paying close attention to jQuery’s ongoing development, you may already know that <a href="http://dev.jquery.com/ticket/4429" rel="nofollow" target="_blank">jQuery 1.3.3 will provide functionality very similar to what I’ve shown you</a>. I decided to go ahead and write this post anyway for a few reasons:</p>
<ul>
<li>You can use this <strong>today</strong>, without waiting for jQuery 1.3.3.</li>
<li>You can use this in previous versions of jQuery, if upgrading isn’t feasible for you (as is often the case with plugins dependent on older versions).</li>
<li>If you use <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">my technique for isolating your code from ASP.NET AJAX’s “.d”</a>, you will still need a method for deserializing JSON in the dataFilter.</li>
</ul>
<p>Speaking of that last point, if you’re using jQuery with ASP.NET AJAX services, be sure to watch out for the next post in this (accidental) series. There is at least one more productive step left in improving this workflow that I have been using in my projects and want to share with you soon.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">Improving jQuery’s JSON performance and security</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/' rel='bookmark' title='Permanent Link: Never worry about ASP.NET AJAX&#8217;s .d again'>Never worry about ASP.NET AJAX&#8217;s .d again</a></li>
<li><a href='http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Permanent Link: Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
<li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 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>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Never worry about ASP.NET AJAX&#8217;s .d again</title>
		<link>http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/</link>
		<comments>http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 05:00:48 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=883</guid>
		<description><![CDATA[When I recently received this message from a frustrated reader: After hours and hours of slamming my head into the desk it turns out it was the darn &#34;d&#34; in the response. My home computer is on .NET 2.0 and my work computer is on 3.5. Jimminie Christmas! I realized that the “.d” introduced in [...]<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/">Never worry about ASP.NET AJAX&#8217;s .d again</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>



Related posts:<ol><li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: 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/2009/02/10/a-breaking-change-between-versions-of-aspnet-ajax/' rel='bookmark' title='Permanent Link: A breaking change between versions of ASP.NET AJAX'>A breaking change between versions of ASP.NET AJAX</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>When I recently received this message from a frustrated reader:</p>
<blockquote><p>After hours and hours of slamming my head into the desk it turns out it was the darn &quot;d&quot; in the response. My home computer is on .NET 2.0 and my work computer is on 3.5. <strong>Jimminie Christmas</strong>!</p></blockquote>
<p>I realized that the “.d” introduced in ASP.NET AJAX 3.5’s JSON responses is still all too common a stumbling block when <a target="_blank" href="http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/">calling ASP.NET AJAX services through a library such as jQuery</a>. In fact, with jQuery’s popularity among ASP.NET developers on the rise, this appears to have <strong>become an even more frequent problem</strong>.</p>
<p>Since a lot of people are having trouble with it, I want to share one method you can use to completely isolate your code from the problem. If you bake this into an $.ajax() code snippet or otherwise use it as a template for calling ASP.NET AJAX services in jQuery, you should never have to think or worry about the “.d” again.</p>
<p>In this post, I will show you <strong>how to detect the “.d”</strong> and how you can <strong>completely isolate your $.ajax success handler from it</strong>.</p>
<h3>“.d” what?</h3>
<p>If you aren’t familiar with the “.d” I’m referring to, it is simply a security feature that Microsoft added in ASP.NET 3.5’s version of ASP.NET AJAX. By encapsulating the JSON response within a parent object, the framework helps protect against <a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx" target="_blank">a particularly nasty XSS vulnerability</a>.</p>
<p>Before ASP.NET 3.5, “ScriptServices” and page methods returned their data at the top level of the JSON response, like this:</p>
<p><img title="2.0 JSON Response" border="0" alt="2.0 JSON Response in Firebug" src="http://encosia.com/blog/wp-content/uploads/2009/02/20-json-response.png" width="490" height="146" /></p>
<p>In ASP.NET 3.5 and later, the same server-side code returns this:</p>
<p><img title="3.5 JSON Response" border="0" alt="3.5 JSON Response in Firebug" src="http://encosia.com/blog/wp-content/uploads/2009/02/35-json-response.png" width="490" height="146" /></p>
<p>For more information about the change and <em>why</em> the change is a good one, be sure to see my earlier post: <a href="http://encosia.com/2009/02/10/a-breaking-change-between-versions-of-aspnet-ajax/" target="_blank">A breaking change between versions of ASP.NET AJAX</a>.</p>
<p>However, what my previous post lacks is a solution for mitigating the inconsistency entirely. Using different client-side code against 2.0 and 3.5 based services is workable, but far from ideal. <strong>Wouldn’t it be nicer to not have to worry about it?</strong></p>
<h3>Determining whether or not the “.d” is there</h3>
<p>In order to isolate ourselves from the “.d”, we first need a reliable way to test for its presence. Though JavaScript provides several methods for determining this, I suggest hasOwnProperty, <a href="http://encosia.com/2009/02/16/review-the-best-javascript-book-i%E2%80%99ve-read/" rel="nofollow" target="_blank">as recommended by Douglas Crockford</a>.</p>
<p>By using hasOwnProperty, your code is protected against <a href="http://encosia.com/2008/09/28/avoid-this-tricky-conflict-between-aspnet-ajax-and-jquery/" target="_blank">unexpected changes to an object’s prototype chain</a>. Though it is an unlikely problem to encounter, it’s always best to code defensively in JavaScript. The browser is a hostile environment!</p>
<p>Using hasOwnProperty to test for “.d”, you might end up with something 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>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;WebService.asmx/MethodName&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>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&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>
    <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;">&quot;d&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #006600; font-style: italic;">// Leave the .d behind and pass the rest of </span>
      <span style="color: #006600; font-style: italic;">//  the JSON object forward.</span>
      DoSomething<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: #000066; font-weight: bold;">else</span>
      <span style="color: #006600; font-style: italic;">// No .d; no transformation necessary.</span>
      DoSomething<span style="color: #009900;">&#40;</span>msg<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>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> DoSomething<span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Do something with the response data here.</span>
  <span style="color: #006600; font-style: italic;">//  Expect it to consistently have no .d.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This code <em>will</em> perform identically against any version of ASP.NET AJAX.</p>
<p>Unfortunately, this might still get in your way. You may not always want to use the response in a call to another function, and you’ll have to remember the conditional every time you write a success handler.</p>
<h3>Don’t make me think</h3>
<p>I prefer a solution that doesn’t touch the success handler at all. Then, you’re free to integrate the “.d” handling into a generic $.ajax code snippet in Visual Studio and/or easily copy-paste it between files without modification.</p>
<p>Luckily, jQuery provides a mechanism that allows us to do just that: <strong>dataFilter</strong>.</p>
<p>The dataFilter parameter to $.ajax allows you to arbitrarily transform a response <em>just before</em> the success handler fires. Specifically tailored to this sort of situation, it passes response data into a callback function, captures the return value of that callback, and then passes the modified data into your success handler.</p>
<p>Hence, you can forever stop worrying about that pesky “.d” 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>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;WebService.asmx/MethodName&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>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&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: #006600; font-style: italic;">// This boils the response string down </span>
    <span style="color: #006600; font-style: italic;">//  into a proper JavaScript Object().</span>
    <span style="color: #003366; font-weight: bold;">var</span> msg <span style="color: #339933;">=</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>
&nbsp;
    <span style="color: #006600; font-style: italic;">// If the response has a &quot;.d&quot; top-level property,</span>
    <span style="color: #006600; font-style: italic;">//  return what's below that instead.</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: #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>
    <span style="color: #006600; font-style: italic;">// This will now output the same thing </span>
    <span style="color: #006600; font-style: italic;">//  across any current version of .NET.</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">foo</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>Now, regardless which of these JSON forms the server returns:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// ASP.NET 2.0 with the ASP.NET AJAX Extensions installed.</span>
<span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// ASP.NET 3.5 and 4.0.</span>
<span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'d'</span><span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Your success handler will simply receive this consistent JSON object every time:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#125;</span></pre></div></div>

<h3>dataType: none of your business</h3>
<p>It&#8217;s important to note the removal of the dataType parameter in the $.ajax() code above. This is required in order to prevent a double-eval of service responses containing only a single string.</p>
<p>Internally, jQuery uses a combination of the dataType parameter and the implicit type the response. If the dataType is &quot;json&quot; and typeof(response) is “string”, then jQuery uses eval() to deserialize the response.</p>
<p>In the example above, manually deserializing the response in dataFilter results in it being of type Object, jQuery leaves it alone, and our dataFilter’d object makes its way back to the success callback either way.</p>
<p>However, if the dataType is set to “json” and the “.d” sanitized response happens to be of JavaScript type “string”, jQuery will assume that it is a JSON response from the server and still needs to be deserialized. That will throw an error at best.</p>
<p>The solution is to simply drop the dataType parameter from the $.ajax() call. It is only needed for purposes of instructing jQuery how to deserialize the response, and we’re handling that ourselves now.</p>
<p>Thanks to Brett <a href="#comment-35702">for pointing this out</a>.</p>
<h3>Wait, isn’t eval() supposed to be evil?</h3>
<p>If the eval() usage gives you pause, don’t worry. For now (as of jQuery 1.3.2), this is the same mechanism that jQuery uses to deserialize JSON too. Though eval() <em>is</em> potentially evil, <strong>it is still a necessary evil in many browsers</strong>.</p>
<p>In my next post, I’ll show you how to modify this to leverage a native browser implementation of JSON.parse instead of eval(), available in some newer browsers.</p>
<p>That post is available now: <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">Improving jQuery&#8217;s JSON performance and security</a>.</p>
<p><hr />

<p>You've been reading <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/">Never worry about ASP.NET AJAX&#8217;s .d again</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p></p>


<p>Related posts:<ol><li><a href='http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='Permanent Link: 3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
<li><a href='http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Permanent Link: 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/2009/02/10/a-breaking-change-between-versions-of-aspnet-ajax/' rel='bookmark' title='Permanent Link: A breaking change between versions of ASP.NET AJAX'>A breaking change between versions of ASP.NET AJAX</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
	</channel>
</rss>
