<?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>blog.rebeccamurphey.com</title>
	<atom:link href="http://blog.rebeccamurphey.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rebeccamurphey.com</link>
	<description>Adventures in front-end consulting</description>
	<lastBuildDate>Thu, 18 Mar 2010 17:31:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TXJS: JS + BBQ + You</title>
		<link>http://blog.rebeccamurphey.com/2010/03/18/txjs-js-bbq-you/</link>
		<comments>http://blog.rebeccamurphey.com/2010/03/18/txjs-js-bbq-you/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 17:29:28 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[txjs]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=256</guid>
		<description><![CDATA[If you follow me on Twitter, you've heard about TXJS by now, but let me tell you: now that we've announced Douglas Crockford and John Resig, there is officially no way you should miss this. TXJS is a full-day conference set for June 5 in Austin, Texas, hosted by the yayQuery team and featuring BBQ [...]]]></description>
			<content:encoded><![CDATA[<p>If you follow me on Twitter, you've heard about <a href="http://txjs.eventbrite.com">TXJS</a> by now, but let me tell you: now that we've announced Douglas Crockford and John Resig, there is officially no way you should miss this. TXJS is a full-day conference set for June 5 in Austin, Texas, hosted by the <a href="http://txjs.eventbrite.com">yayQuery</a> team and featuring BBQ and a slew of awesome JavaScripters:  </p>
<ul>
<li><strong>Brandon Aaron</strong>, jQuery team member</li>
<li><strong>Tim Caswell</strong>, Node.js contributor and founder of <a href="http://howtonode.org">howtonode.org</a></li>
<li><strong>Douglas Crockford</strong>, JavaScript architect at Yahoo! and author of "JavaScript: The Good Parts"</li>
<li><strong>Andrew Dupont</strong>, Prototype core team member</li>
<li><strong>Peter Higgins</strong>, Dojo project lead</li>
<li><strong>Paul Irish</strong>, jQuery team member and yayQuery podcast co-host</li>
<li><strong>Brian LeRoux</strong>, software architect at Nitobi and PhoneGap hacker/contributor</li>
<li><strong>Joe McCann</strong>, senior technologist at Frog Design</li>
<li><strong>John Resig</strong>, creator of the jQuery JavaScript library</li>
<li><strong>Alex Sexton</strong>, front-end developer and yayQuery podcast co-host</li>
<li><strong>Kyle Simpson</strong>, <a href="http://twitter.com/AustinJS">Austin JS</a> organizer and author of LABjs</li>
<li><strong>Adam Sontag</strong>, jQuery UI developer relations team member and yayQuery podcast co-host</li>
<li><strong>Mike Taylor</strong>, HTML5 aficionado and front-end developer at Tunecore</li>
<li><strong>Juriy Zaytsev</strong> (aka @kangax), expert JavaScript wrangler and Prototype core developer</li>
</ul>
<p>Earlybird tickets are just $49 while they last, and regular tickets are just $69, which is about as close to free as we could get. See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2010/03/18/txjs-js-bbq-you/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>srchr: Crowdsourcing JavaScript wisdom</title>
		<link>http://blog.rebeccamurphey.com/2010/03/15/srchr-crowdsourcing-javascript-wisdom/</link>
		<comments>http://blog.rebeccamurphey.com/2010/03/15/srchr-crowdsourcing-javascript-wisdom/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 05:40:14 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[front-end development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=248</guid>
		<description><![CDATA[UPDATE: The deadline for completing your submission is April 16, the day before JSConf. If you're at the conference, join others in the hacker lounge to see what they did!
I've been working on a blog post about using classes and pub/sub for structuring jQuery applications, and I had in mind a pretty simple demo app [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:</strong> The deadline for completing your submission is April 16, the day before <a href="http://jsconf.us/2010/">JSConf</a>. If you're at the conference, join others in the hacker lounge to see what they did!</p>
<p>I've been working on a blog post about using classes and pub/sub for structuring jQuery applications, and I had in mind a pretty simple demo app that I was going to build. I also wanted to show a version of the app that was built in a more traditional way, and I'd been pondering whether I should write that version myself, or see if I could cajole someone else into doing it. And then, a moment of inspiration: rather than a contrived counter-example, why not get a whole bunch of developers to show how they'd tackle the problem, so we can all gain from the exercise and learn from each other? </p>
<p>I tweeted my idea, and five minutes later I had a dozen volunteers and counting, which is downright awesome and in hindsight shouldn't be surprising. It's so rare that we get to see multiple approaches to a moderately complex problem -- it's much more common to see horrendous code and bitch about it <img src='http://blog.rebeccamurphey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<h2>The project</h2>
<p>I've put together a mock/spec for a small, strictly client-side application that uses <a href="http://developer.yahoo.com/yql/console/">YQL</a> to search for content and then displays it to the user. (Click on the image to see it full-size.)</p>
<p><a href="http://blog.rebeccamurphey.com/wp-content/uploads/2010/03/mock.png" title="srchr spec/mock"><img src="http://blog.rebeccamurphey.com/wp-content/uploads/2010/03/mock-300x232.png" alt="srchr spec/mock" title="srchr spec/mock" width="300" height="232" class="alignnone size-medium wp-image-250" /></a></p>
<p>Think of this as an exercise in creating a product, not a site that you finish and walk away from -- the goal is to create an extensible, modular application. That said, there are no "right" answers here: the point is for you to demonstrate how you, personally, would approach the problem. </p>
<h2>Presenting your solution</h2>
<p>I've created a <a href="http://github.com/rmurphey/srchr">github repository</a> for the project that contains nothing more than some documentation, the mock/spec, and a few stub files and directories. You should fork this repository to get started. If you create some CSS that you'd like to share, I'd encourage you to send a pull request so I can make it available to everyone; this isn't an CSS exercise, so no one should labor over that part if they don't want to. I may very well write some basic CSS myself in the next couple of days, but it's late <img src='http://blog.rebeccamurphey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Finally: please comment on this post if you have any questions!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2010/03/15/srchr-crowdsourcing-javascript-wisdom/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Building a standalone JavaScriptMVC controller.js</title>
		<link>http://blog.rebeccamurphey.com/2010/03/10/building-standalone-javascriptmvc-controller-js/</link>
		<comments>http://blog.rebeccamurphey.com/2010/03/10/building-standalone-javascriptmvc-controller-js/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 21:25:02 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[javascriptmvc]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=242</guid>
		<description><![CDATA[I've been doing a lot of work lately with a client who's using just the controller portion of JavaScriptMVC. I plan to write a more in-depth post about this while I'm traveling this week, but in the meantime, I wanted to jot down the steps to create the standalone controller.js file for my future reference. [...]]]></description>
			<content:encoded><![CDATA[<p>I've been doing a lot of work lately with a client who's using just the controller portion of <a href="http://javascriptmvc.com">JavaScriptMVC</a>. I plan to write a more in-depth post about this while I'm traveling this week, but in the meantime, I wanted to jot down the steps to create the standalone controller.js file for my future reference. These instructions work for me on OSX 10.6.</p>
<ol>
<li>Go to the <a href="http://github.com/pinhook/framework/downloads">JavaScriptMVC downloads page on Github</a></li>
<li>Download the latest version (3.0.0a0 as of this writing) of the framework and unzip it</li>
<li>Open a terminal window and cd to the directory created when you unzipped the file</li>
<li>Run <code>steal/js steal/compress/plugin.js jquery/controller</code></li>
<li>You should now have a new controller.js file in the directory; you're all set!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2010/03/10/building-standalone-javascriptmvc-controller-js/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Demystifying custom events in jQuery</title>
		<link>http://blog.rebeccamurphey.com/2009/12/03/demystifying-custom-events-in-jquery/</link>
		<comments>http://blog.rebeccamurphey.com/2009/12/03/demystifying-custom-events-in-jquery/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 23:28:33 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=240</guid>
		<description><![CDATA[This article originally appeared in the May 2009 issue of JSMag.
We’re all familiar with the basic events — click, mouseover, focus, blur, submit, etc. — that we can latch on to as a user interacts with the browser. Custom events open up a whole new world of event-driven programming. In this article, we’ll use jQuery’s [...]]]></description>
			<content:encoded><![CDATA[<p><em>This article originally appeared in the May 2009 issue of <a href="http://jsmag.com">JSMag</a>.</em></p>
<p>We’re all familiar with the basic events — click, mouseover, focus, blur, submit, etc. — that we can latch on to as a user interacts with the browser. Custom events open up a whole new world of event-driven programming. In this article, we’ll use jQuery’s custom events system to make a simple Twitter search application, but the general concepts should apply to any framework that supports custom events.  </p>
<p>I confess: it took me a long time to decide to learn about custom events. The built-in events seemed to suit my needs just fine, and it was difficult to understand why I’d want to start adding my own. </p>
<p>Boy, was I missing out.</p>
<p>It turns out that custom events offer a whole new way of thinking about event-driven JavaScript. Instead of focusing on the element that triggers an action, custom events put the spotlight on the element being acted upon. This brings a bevy of benefits, including: </p>
<ul>
<li>behaviors of the target element can easily be triggered by different elements using the same code; </li>
<li>behaviors can be triggered across multiple, similar, target elements at once; and </li>
<li>behaviors are more clearly associated with the target element in code, making code easier to read and maintain</li>
</ul>
<p>Why should you care? An example is probably the best way to explain. </p>
<p>Suppose you have a lightbulb in a room in a house. The lightbulb is currently turned on, and it’s controlled by two three-way switches and a clapper, as shown here:</p>
<pre>&nbsp;
&lt;div class=&quot;room&quot; id=&quot;kitchen&quot;&gt;
&lt;div class=&quot;lightbulb on&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;switch&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;switch&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;clapper&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&nbsp;</pre>
<p>Triggering the clapper or either of the switches will change the state of the lightbulb. The switches and the clapper don’t care what state the lightbulb is in; they just want to change the state. </p>
<p>Without custom events, you might write some code like this:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.switch, .clapper'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> $light = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$light.<span style="color: #006600;">hasClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>With custom events, your code might look more like this:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'changeState'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> $light = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$light.<span style="color: #006600;">hasClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.switch, .clapper'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'changeState'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>This last bit of code is not that exciting, but something important has happened: we’ve moved the behavior of the lightbulb to the lightbulb, and away from the switches and the clapper.</p>
<p>Let’s make our example a little more interesting. We’ll add another room to our house, along with a master switch, as shown here:</p>
<pre class="javascript">&nbsp;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;room&quot;</span> id=<span style="color: #3366CC;">&quot;kitchen&quot;</span>&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;lightbulb on&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;switch&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;switch&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;clapper&quot;</span>&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;room&quot;</span> id=<span style="color: #3366CC;">&quot;bedroom&quot;</span>&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;lightbulb on&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;switch&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;switch&quot;</span>&gt;&lt;/div&gt;
&lt;div <span style="color: #003366; font-weight: bold;">class</span>=<span style="color: #3366CC;">&quot;clapper&quot;</span>&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=<span style="color: #3366CC;">&quot;master_switch&quot;</span>&gt;&lt;/div&gt;
&nbsp;</pre>
<p>If there are any lights on in the house, we want the master switch to turn all the lights off; otherwise, we want it to turn all lights on. To accomplish this, we’ll add two more custom events to the lightbulbs: turnOn and turnOff. We’ll make use of them in the changeState custom event, and use some logic to decide which one the master switch should trigger:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.
<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'changeState'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> $light = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$light.<span style="color: #006600;">hasClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOff'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">&#123;</span>
		$light.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOn'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOn'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOff'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'off'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'on'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.switch, .clapper'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'changeState'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#master_switch'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb.on'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOff'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">&#123;</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'.lightbulb'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'turnOn'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>A bit more interesting, huh? Note how the rules about what the master switch does belongs to the master switch; the rules about how a lightbulb turns on and off belong to the lightbulb. It’s also worth noting that the master switch is able to affect all of the lightbulbs without having to iterate over them — it just triggers an event on all elements that have the class “lightbulb”. This isn’t critical to the example, but if we were to perform more elaborate manipulations of each lightbulb than adding and removing a class, this would be an important benefit of custom events, as you’ll see in the rest of the article.</p>
<p>(If you’re accustomed to object-oriented programming, you may find it useful to think of custom events as methods of objects. Loosely speaking, the object to which the method belongs is created via the jQuery selector. Binding the changeState custom event to all $('.light') elements is akin to having a class called Light with a method of changeState(), and then instantiating new Light objects for each element with a classname of light.)</p>
<h2>jQuery Event Primer</h2>
<p>Before we dive in, a couple of things we need to recap. In the world of custom events, there are two important jQuery methods: .bind() and .trigger(). I encourage you to read the jQuery docs for details, but basically:</p>
<ul>
<li>The .bind() method takes an event type and an event handling function as arguments. Optionally, it can also receive data, which will be available to the event handling function in the data property of the event object. The event handling function always receives the event object as its first argument.</li>
<li>The .trigger() method takes an event type as its argument. Optionally, it can also take an array of values. The first item in the array will be the second argument passed to the event handling function (after the event object).</li>
</ul>
<p>Confused? I don’t blame you. Read on and I’ll try to clear some things up. </p>
<h2>Our Mission</h2>
<p>To demonstrate the power of custom events, we’re going to create a simple tool for searching Twitter. The tool will offer several ways for a user to add search terms to the display: by entering a search term in a text box, by entering multiple search terms in the URL, and by querying Twitter for trending terms. </p>
<p>The results for each term will be shown in a results container; these containers will be able to be expanded, collapsed, refreshed, and removed, either individually or all at once.  </p>
<p>When we’re done, it will look like this:</p>
<h2>The Setup</h2>
<p>We’ll start with some basic HTML:</p>
<pre>&nbsp;
&lt;h1&gt;Twitter Search&lt;/h1&gt;
&lt;input type=&quot;button&quot; id=&quot;get_trends&quot;
	value=&quot;Load Trending Terms&quot; /&gt;
&lt;form&gt;
&lt;input type=&quot;text&quot; class=&quot;input_text&quot;
		id=&quot;search_term&quot; /&gt;
&lt;input type=&quot;submit&quot; class=&quot;input_submit&quot;
		value=&quot;Add Search Term&quot; /&gt;
&lt;/form&gt;
&lt;div id=&quot;twitter&quot;&gt;
&lt;div class=&quot;template results&quot;&gt;
&lt;h2&gt;Search Results for
		&lt;span class=&quot;search_term&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&nbsp;</pre>
<p>This gives us a container (#twitter) for our widget, a template for our results containers (hidden via CSS), and a simple form where users can input a search term. (For the sake of simplicity, we’re going to assume that our application is JavaScript-only and that our users will always have CSS.)</p>
<p>First, the setup. We’ll build an $actions object that we’ll use later to create the buttons in each results container, and we’ll also create a global search_terms object so we can store a list of search terms that are being displayed on the page.<br />
Next, we’ll do our custom event binding. There are two types of objects we’ll want to act on: the results containers, and the Twitter container.</p>
<h3>The Results Containers</h3>
<p>The results containers are the heart of the application. We’ll create a setupResults() plugin that will prepare each results container once it’s added to the Twitter container. Among other things, it will bind the custom events for each container and add the action buttons at the top right of each container. Each results container will have the following custom events:</p>
<ul>
<li>The refresh event will mark the container as being in the “refreshing” state, and fire the $.getJSON() request to fetch the data for the search term.</li>
<li>The populate event will receive the returned JSON data and use it to populate the container.</li>
<li>The remove event will remove the container from the page after the user verifies the request to do so. Verification can be bypassed by passing true as the second argument to the event handler. The remove event also removes the term associated with the results container from the global search_terms object.</li>
<li>The collapse event will add a class of collapsed to the container, which will hide the results via CSS. It will also turn the container’s “Collapse” button into an “Expand” button.</li>
<li>The expand event will remove the collapsed class from the container. It will also turn the container’s “Expand” button into a “Collapse” button.</li>
</ul>
<p>The plugin is also responsible for adding the action buttons to the container by cloning the $actions object that was created earlier. It binds a click event to each action’s list item, and uses the list item’s class to determine which custom event will be triggered on the corresponding results container. </p>
<pre class="javascript">&nbsp;
<span style="color: #009900; font-style: italic;">// we'll use this every time we add a new results panel,</span>
<span style="color: #009900; font-style: italic;">// so let's build it once and cache it in $actions</span>
<span style="color: #003366; font-weight: bold;">var</span> $actions = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;ul class=&quot;actions&quot; /&gt;'</span><span style="color: #66cc66;">&#41;</span>;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li class=&quot;refresh&quot;&gt;Refresh&lt;/li&gt;
&nbsp;
'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">appendTo</span><span style="color: #66cc66;">&#40;</span>$actions<span style="color: #66cc66;">&#41;</span>;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li class=&quot;remove&quot;&gt;Remove&lt;/li&gt;
&nbsp;
'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">appendTo</span><span style="color: #66cc66;">&#40;</span>$actions<span style="color: #66cc66;">&#41;</span>;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li class=&quot;collapse&quot;&gt;Collapse&lt;/li&gt;
&nbsp;
'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">appendTo</span><span style="color: #66cc66;">&#40;</span>$actions<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #009900; font-style: italic;">// this is where we'll keep track of which search terms</span>
<span style="color: #009900; font-style: italic;">// are shown on the page already</span>
<span style="color: #003366; font-weight: bold;">var</span> search_terms = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>;
&nbsp;</pre>
<p>Here's the setupResults plugin:</p>
<pre class="javascript">&nbsp;
$.<span style="color: #006600;">fn</span>.<span style="color: #006600;">setupResults</span> = <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>settings<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
		<span style="color: #003366; font-weight: bold;">var</span> $results = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #003366; font-weight: bold;">var</span> $actions = settings.<span style="color: #006600;">actions</span>;
		<span style="color: #003366; font-weight: bold;">var</span> term = settings.<span style="color: #006600;">term</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// change the &quot;Search results for&quot; text</span>
		$results.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'span.search_term'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span>term<span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// bind custom events for results box</span>
		$results. 
&nbsp;
		<span style="color: #009900; font-style: italic;">// the &quot;refresh&quot; event fetches</span>
		<span style="color: #009900; font-style: italic;">// the latest content for the term</span>
		bind<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refresh'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #009900; font-style: italic;">// indicate that the results are refreshing</span>
			<span style="color: #003366; font-weight: bold;">var</span> $this = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refreshing'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			$this.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'p.tweet'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
			$results.<span style="color: #006600;">append</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;p class=&quot;loading&quot;&gt;Loading ...
&nbsp;
'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			<span style="color: #009900; font-style: italic;">// get the twitter data using jsonp</span>
			$.<span style="color: #006600;">getJSON</span><span style="color: #66cc66;">&#40;</span>
				<span style="color: #3366CC;">'http://search.twitter.com/search.json?q='</span> + 					escape<span style="color: #66cc66;">&#40;</span>term<span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">'&amp;rpp=5&amp;callback=?'</span>,
				<span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>json<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
					$this.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'populate'</span>, <span style="color: #66cc66;">&#91;</span> json <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
				<span style="color: #66cc66;">&#125;</span>
			<span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
		<span style="color: #009900; font-style: italic;">// the &quot;populate&quot; event takes results</span>
		<span style="color: #009900; font-style: italic;">// in json format</span>
		<span style="color: #009900; font-style: italic;">// and populates the results container</span>
		bind<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'populate'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e, json<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> results = json.<span style="color: #006600;">results</span>;
			<span style="color: #003366; font-weight: bold;">var</span> $this = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			$this.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'p.loading'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			$.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span>results, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>i,result<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> tweet = <span style="color: #3366CC;">'
&lt;p class=&quot;tweet&quot;&gt;'</span> +
					<span style="color: #3366CC;">'&lt;a href=&quot;http://twitter.com/'</span> +
					result.<span style="color: #006600;">from_user</span> +
					<span style="color: #3366CC;">'&quot;&gt;'</span> +
					result.<span style="color: #006600;">from_user</span> +
					<span style="color: #3366CC;">'&lt;/a&gt;: '</span> +
					result.<span style="color: #006600;">text</span> +
					<span style="color: #3366CC;">' &lt;span class=&quot;date&quot;&gt;'</span> +
					result.<span style="color: #006600;">created_at</span> +
					<span style="color: #3366CC;">'&lt;/span&gt;'</span> +
				<span style="color: #3366CC;">'
&nbsp;
'</span>;
				$this.<span style="color: #006600;">append</span><span style="color: #66cc66;">&#40;</span>tweet<span style="color: #66cc66;">&#41;</span>;
					<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
					<span style="color: #009900; font-style: italic;">// indicate that the results</span>
					<span style="color: #009900; font-style: italic;">// are done refreshing</span>
					$this.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refreshing'</span><span style="color: #66cc66;">&#41;</span>;
				<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
						<span style="color: #009900; font-style: italic;">// the remove event removes</span>
						<span style="color: #009900; font-style: italic;">// the results from the page</span>
						<span style="color: #009900; font-style: italic;">// after the user confirms the action</span>
						bind<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'remove'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e, force<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
							<span style="color: #009900; font-style: italic;">// allow forced removal without confirmation</span>
							<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>
								!force &amp;&amp;
								!<span style="color: #000066;">confirm</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Remove panel for term '</span> + term + <span style="color: #3366CC;">'?'</span><span style="color: #66cc66;">&#41;</span>
							<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
								<span style="color: #000066; font-weight: bold;">return</span>;
							<span style="color: #66cc66;">&#125;</span>
							$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
							<span style="color: #009900; font-style: italic;">// indicate that we no longer</span>
							<span style="color: #009900; font-style: italic;">// have a panel for the term</span>
							search_terms<span style="color: #66cc66;">&#91;</span>term<span style="color: #66cc66;">&#93;</span> = <span style="color: #CC0000;">0</span>;
						<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
						<span style="color: #009900; font-style: italic;">// the collapse event collapses the results so only the</span>
						<span style="color: #009900; font-style: italic;">// header of the results section is showing</span>
						bind<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapse'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
							$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'li.collapse'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapse'</span><span style="color: #66cc66;">&#41;</span>
								.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'expand'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Expand'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
							$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapsed'</span><span style="color: #66cc66;">&#41;</span>;
						<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
						<span style="color: #009900; font-style: italic;">// the expand event</span>
						bind<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'expand'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
							$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'li.expand'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'expand'</span><span style="color: #66cc66;">&#41;</span>
								.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapse'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Collapse'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
							$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapsed'</span><span style="color: #66cc66;">&#41;</span>;
						<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
						<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$actions &amp;&amp; $actions.<span style="color: #006600;">length</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
							<span style="color: #009900; font-style: italic;">// add a clone of $actions to the results panel</span>
							<span style="color: #003366; font-weight: bold;">var</span> $a = $actions.<span style="color: #006600;">clone</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">prependTo</span><span style="color: #66cc66;">&#40;</span>$results<span style="color: #66cc66;">&#41;</span>;
&nbsp;
							<span style="color: #009900; font-style: italic;">// use the class of each action to figure out</span>
							<span style="color: #009900; font-style: italic;">// which event it will trigger on the results panel</span>
							$a.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'li'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
								<span style="color: #009900; font-style: italic;">// pass the li that was clicked to the function</span>
								<span style="color: #009900; font-style: italic;">// so it can be manipulated if needed</span>
								$results.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span>
									$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'class'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#91;</span> $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#93;</span>
								<span style="color: #66cc66;">&#41;</span>;
							<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
						<span style="color: #66cc66;">&#125;</span>
					<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
				<span style="color: #66cc66;">&#125;</span>;
&nbsp;</pre>
<h3>The Twitter Container</h3>
<p>The Twitter container itself will have just two custom events:</p>
<ul>
<li>The getResults event will receive a search term. It will check the global search_terms object to determine whether there’s already a results container for the term; if not, it will add a results container using the results template (div.template), set up the results container using the setupResults() plugin discussed above, and then trigger the refresh event on the results container in order to actually load the results. Finally, it will store the search term in the global search_terms object, so the application knows not to re-fetch the term.</li>
<li>The getTrends event will query Twitter for the top 10 trending terms. It will iterate over them and trigger the widget’s getResults event for each of them, thereby adding a results container for each term. Here you can see how we go about passing data to a triggered event.</li>
</ul>
<p>The Twitter container bindings are shown here:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter'</span><span style="color: #66cc66;">&#41;</span>.
<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getResults'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e, term<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #009900; font-style: italic;">// make sure we don't have a box for this term already</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>!search_terms<span style="color: #66cc66;">&#91;</span>term<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> $this = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #003366; font-weight: bold;">var</span> $template = $this.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div.template'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// make a copy of the template div</span>
		<span style="color: #009900; font-style: italic;">// and insert it as the first results box</span>
		$results = $template.<span style="color: #006600;">clone</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'template'</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">insertBefore</span><span style="color: #66cc66;">&#40;</span>$this.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div:first'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">setupResults</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
				<span style="color: #3366CC;">'term'</span> : term,
				<span style="color: #3366CC;">'actions'</span> : $actions
			<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// load the content using the &quot;refresh&quot;</span>
		<span style="color: #009900; font-style: italic;">// custom event that we bound to the results container</span>
		$results.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refresh'</span><span style="color: #66cc66;">&#41;</span>;
		search_terms<span style="color: #66cc66;">&#91;</span>term<span style="color: #66cc66;">&#93;</span> = <span style="color: #CC0000;">1</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getTrends'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> $this = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
	$.<span style="color: #006600;">getJSON</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'http://search.twitter.com/trends.json?callback=?'</span>, 		<span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>json<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> trends = json.<span style="color: #006600;">trends</span>;
			$.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span>trends, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>i, trend<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				$this.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getResults'</span>, <span style="color: #66cc66;">&#91;</span> trend.<span style="color: #000066;">name</span> <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>So far, we’ve written a lot of code that does approximately nothing, but that’s OK. By specifying all the behaviors that we want our core objects to have, we’ve created a solid framework for rapidly building out the interface.</p>
<p>Let’s start by hooking up our text input and the “Load Trending Terms” button. For the text input, we’ll make the form submission stop in its tracks using e.preventDefault(), then capture the term that was entered in the input and pass it to the Twitter widget’s getResults event. (Again, you can see how we go about passing data to a triggered event.) Clicking the “Load Trending Terms” will simply trigger the Twitter widget’s getTrends event:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">submit</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	e.<span style="color: #006600;">preventDefault</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #003366; font-weight: bold;">var</span> term = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#search_term'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">val</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getResults'</span>, <span style="color: #66cc66;">&#91;</span> term <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#get_trends'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getTrends'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>Just entering a search term into a text box is boring, of course — the following code shows how we can capture search terms from the URL’s hash (e.g., http://foo.com/index.html#foo,bar):</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
<span style="color: #009900; font-style: italic;">// pass search terms via URL hash</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>document.<span style="color: #006600;">location</span>.<span style="color: #006600;">hash</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> terms = document.<span style="color: #006600;">location</span>.<span style="color: #006600;">hash</span>.<span style="color: #006600;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">','</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">reverse</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	$.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span>terms, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>i,term<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'getResults'</span>, <span style="color: #66cc66;">&#91;</span> term <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>By adding a few buttons with the appropriate IDs, we can make it possible to remove, collapse, expand, and refresh all results containers at once, as shown below. For the remove button, note how we’re passing a value of true to the event handler as its second argument, telling the event handler that we don’t want to verify the removal of individual containers.</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#refresh'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter div.results'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refresh'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#expand'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter div.results'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'expand'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#collapse'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter div.results'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'collapse'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#remove'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Remove all results?'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#twitter div.results'</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'remove'</span>, <span style="color: #66cc66;">&#91;</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>It should be noted that you don’t have to choose one or all results containers — really, you can choose any results containers you want to affect. For example, if for some (strange) reason you wanted to refresh only the first and last results containers, you could do:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div.results:first, div.results:last'</span><span style="color: #66cc66;">&#41;</span>.
	<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'refresh'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>You can see the entire application, including the full HTML and CSS, at http://www.rebeccamurphey.com/jsmag/custom-events/. </p>
<h2>Conclusion</h2>
<p>Custom events offer a new way of thinking about your code: they put the emphasis on the target of a behavior, not on the element that triggers it. If you take the time at the outset to spell out the pieces of your application, as well as the behaviors those pieces need to exhibit, custom events can provide a powerful way for you to “talk” to those pieces, either one at a time or en masse. Once the behaviors of a piece have been described, it becomes trivial to trigger those behaviors from anywhere, allowing for rapid creation of and experimentation with interface options. Finally, custom events can enhance code readability and maintainability, by making clear the relationship between an element and its behaviors.</p>
<h2>Learn More</h2>
<ul>
<li><a href="http://docs.jquery.com/Events/jQuery.Event">The jQuery Event object</a></li>
<li><a href="http://docs.jquery.com/Events/bind#typedatafn">jQuery’s bind() method</a></li>
<li><a href="http://docs.jquery.com/Events/trigger#eventdata">jQuery’s trigger() method</a></li>
<li><a href="http://remysharp.com/2007/10/08/what-is-jsonp/">jQuery and JSON-P</a></li>
<li><a href="http://en.wikipedia.org/wiki/The_Clapper">Need I say more?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/12/03/demystifying-custom-events-in-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Dojo Confessions (Or: How I gave up my jQuery Security Blanket and Lived to Tell the Tale)</title>
		<link>http://blog.rebeccamurphey.com/2009/11/12/dojo-confessions-or-how-i-gave-up-my-jquery-security-blanket-and-lived-to-tell-the-tale/</link>
		<comments>http://blog.rebeccamurphey.com/2009/11/12/dojo-confessions-or-how-i-gave-up-my-jquery-security-blanket-and-lived-to-tell-the-tale/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 15:12:10 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=235</guid>
		<description><![CDATA[This is a reprint of an article that originally appeared in the October issue of JSMag.
I recently had the opportunity to architect the front-end of a new web application from scratch, and after years of using jQuery, I decided to give Dojo a try. For a variety of reasons — not least of which was [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a reprint of an article that originally appeared in the October issue of <a href="http://jsmag.com">JSMag</a>.</em></p>
<p>I recently had the opportunity to architect the front-end of a new web application from scratch, and after years of using <a href="http://jquery.com">jQuery</a>, I decided to give <a href="http://dojotoolkit.org">Dojo</a> a try. For a variety of reasons — not least of which was Dojo’s approach to code organization and dependency management — I thought this would be a good project to get some real-world Dojo experience under my belt. What follows is an overview of Dojo from the perspective of an avid jQuery user.</p>
<p>I’ve been using jQuery for years. Its simplicity is seductive; after a while, it kind of writes itself. And maybe that was my problem: I was ready to try something new. Many months ago, I wrote on Twitter that I was interested in learning more about Dojo. <a href="http://blog.reybango.com/">Rey Bango</a>, jQuery evangelist, wrote back, and put me in touch with <a href="http://higginsforpresident.com">Pete Higgins</a>, the Dojo project lead. Pete proceeded to lobby me for months to give his “unified toolkit” a try.</p>
<p>I dabbled. I read the docs. Pete plied me with sample code to show me what I was missing, and even drove to North Carolina to lead a Dojo camp. In August, I decided it was time to stop dabbling and dive in. I’d just finished writing some essentially library-less JavaScript for a web-based iPhone application, a task that left me much more confident in my knowledge of JavaScript. With the mobile site out of the way, the client was ready to build the desktop version, and I would be in charge of the front end. </p>
<p>It was time to choose a library; this time, I chose Dojo.</p>
<h2>Deciding on Dojo</h2>
<p>The decision to try a new library on a client project was a tough one — I knew that I could write the basic functionality of the site using jQuery a whole lot faster than I would write it with Dojo, simply because I knew my way around jQuery so much better. Using Dojo would mean I’d be looking up a lot of things, from simple stuff like how to work with DOM selections, to more complicated tasks like how to structure my code for the purposes of reuse and abstraction. </p>
<p>As my work on the project progressed and the deadline neared, I had plenty of second thoughts. A few things convinced me to stick with Dojo when the going got tough:</p>
<ul>
<li>Code organization patterns: Dojo provides pretty clear guidance on structuring both your features and your codebase. I’ve given a lot of thought to organizing jQuery code.  I wrote an article on the topic for JSMag and gave a presentation on the topic at the jQuery conference. I was eager to try a library that explicitly answers the organization question. </li>
<li>Class inheritance: I knew from the start that I was going to use a lot of interaction patterns over and over. I wanted to be able to write those patterns in a way that would let me use them across features while still staying DRY. The class inheritance provided by <code>dojo.declare()</code> was an elegant, easy-to-use solution to the problem.</li>
<li>Dependency management: Being able to easily manage dependencies was a huge draw for me; it promotes reuse and abstraction in a big way. Dojo’s dependency management would also pave the way to easily building production-ready files that would combine all the necessary functionality for a given type of page, reducing the number of HTTP requests required.</li>
<li>Service method descriptions: This particular application relied on XHRs (AJAX) in a big way. Dojo’s service method description approach would let me manage the URLs and parameters for those requests in a single place, keeping pieces that might change separate from the core code. Eventually, theoretically, the server-side code could actually generate this SMD file automatically. More on this in a bit.</li>
<li>Templating: All the XHR responses were JSON, which I’d need to turn into HTML. jQuery has templating plugins to solve this problem, so this wasn’t really a differentiating factor, but nonetheless it was going to make my life easier. I could maintain the templates for turning JSON into HTML separately from my JavaScript, and even programmatically choose the template depending on the situation. </li>
<li>The meaning of <code>this</code>: When binding a function to an event on an element in jQuery, <code>this</code> inside the function refers to the element that triggered the event. This is arguably desirable for simple code, but when you start organizing your code into objects with methods and you want this to refer to the object, not the element, it can get painful. The <code>dojo.hitch()</code> method lets you cleanly change the meaning of this for any given function, and it’s transparently rolled into other methods, such as <code>dojo.connect()</code> for event binding.</li>
<li>Documentation and support: Dojo has a reputation for poor documentation, and to some extent it’s deserved. Their documentation is a whole lot harder to use than jQuery’s because, at first glance, it’s quite a bit more scattered and substantially more API-based than task-based. However, once I figured out <a href="http://docs.dojocampus.org/manual/index">where to look for the docs I needed</a>, finding answers to my questions was pretty painless. I also leaned heavily on some experienced Dojo developers for guidance and support, and dropped in to the ever-helpful #dojo IRC channel on Freenode if I got stuck.</li>
</ul>
<h2>Getting Started</h2>
<p>The first step was assembling my new toy. I opted to use the library via Google’s CDN so I could get up and running as quickly as possible. After that, it was time to figure out  how I’d organize my files. </p>
<p>Dojo actively supports namespaces for components, which means you can put your application files in one or more directories and associate your namespaces with those directories. I created a high-level controller file in the root /js directory; it would be responsible for figuring out which functionality was required for a given page (a decision I’ll eventually revisit). Then, I created a directory inside the root /js directory, where I’d put all of the individual files for the various components.</p>
<p>Because I was using the Google-hosted version of Dojo, I had to put a script tag in my header template, before I included the base dojo.js, telling Dojo where to find my local files:</p>
<pre>&nbsp;
&lt;script&gt;var djConfig = { baseUrl : '/static/js/' };&lt;/script&gt;
&nbsp;</pre>
<p>Finally, I included a line in my controller file to tell Dojo where to find the namespace I’d be using:</p>
<p><code>dojo.registerModulePath('myNamespace', '../js/myNamespace');</code></p>
<p>Figuring out all of these pieces may have been the hardest part of making the switch to Dojo — it was a whole lot more setup than I was used to with jQuery, and though it is all documented, it took a bit of effort to find the details and to get the paths set up correctly. The time it took to get everything working properly was time that I spent wondering whether I’d made a good decision. Once it was working, it was time to write some actual code and try to answer that question.</p>
<h2>Get Some Elements, Do Something With Them</h2>
<p>Those words sum up the jQuery paradigm. In jQuery, you query the DOM using a CSS selector, and the result of that query is a jQuery object, which you can then operate on using method chains. It’s fairly rare in jQuery to work directly with a DOM element. While Dojo supports this paradigm through its dojo.query() method and the NodeList it returns, it’s common in Dojo to work directly with a DOM element rather than a NodeList. </p>
<p>My initial inclination was to stick with what I knew from jQuery, and to use <code>dojo.query()</code> to get everything I wanted to work with. As I dug in, though, I discovered that it could actually be just as elegant (and less expensive) to work directly with DOM elements, even though they didn’t come with any of the magic of a jQuery object. The syntax for doing so was a bit different — for example, <code>dojo.addClass(myDomElement, ‘foo’)</code> instead of <code>$(myDomElement).addClass(‘foo’)</code> — but the more code I wrote, the more frequently and easily I found myself using the dojo.addClass syntax instead. </p>
<p>Embracing this approach was especially valuable when it came to methods that returned something. For example, the <code>dojo.connect()</code> method (used to connect events to elements, similar to <code>$().bind()</code>) returns a connection object, which can be stored and disconnected later without having to know which element the event was attached to. This is, in a word, awesome. It’s also an example of how Dojo requires you to think somewhat differently about how you write your JavaScript. </p>
<h2>Returning a Result For the Win</h2>
<p>Along those lines, I had to get used to the fact that a lot of Dojo methods returned objects that I could talk to later. For example, <code>dojo.animateProperty()</code> created an animation object which could later be play()’d. All of the XHR methods — and asynchronous methods in general — returned a “deferred” object, to which I could later add success and failure callbacks.<br />
jQuery does return the native XHR object from its <code>$.ajax()</code> method, so you can technically add callbacks there too. What I liked about Dojo’s deferred approach is that it provides a common, simple interface for interacting with all asynchronous operations, and even lets you define your own.</p>
<p>Getting the hang of how to take advantage of these things took some doing, coming from the more procedural, chained world of jQuery, where just about everything returns a jQuery object. Soon, though, I was setting up animations long before I was ready to play them, and adding callbacks to XHRs after they started. </p>
<h2>SMDs: A Unified Way to Talk to the Server</h2>
<p>One thing I really wanted to try with Dojo was making use of Service Method Descriptions, or SMDs. An SMD file basically contains information about all of the services provided by a resource. In my case, the resource was the server-side application, which I’d be communicating with to request JSON data.</p>
<p>By creating an SMD file, and then instantiating a new Service based on that file, I could create a single place for managing all the paths and parameters I’d use to get what I needed from the server. When I asked the server for something, the Service I created would return a deferred object, to which I could attach callbacks. In the background, Dojo was just running an XHR, but my individual classes didn’t have to worry about the details — I just had to worry about the name of the method and the parameters it required, and the Service I’d defined and instantiated would take care of the rest.</p>
<p>For my initial work, I just created the SMD file by hand, but eventually it’s easy to see how the SMD could be generated by the server-side application itself. </p>
<p>Here's a sample SMD (normally an SMD would have a lot more services, obviously):</p>
<pre class="javascript">&nbsp;
<span style="color: #66cc66;">&#123;</span>
	transport	: 	<span style="color: #3366CC;">'GET'</span>,
	envelope 	: 	<span style="color: #3366CC;">'PATH'</span>,
	target 		: 	<span style="color: #3366CC;">'/json'</span>,
&nbsp;
	services 	: 	<span style="color: #66cc66;">&#123;</span>
		callouts : <span style="color: #66cc66;">&#123;</span>
			parameters : <span style="color: #66cc66;">&#91;</span>
				<span style="color: #66cc66;">&#123;</span> <span style="color: #000066;">name</span> : <span style="color: #3366CC;">'callouts'</span>, type : <span style="color: #3366CC;">'string'</span> <span style="color: #66cc66;">&#125;</span>
			<span style="color: #66cc66;">&#93;</span>,
			returns : <span style="color: #3366CC;">'object'</span>
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>And here's some abbreviated code that makes use of the SMD:</p>
<pre class="javascript">&nbsp;
dojo.<span style="color: #006600;">provide</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'myProject.Callouts'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'dijit._Widget'</span><span style="color: #66cc66;">&#41;</span>;
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'myProject.Services'</span><span style="color: #66cc66;">&#41;</span>;
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'dojox.rpc.Service'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
dojo.<span style="color: #006600;">declare</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'myProject.Callouts'</span>, dijit._Widget, <span style="color: #66cc66;">&#123;</span>
	cache : <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>,
&nbsp;
	services : <span style="color: #003366; font-weight: bold;">new</span> dojox.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">Service</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">moduleUrl</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'smd'</span>, <span style="color: #3366CC;">'json.smd'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>,
&nbsp;
	postCreate : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// ...</span>
	<span style="color: #66cc66;">&#125;</span>,
	_lookup : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> val = <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">domNode</span>.<span style="color: #006600;">value</span>;
&nbsp;
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">cache</span><span style="color: #66cc66;">&#91;</span>val<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">this</span>._handleResult<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">cache</span><span style="color: #66cc66;">&#91;</span>val<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #66cc66;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> c = <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">services</span>.<span style="color: #006600;">json</span>.<span style="color: #006600;">callouts</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
					<span style="color: #3366CC;">'callouts'</span> : val
				<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
				c.<span style="color: #006600;">addCallback</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">hitch</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>,
					<span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>resp<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
						<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">cache</span><span style="color: #66cc66;">&#91;</span>val<span style="color: #66cc66;">&#93;</span> = resp;
					<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
				<span style="color: #66cc66;">&#41;</span>;
&nbsp;
				c.<span style="color: #006600;">addCallback</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">hitch</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>,
					<span style="color: #3366CC;">'_handleResult'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	_handleResult : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>resp<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// ...</span>
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<h2>Dependency Management and Building</h2>
<p>I love jQuery, I do, but this is an area where it is sorely lacking. It offers little guidance on how to structure your codebase, how to ensure that everything you need is loaded, or how to build your code into production-ready files. Dojo really shines here, but again, it takes a bit of getting used to. </p>
<p>The base dojo.js includes a ton of basic functionality, but I had to quickly learn to dojo.require() additional functionality as I needed it. In jQuery, you’d do this simply by adding another script tag to your HTML; dojo.require() basically does this for you programmatically, but checks to see that the required code hasn’t already been included first. This means each of your components can require exactly what it needs, and it’s perfectly safe to require the same thing more than once. The flip side of this is that if you forget to require something you need, or if you require it using the wrong name, it’s not always clear exactly where you made the mistake.<br />
Each file that will be <code>dojo.require()</code>’d begins with a <code>dojo.provide()</code> statement, telling the dependency management system that it has, indeed, found the right file. After that, the file can go on to <code>dojo.require()</code> its own dependencies, which Dojo loads before proceeding with the rest of the file’s code. The <code>dojo.provide()</code> method also sets up the object chain along the path; for example, if you <code>dojo.provide(‘a.b.c.d’)</code>, you can then safely do <code>a.b.c.d.e = { ... }</code>.</p>
<p>When it comes time to assemble your individual files into production-ready, combined, minified files, Dojo’s build system is able to parse <code>dojo.require()</code> statements and automatically include the appropriate files; with jQuery, this is a much more manual process that can be difficult to maintain. </p>
<p>Creating a build wasn’t as straightforward as I’d hoped it would be, and I stumbed a lot along the way. It took a bit of doing to get all of the paths just right, and to figure out how to have a repeatable build process that we could roll up into our full release process. The payoff was big, though: I could keep my files organized how I wanted them, but only serve one file in production. The build system figured out the steps in between.</p>
<h2>Organization, Inheritance and Abstraction</h2>
<p>As I mentioned above, code organization has been a big issue for me with jQuery. I’ve developed some patterns that I use to keep my code sane, but plenty of other jQuery developers have not, which can make working with other people’s code rather painful. While it’s certainly possible to write procedural, disorganized code with Dojo, <code>dojo.declare()</code> provides a clear way to avoid it. </p>
<p>I talked earlier about creating a namespace for my code and an associated directory. When it came time to start writing, I created individual files in that directory for each component on the page. Inside each file, I indicated which component the file was providing via <code>dojo.provide()</code>, loaded any dependencies via <code>dojo.require()</code>, and then created a class in the namespace using <code>dojo.declare()</code>. </p>
<p>The <code>dojo.declare()</code> method takes three arguments: the name of the class you want to create <code>(‘myNamespace.Thinger’)</code>, other classes you want to “mix in” to your new class (if any — this argument can be null, a single class, or an array of classes), and, lastly, an object that defines the class methods and properties. The result is a class that can be instantiated using <code>new myNamespace.Thinger();</code> the object that’s created encapsulates all the behaviors and states associated with a particular Thinger, and you can have as many instances of Thinger as you want.</p>
<p>The mixing in thing is huge, because it lets you have a class that incorporates methods defined in another class. For example, I created a class called myNamespace.Toggler that would show either the first item in a list or all of the items in a list; clicking on the first list item would toggle between the behaviors. Once the myNamespace.Toggler class was created, other classes could inherit its behavior simply by passing a reference to the myNamespace.Toggler class as the second argument of <code>dojo.declare()</code>. I was able to encapsulate the Toggler behavior in a reusable way, and keep the code for the classes that inherited the Toggler behavior nice and clean.</p>
<h2>Event Management</h2>
<p>I mentioned earlier that Dojo has a slightly different take on event binding than jQuery. I should also say that you can bind events to entire NodeLists (the result of <code>dojo.query()</code>) if you want, using <code>.connect()</code> (or convenience methods like <code>.onclick()</code>, etc.). However, if you want a reference to the connection for later use, <code>dojo.connect()</code> is your friend. </p>
<p>I created a component using <code>dojo.declare()</code> that was responsible for managing user interaction with a star rating UI element. I used <code>dojo.connect()</code> to hook up some mouseover/mouseout behaviors to the element, and stored the returned connections as properties of the component. When the element was clicked, I registered the rating, and I wanted the mouseover/mouseout behaviors to go away; eliminating them was simply a matter of dojo.disconnect()-ing the stored connections. </p>
<pre class="javascript">&nbsp;
dojo.<span style="color: #006600;">provide</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'myProject.Stars'</span><span style="color: #66cc66;">&#41;</span>;
dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'dijit._Widget'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
dojo.<span style="color: #006600;">declare</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'myProject.Stars'</span>, dijit._Widget, <span style="color: #66cc66;">&#123;</span>
	postCreate : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">stars</span> = dojo.<span style="color: #006600;">query</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span>, <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">domNode</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">input</span> = dojo.<span style="color: #006600;">query</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input'</span>, <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">domNode</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">hoverConnections</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>i=<span style="color: #CC0000;">1</span>; i&lt;<span style="color: #CC0000;">6</span>; i++<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> span = dojo.<span style="color: #006600;">create</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'span'</span>, <span style="color: #66cc66;">&#123;</span>
				<span style="color: #3366CC;">'data-value'</span> : i,
				<span style="color: #3366CC;">'class'</span> : <span style="color: #3366CC;">'star_helper'</span>
			<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">hoverConnections</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">connect</span><span style="color: #66cc66;">&#40;</span>span, <span style="color: #3366CC;">'onmouseover'</span>, <span style="color: #000066; font-weight: bold;">this</span>, <span style="color: #3366CC;">'_update'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">hoverConnections</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span>dojo.<span style="color: #006600;">connect</span><span style="color: #66cc66;">&#40;</span>span, <span style="color: #3366CC;">'onmouseout'</span>, <span style="color: #000066; font-weight: bold;">this</span>, <span style="color: #3366CC;">'_reset'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; 
&nbsp;
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">connect</span><span style="color: #66cc66;">&#40;</span>span, <span style="color: #3366CC;">'onclick'</span>, <span style="color: #3366CC;">'_vote'</span><span style="color: #66cc66;">&#41;</span>;
			dojo.<span style="color: #006600;">place</span><span style="color: #66cc66;">&#40;</span>span, <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">stars</span>, <span style="color: #3366CC;">'last'</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	_update : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> val = dojo.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span>e.<span style="color: #006600;">currentTarget</span>, <span style="color: #3366CC;">'data-value'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		dojo.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">domNode</span>, <span style="color: #3366CC;">'class'</span>, <span style="color: #3366CC;">'stars value_'</span> + val<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	_reset : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		dojo.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">domNode</span>, <span style="color: #3366CC;">'class'</span>, <span style="color: #3366CC;">'stars value_0'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	_vote : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		dojo.<span style="color: #006600;">forEach</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">hoverConnections</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>connection<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			dojo.<span style="color: #006600;">disconnect</span><span style="color: #66cc66;">&#40;</span>connection<span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #000066; font-weight: bold;">this</span>._update<span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span>;
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">input</span>.<span style="color: #006600;">value</span> = dojo.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span>e.<span style="color: #006600;">currentTarget</span>, <span style="color: #3366CC;">'data-value'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<h2>Publish and Subscribe</h2>
<p>With all of the XHR traffic occurring on the page, I wanted a way to shut it off if the user was inactive for a little while, but I didn’t want to write the code for handling that inside every component that used XHR. </p>
<p>Dojo’s pub/sub tools offered the perfect answer. I created a new component whose sole purpose was to watch for inactivity; when it discovered inactivity, it would <code>dojo.publish(‘/user/inactive’)</code>. Then, other components — the ones I’d already written, and ones I write in the future — could subscribe to the /user/inactive topic and react accordingly. </p>
<p>Pub/sub is an excellent way to allow this sort of abstract communication between components. The component that publishes a “topic” doesn’t care who’s listening; the component that subscribes to a topic doesn’t care which component sent it. It’s another example of how Dojo leads you to think a bit differently about how you architect your applications — knowing about pub/sub can help you write much more loosely coupled code.</p>
<h2>What I Missed from jQuery</h2>
<p>jQuery’s event delegation-related methods <code>.live()</code> and <code>.is()</code> were hard to live without. There’s a reasonable way to mimic <code>.is()</code>, but no out-of-the-box replacement for <code>.live()</code> — you end up writing your event delegation yourself. Dojo does have <code>dojo.behavior()</code>, which automatically binds event handlers to elements that match a given selector as they’re added to the page; however, the event handlers are bound to individual elements, and there’s no way to provide a context to the selector that you pass to <code>dojo.behavior()</code>.</p>
<p>This may be my noob-ness talking, or maybe I’m just used to the error messages I’d see when I did something wrong with jQuery, but I often found myself feeling that the error messages from Dojo were too cryptic. Worse, sometimes I’d do something wrong and it would seem to fail silently. I spent a lot more time in Firebug tracking down the errors of my ways.</p>
<p>In general, the thing I really missed from jQuery was the “it just works” aspect of the library. I expect that with time I’ll feel that way about Dojo, but in the meantime there are definitely growing pains. I had to constantly remind myself that the way to solve a problem in Dojo might not be the same way I’d solve it in jQuery. More than once I rewrote a slew of code when I discovered some Dojo methodology or approach I hadn’t known about before.</p>
<h2>Conclusion</h2>
<p>Lest Rey worry that he never should have introduced me to Pete in the first place, fear not: I don’t expect to give up jQuery anytime soon. If anything, I’m excited to see how the library and the community mature and start answering some of the organization and dependency management questions I mentioned above. As a library, jQuery most definitely has its place; it has virtually no barriers to entry and it has helped usher in an era where it’s dead-simple to create rich, interactive websites.  </p>
<p>Deciding to use Dojo instead was something of a gamble. I had to convince the project lead that it was a good decision, which was challenging considering the popularity of the jQuery library. He asked lots of pointed questions about the maintainability of the code if I were to leave the project, and those questions were well deserved. If anything, though, I think that choosing Dojo has actually increased the maintainability of the code by presenting clear patterns for organization, abstraction, and dependency management.<br />
Did it take a while to come up to speed with Dojo? For sure. Will a jQuery developer off the street be able to jump right in to the code I wrote? Possibly not. At the end of the day, though, it is just JavaScript, and any skilled JavaScript developer should be able to find their way around. They’ll almost certainly find, given an hour or two, that the code I wrote is easier to follow than some of the jQuery code I’ve run into that doesn’t make use of good organizing principles.  </p>
<p>In the meantime, I hope to be working on the project for a while to come, and I expect the trouble I went through to come up to speed on Dojo will pay big dividends as the application I’m working on grows and matures. </p>
<h2>Learn More</h2>
<ul>
<li><a href="http://docs.dojocampus.org/manual/index">Dojo documentation</a></li>
<li><a href="http://www.sitepen.com/blog/2008/03/19/pluggable-web-services-with-smd/">Service method descriptions</a></li>
<li><a href="http://higginsforpresident.net/js/static/jq.pubsub.js">jQuery pub/sub plugin</a></li>
<li><a href="http://github.com/phiggins42/twitterverse">Twitterverse, an example of a simple Dojo application</a></li>
<li><a href="http://oreilly.com/catalog/9780596516482/">Dojo: The Definitive Guide</a>, by Matthew A. Russell</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/11/12/dojo-confessions-or-how-i-gave-up-my-jquery-security-blanket-and-lived-to-tell-the-tale/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Introducing yayQuery &#8212; A jQuery podcast</title>
		<link>http://blog.rebeccamurphey.com/2009/11/05/introducing-yayquery-a-jquery-podcast/</link>
		<comments>http://blog.rebeccamurphey.com/2009/11/05/introducing-yayquery-a-jquery-podcast/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 01:50:23 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=229</guid>
		<description><![CDATA[
  
  

If you'd like a download:
mp3 audio (30mb), mp4 video (94mb), ogg video (61mb), Vimeo
In this our first episode of the official yayQuery Podcast, Paul Irish, Adam J. Sontag, Alex Sexton and I stayed up way too late on Monday night and had ridiculous amounts of fun talking about: 

Underscore.js, the new [...]]]></description>
			<content:encoded><![CDATA[<p><video width="360" height="240" poster="http://a1.twimg.com/profile_images/505119928/yayquery.png" autobuffer controls><br />
  <source src="http://paulirish.com/yayQuery/yayQuery_1.0.ogv" type='video/ogg; codecs="theora, vorbis"'><br />
  <source src="http://paulirish.com/yayQuery/yayQuery_1.0.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'><br />
</video></p>
<p>If you'd like a download:<br />
<a href="http://paulirish.com/yayQuery/yayQuery_1.0.mp3">mp3 audio (30mb)</a>, <a href="http://paulirish.com/yayQuery/yayQuery_1.0.mp4">mp4 video (94mb)</a>, <a href="http://paulirish.com/yayQuery/yayQuery_1.0.ogv">ogg video (61mb)</a>, <a href="http://vimeo.com/7462067">Vimeo</a></p>
<p>In this our first episode of the official yayQuery Podcast, <a href="http://paulirish.com/">Paul Irish</a>, <a href="http://www.ajpiano.com/">Adam J. Sontag</a>, <a href="http://alexsexton.com/">Alex Sexton</a> and I stayed up way too late on Monday night and had ridiculous amounts of fun talking about: </p>
<ul>
<li><a href="http://documentcloud.github.com/underscore/">Underscore.js</a>, the new functional programming JavaScript library. </li>
<li>The demise of Thickbox (and some good, modern alternatives).</li>
<li>Using (or not using) jQuery for mobile development.</li>
<li>Paul Irish's antipattern of the week: css(key, value)</li>
<li>$var vs. var (<a href="http://en.wikipedia.org/wiki/Hungarian_notation">Hungarian Notation</a>)</li>
</ul>
<p>Perhaps because it was so late when we finished, there was also chair dancing. Make sure you don't miss it, but don't fast-forward to the end or you'll miss the good stuff.</p>
<p>This is our first try with this, and who knows what will become of it, but we're very grateful for any and all feedback. You can find us on Twitter <a href="http://twitter.com/yayQuery">@yayQuery</a>, or on the #jquery IRC channel. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/11/05/introducing-yayquery-a-jquery-podcast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://paulirish.com/yayQuery/yayQuery_1.0.ogv" length="63707540" type="video/ogg" />
<enclosure url="http://paulirish.com/yayQuery/yayQuery_1.0.mp4" length="98775887" type="video/mp4" />
<enclosure url="http://paulirish.com/yayQuery/yayQuery_1.0.mp3" length="31439904" type="audio/mpeg" />
		</item>
		<item>
		<title>Using Objects to Organize Your Code</title>
		<link>http://blog.rebeccamurphey.com/2009/10/15/using-objects-to-organize-your-code/</link>
		<comments>http://blog.rebeccamurphey.com/2009/10/15/using-objects-to-organize-your-code/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 12:53:15 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=219</guid>
		<description><![CDATA[This is a reprint of an article that originally appeared in the March 2009 issue of JSMag.
When you move beyond simple snippets of jQuery and start developing more complex user interactions, your code can quickly become unwieldy and difficult to debug. This article shows you how to start thinking about these interactions in terms of [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a reprint of an article that originally appeared in the March 2009 issue of <a href="http://jsmag.com">JSMag</a>.</em></p>
<p>When you move beyond simple snippets of jQuery and start developing more complex user interactions, your code can quickly become unwieldy and difficult to debug. This article shows you how to start thinking about these interactions in terms of the bits of behavior the feature comprises, using the object literal pattern.</p>
<p>In the past few years, JavaScript libraries have given beginning developers the ability to add elaborate interactions to their sites. Some, like jQuery, have a syntax so simple that people with zero programming experience can quickly add bells and whistles to their pages.</p>
<p>Adding all those bells and whistles, even some pretty elaborate ones, seems to be just a few Google searches away. A copy here, a paste there, a plugin or a few dozen lines of custom code — the client is duly impressed, and you’re adding jQuery to your resume.</p>
<p>But wait. Now the requirements have changed. Now the thing that needed to work for three elements needs to work for ten. Now your code needs to be reused for a slightly different application where all the IDs are different.</p>
<p>We’ve all seen the snippets that make jQuery (and other libraries) look dead-simple. What those snippets leave out — and hey, they’re just snippets, right? — is how to design your code when your needs go beyond dropping in a plugin or doing some show() and hide().</p>
<h2>Introducing the Object Literal pattern</h2>
<p>The object literal pattern offers a way to organize code by the behaviors it comprises. It’s also a means to keep your code from “polluting the global namespace,” which is a good practice for all projects and imperative for larger ones. It forces you to think at the outset about what your code will do and what pieces need to be in place in order for you to do it.<br />
An object literal is a way to encapsulate related behaviors, as shown here:</p>
<pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> myObjectLiteral = <span style="color: #66cc66;">&#123;</span>
	myBehavior1 : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">/* do something */</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	myBehavior2 : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">/* do something else */</span>
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>;</pre>
<p>As an artificially simplistic example, suppose you had the jQuery shown in Listing 2 for showing and hiding content when a list item was clicked.</p>
<pre class="javascript">$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#myFeature li'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">append</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;div&gt;'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #66cc66;">&#41;</span>.
				<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'foo.php?item='</span> + $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
	<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">show</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">siblings</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">hide</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;&lt;/div&gt;
&nbsp;</pre>
<p>Simple enough, and yet even in this example there are several things you might want to change later — for example, the way you determine the URL for loading the content, the destination of the loaded content, or the show and hide behavior.</p>
<p>An object literal representation of the feature cleanly separates these aspects. It might look like this:</p>
<pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> myFeature = <span style="color: #66cc66;">&#123;</span>
	config : <span style="color: #66cc66;">&#123;</span>
		$wrapper : $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#myFeature'</span><span style="color: #66cc66;">&#41;</span>,
		container : <span style="color: #3366CC;">'div'</span>,
		urlBase : <span style="color: #3366CC;">'foo.php?item='</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	init : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>config<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$.<span style="color: #006600;">extend</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">config</span>, config<span style="color: #66cc66;">&#41;</span>;
		myFeature.<span style="color: #006600;">config</span>.$wrapper.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'li'</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				myFeature.<span style="color: #006600;">getContent</span><span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				myFeature.<span style="color: #006600;">showContent</span><span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	buildUrl : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$li<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">return</span> myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">urlBase</span> + $li.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>, 
&nbsp;
	getContent : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$li<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$li.<span style="color: #006600;">append</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">container</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #003366; font-weight: bold;">var</span> url = myFeature.<span style="color: #006600;">buildUrl</span><span style="color: #66cc66;">&#40;</span>$li<span style="color: #66cc66;">&#41;</span>;
		$li.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">container</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span>url<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	showContent : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$li<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$li.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">show</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		myFeature.<span style="color: #006600;">hideContent</span><span style="color: #66cc66;">&#40;</span>$li.<span style="color: #006600;">siblings</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	hideContent : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$elements<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$elements.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">hide</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>;
&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> myFeature.<span style="color: #006600;">init</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre>
<p>Because the initial example was incredibly simplistic, the object literal incarnation is longer. Truth be told, the object literal method generally won’t save you lines of code. What it will save is headaches. By using an object literal, we’ve broken our code into its logical parts, making it easy to locate the things we might want to change down the road. We’ve made our feature extendable, by providing the ability to pass in overrides to the default configuration. And, we’ve done some limited self-documentation — it’s easy to see at a glance what the feature does. As your needs grow beyond the simplicity of this example the benefits of the structure will become clearer, as you’ll see below.</p>
<p><em>Note: For an excellent primer on objects, properties, and methods, check out <a href="http://www.amazon.com/Object-Oriented-JavaScript-high-quality-applications-libraries/dp/1847194141">Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries</a> by Stoyan Stefanov. You may also want to read up on JSON (JavaScript Object Notation). </em></p>
<h2>An in-depth example</h2>
<p>Our mission will be to create a UI element that features multiple pieces of content divided into several sections. Clicking on a section will show a list of items in the section; clicking on an item in the left nav will show the item in the content area. Whenever a section is shown, the first item in the section should be shown. The first section should be shown when the page loads.</p>
<h3>Step 1: Crafting the HTML</h3>
<p>Writing good semantic HTML is a crucial prerequisite to writing good JavaScript, so let’s start by thinking about what the HTML for something like this might look like. The HTML should:</p>
<ul>
<li>Make sense (and work) when JavaScript isn’t available.</li>
<li>Provide a predictable DOM to which we can attach JavaScript.</li>
<li>Avoid unnecessary IDs and classes (and you might be surprised by how few are necessary).</li>
</ul>
<p>With those guidelines in mind, we’ll start with <a href="http://www.rebeccamurphey.com/jsmag/object-literal/">this html</a>.</p>
<p>Note that we haven’t included any markup to display the section navigation or the item navigation; those pieces will be added by jQuery since they will only work with jQuery; non-JavaScript users will get nice semantic markup. (If there’s anything surprising or confusing in that HTML, now would be a good time to read up on POSH (plain-old semantic HTML) and progressive enhancement.)</p>
<h3>Step 2: Scaffolding the Object</h3>
<p>My first step in creating an object for a feature is to create “stubs” within the object. Stubs are basically placeholders; they’re the outline for the feature we’re going to build. Our object will have the following methods:</p>
<ul>
<li><strong>myFeature.init()</strong> will run on $(document).ready(). It will turn the semantic HTML we start with into a JavaScript-enabled user interface.</li>
<li><strong>myFeature.buildSectionNav()</strong> will be called by myFeature.init(). It will take a jQuery object that contains all of the sections from the semantic HTML and use those sections to build the top navigation. It will bind the click handlers to the top navigation items so that clicking on them will show the appropriate section.</li>
<li><strong>myFeature.buildItemNav()</strong> will be called by myFeature.showSection(). It will take a jQuery object that contains all of the items associated with the section from the semantic HTML, and use them to build the side navigation. It will bind the click handlers to the side navigation items so that clicking on them will show the appropriate content.</li>
<li><strong>myFeature.showSection()</strong> will be called when the user clicks on an item in the top navigation. It will use the navigation item that’s clicked on to figure out which section to show from the semantic HTML.</li>
<li><strong>myFeature.showContentItem()</strong> will be called when the user clicks on an item in the side navigation. It will use the navigation item that’s clicked on to figure out which content item to show from the semantic HTML.</li>
<li>We’ll also make room for a configuration property, <strong>myFeature.config</strong>, which will be a single location for setting default values rather than scattering them throughout the code. We’ll include the ability to override the defaults when we define the myFeature.init() method.</li>
<pre class="javascript">&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> myFeature = <span style="color: #66cc66;">&#123;</span>
	<span style="color: #3366CC;">'config'</span> : <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>,
	<span style="color: #3366CC;">'init'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>,
	<span style="color: #3366CC;">'buildSectionNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>,
	<span style="color: #3366CC;">'buildItemNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>,
	<span style="color: #3366CC;">'showSection'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>,
	<span style="color: #3366CC;">'showContentItem'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>;
&nbsp;</pre>
<h3>Step 3: The Code</h3>
<p>Once we’ve built this skeleton, it’s time to start coding. Let’s start by setting up a simple myFeature.config object and writing the myFeature.init() method:</p>
<pre class="javascript">&nbsp;
<span style="color: #3366CC;">'config'</span> : <span style="color: #66cc66;">&#123;</span>
	<span style="color: #009900; font-style: italic;">// default container is #myFeature</span>
	<span style="color: #3366CC;">'container'</span> : $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#myFeature'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>,
&nbsp;
<span style="color: #3366CC;">'init'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>config<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> 
&nbsp;
	<span style="color: #009900; font-style: italic;">// provide for custom configuration via init()</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>config &amp;&amp; <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #66cc66;">&#40;</span>config<span style="color: #66cc66;">&#41;</span> == <span style="color: #3366CC;">'object'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		$.<span style="color: #006600;">extend</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">config</span>, config<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">// create and/or cache some DOM elements</span>
	<span style="color: #009900; font-style: italic;">// we'll want to use throughout the code</span>
	myFeature.$container = myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">container</span>;
&nbsp;
	myFeature.$sections = myFeature.$container.
		<span style="color: #009900; font-style: italic;">// only select immediate children!</span>
		find<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'ul.sections &gt; li'</span><span style="color: #66cc66;">&#41;</span>; 
&nbsp;
	myFeature.$section_nav = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;ul/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span>,<span style="color: #3366CC;">'section_nav'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">prependTo</span><span style="color: #66cc66;">&#40;</span>myFeature.$container<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	myFeature.$item_nav = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;ul/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span>,<span style="color: #3366CC;">'item_nav'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">insertAfter</span><span style="color: #66cc66;">&#40;</span>myFeature.$section_nav<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	myFeature.$content = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;div/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span>,<span style="color: #3366CC;">'content'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">insertAfter</span><span style="color: #66cc66;">&#40;</span>myFeature.$item_nav<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// build the section-level nav and</span>
	<span style="color: #009900; font-style: italic;">// &quot;click&quot; the first item</span>
	myFeature.<span style="color: #006600;">buildSectionNav</span><span style="color: #66cc66;">&#40;</span>myFeature.$sections<span style="color: #66cc66;">&#41;</span>;
	myFeature.$section_nav.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'li:first'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// hide the plain HTML from sight</span>
	myFeature.$container.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'ul.sections'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">hide</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// make a note that the initialization</span>
	<span style="color: #009900; font-style: italic;">// is complete; we don't strictly need this</span>
	<span style="color: #009900; font-style: italic;">// for this iteration, but it can come in handy</span>
	myFeature.<span style="color: #006600;">initialized</span> = <span style="color: #003366; font-weight: bold;">true</span>;
&nbsp;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Next we’ll create the myFeature.buildSectionNav() method:</p>
<pre class="javascript">&nbsp;
<span style="color: #3366CC;">'buildSectionNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$sections<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">// iterate over the provided list of sections</span>
	$sections.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
		<span style="color: #009900; font-style: italic;">// get the section</span>
		<span style="color: #003366; font-weight: bold;">var</span> $section = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;		
&nbsp;
		<span style="color: #009900; font-style: italic;">// create an</span>
&lt;li&gt; element
		<span style="color: #009900; font-style: italic;">// for the section navigation</span>
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// use the text of the first h2</span>
			<span style="color: #009900; font-style: italic;">// in the section as the text for</span>
			<span style="color: #009900; font-style: italic;">// the section navigation</span>
			text<span style="color: #66cc66;">&#40;</span>$section.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'h2:first'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #009900; font-style: italic;">// add the</span>
&lt;li&gt; to the section navigation
			appendTo<span style="color: #66cc66;">&#40;</span>myFeature.$section_nav<span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// use data() to store a reference</span>
			<span style="color: #009900; font-style: italic;">// to the original section on the</span>
			<span style="color: #009900; font-style: italic;">// newly-created</span>
&lt;li&gt;
			data<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'section'</span>, $section<span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// bind the click behavior</span>
			<span style="color: #009900; font-style: italic;">// to the newly created</span>
&lt;li&gt;
			<span style="color: #009900; font-style: italic;">// so it will show the section</span>
			click<span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">showSection</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Next we’ll create the myFeature.buildItemNav() method:</p>
<pre class="javascript">&nbsp;
<span style="color: #3366CC;">'buildItemNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$items<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">// iterate over the provided list of items</span>
	$items.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
		<span style="color: #009900; font-style: italic;">// get the item</span>
		<span style="color: #003366; font-weight: bold;">var</span> $item = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// create an</span>
&lt;li&gt; element <span style="color: #000066; font-weight: bold;">for</span> the <span style="color: #000066; font-weight: bold;">item</span> navigation
		$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// use the text of the first h3</span>
			<span style="color: #009900; font-style: italic;">// in the item as the text for the</span>
			<span style="color: #009900; font-style: italic;">// item navigation</span>
			text<span style="color: #66cc66;">&#40;</span>$item.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'h3:first'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// add the</span>
&lt;li&gt; to the <span style="color: #000066; font-weight: bold;">item</span> navigation
			appendTo<span style="color: #66cc66;">&#40;</span>myFeature.$item_nav<span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// use data() to store a reference</span>
			<span style="color: #009900; font-style: italic;">// to the original item on the</span>
			<span style="color: #009900; font-style: italic;">// newly-created</span>
&lt;li&gt;
			data<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'item'</span>, $item<span style="color: #66cc66;">&#41;</span>.
&nbsp;
			<span style="color: #009900; font-style: italic;">// bind the click behavior</span>
			<span style="color: #009900; font-style: italic;">// to the newly created</span>
&lt;li&gt;
			<span style="color: #009900; font-style: italic;">// so it will show the content item</span>
			click<span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">showContentItem</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Finally, we’ll write the methods for showing sections and content items:</p>
<pre class="javascript">&nbsp;
<span style="color: #3366CC;">'showSection'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> 
&nbsp;
	<span style="color: #009900; font-style: italic;">// capture the</span>
&lt;li&gt; that was clicked on
	<span style="color: #003366; font-weight: bold;">var</span> $li = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// clear out the left nav and the content area</span>
	myFeature.$item_nav.<span style="color: #006600;">empty</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	myFeature.$content.<span style="color: #006600;">empty</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// get the jQuery section object from the original HTML,</span>
	<span style="color: #009900; font-style: italic;">// which we stored using data() during myFeature.buildSectionNav()</span>
	<span style="color: #003366; font-weight: bold;">var</span> $section = $li.<span style="color: #006600;">data</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'section'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// mark the clicked</span>
&lt;li&gt; <span style="color: #000066; font-weight: bold;">as</span> current
	<span style="color: #009900; font-style: italic;">// and remove the current marker from its siblings</span>
	$li.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'current'</span><span style="color: #66cc66;">&#41;</span>.
		<span style="color: #006600;">siblings</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'current'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// find all of the items related to the section</span>
	<span style="color: #003366; font-weight: bold;">var</span> $items = $section.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'ul li'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// build the item nav for the section</span>
	myFeature.<span style="color: #006600;">buildItemNav</span><span style="color: #66cc66;">&#40;</span>$items<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #009900; font-style: italic;">// &quot;click&quot; on the first</span>
&lt;li&gt; <span style="color: #000066; font-weight: bold;">in</span> the section<span style="color: #3366CC;">'s item nav
	myFeature.$item_nav.find('</span>li:first<span style="color: #3366CC;">').click();
&nbsp;
},
&nbsp;
'</span>showContentItem<span style="color: #3366CC;">' : function() {
&nbsp;
	var $li = $(this);
&nbsp;
	// mark the clicked
&lt;li&gt; as current
	// and remove the current marker from its siblings
	$li.addClass('</span>current<span style="color: #3366CC;">').
		siblings().removeClass('</span>current<span style="color: #3366CC;">');
&nbsp;
	// get the jQuery item object from the orignial HTML,
	// which we stored using data() during myFeature.buldContentNav()
	var $item = $li.data('</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #3366CC;">');
	// use the item'</span>s HTML to populate
	<span style="color: #009900; font-style: italic;">// the content area</span>
	myFeature.$content.<span style="color: #006600;">html</span><span style="color: #66cc66;">&#40;</span>$item.<span style="color: #006600;">html</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>All that’s left to do is to call the myFeature.init() method:</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">init</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>You can see the whole thing (including a little CSS to make it presentable) <a href="http://www.rebeccamurphey.com/jsmag/object-literal/">here</a>.</p>
<h3>Step 4: Changing Requirements</h3>
<p>No project is complete without some last-minute change in the requirements, right? Here’s where the object literal approach really shines by making it quick and fairly painless to implement last-minute changes.</p>
<p>What if we need to get the content item excerpts via AJAX instead of from the HTML? Assuming the backend is set up to handle it, try this:</p>
<pre class="javascript">&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> myFeature = <span style="color: #66cc66;">&#123;</span>
&nbsp;
	<span style="color: #3366CC;">'config'</span> : <span style="color: #66cc66;">&#123;</span>
		<span style="color: #3366CC;">'container'</span> : $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#myFeature'</span><span style="color: #66cc66;">&#41;</span>,
&nbsp;
		<span style="color: #009900; font-style: italic;">// configurable function for getting</span>
		<span style="color: #009900; font-style: italic;">// a URL for loading item content</span>
		<span style="color: #3366CC;">'getItemURL'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$item<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> $item.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'a:first'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span>
&nbsp;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'init'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>config<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'buildSectionNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$sections<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'buildItemNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$items<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'showSection'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'showContentItem'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
		<span style="color: #003366; font-weight: bold;">var</span> $li = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		$li.<span style="color: #006600;">addClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'current'</span><span style="color: #66cc66;">&#41;</span>.
			<span style="color: #006600;">siblings</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'current'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #003366; font-weight: bold;">var</span> $item = $li.<span style="color: #006600;">data</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'item'</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #003366; font-weight: bold;">var</span> url = myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">getItemURL</span><span style="color: #66cc66;">&#40;</span>$item<span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #009900; font-style: italic;">// myFeature.$content.html($item.html());</span>
		myFeature.$content.<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span>url<span style="color: #66cc66;">&#41;</span>;
&nbsp;
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#125;</span>;
&nbsp;</pre>
<p>Do you need more flexibility? There’s a lot more you can configure (and therefore override) if you really want to make this flexible. For example, you can use myFeature.config to specify how to find and process the title text for each item in the left nav. </p>
<pre class="javascript">&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> myFeature = <span style="color: #66cc66;">&#123;</span>
	<span style="color: #3366CC;">'config'</span> : <span style="color: #66cc66;">&#123;</span>
		<span style="color: #3366CC;">'container'</span> : $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#myFeature'</span><span style="color: #66cc66;">&#41;</span>,
&nbsp;
		<span style="color: #009900; font-style: italic;">// specify the default selector</span>
		<span style="color: #009900; font-style: italic;">// for finding the text to use</span>
		<span style="color: #009900; font-style: italic;">// for each item in the item nav</span>
		<span style="color: #3366CC;">'itemNavSelector'</span> : <span style="color: #3366CC;">'h3'</span>,
&nbsp;
		<span style="color: #009900; font-style: italic;">// specify a default callback</span>
		<span style="color: #009900; font-style: italic;">// for &quot;processing&quot; the jQuery object</span>
		<span style="color: #009900; font-style: italic;">// returned by the itemNavText selector</span>
		<span style="color: #3366CC;">'itemNavProcessor'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$selection<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'Preview of '</span> +
				$selection.<span style="color: #006600;">eq</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'init'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>config<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'buildSectionNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$sections<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'buildItemNav'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>$items<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
		$items.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> $item = $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
			<span style="color: #009900; font-style: italic;">// use the selector and processor</span>
			<span style="color: #009900; font-style: italic;">// from the config</span>
			<span style="color: #009900; font-style: italic;">// to get the text for each item nav</span>
			<span style="color: #003366; font-weight: bold;">var</span> myText = myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">itemNavProcessor</span><span style="color: #66cc66;">&#40;</span>
				$item.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">config</span>.<span style="color: #006600;">itemNavSelector</span><span style="color: #66cc66;">&#41;</span>
			<span style="color: #66cc66;">&#41;</span>;
&nbsp;
			$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'
&lt;li/&gt;'</span><span style="color: #66cc66;">&#41;</span>.
				<span style="color: #009900; font-style: italic;">// use the new variable</span>
				<span style="color: #009900; font-style: italic;">// as the text for the nav item</span>
				text<span style="color: #66cc66;">&#40;</span>myText<span style="color: #66cc66;">&#41;</span>.
				<span style="color: #006600;">appendTo</span><span style="color: #66cc66;">&#40;</span>myFeature.$item_nav<span style="color: #66cc66;">&#41;</span>.
				<span style="color: #006600;">data</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'item'</span>, $item<span style="color: #66cc66;">&#41;</span>.
				<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span>myFeature.<span style="color: #006600;">showContentItem</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'showSection'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>,
&nbsp;
	<span style="color: #3366CC;">'showContentItem'</span> : <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #009900; font-style: italic;">// stays the same</span>
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&#125;</span>;
&nbsp;</pre>
<p>Once you’ve added defaults to the config object, you can override them when you call myFeature.init():</p>
<pre class="javascript">&nbsp;
$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
	myFeature.<span style="color: #006600;">init</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span> <span style="color: #3366CC;">'itemNavSelector'</span> : <span style="color: #3366CC;">'h2'</span> <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>Beyond the scope of this article (but also interesting to contemplate and much easier with the object literal pattern) is this: making the back button retrace your path through the tabs using the jQuery history plugin. I leave it as an exercise for the reader.</p>
<h2>Conclusion</h2>
<p>If you’ve stepped through the code examples in this column, you should have a basic understanding of the object literal pattern and how it might prove useful to you as you develop more complex features and interactions. You also have access to some code that you can use to build on this basic foundation.</p>
<p>I encourage you to give this pattern a try the next time you find yourself writing more than a few lines of JavaScript — it forces you to think through the elements and behaviors that make up a complex feature or interaction. Once you become proficient, it provides a sturdy foundation for extending and reusing your code.</p>
<h2>Learn More</h2>
<ul>
<li><a href="http://docs.jquery.com/Data">More on the jQuery data() method</a></li>
<li><a href="http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/">More praise for the object literal pattern</a></li>
<li><a href="http://www.mikage.to/jquery/jquery_history.html">The jQuery History plugin</a></li>
<li><a href="http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/">An interesting application of the object literal pattern for architecting code for multiple page types</li>
<li><a href="/organize-your-jquery">My presentation at the 2009 jQuery Conference about code organization</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/10/15/using-objects-to-organize-your-code/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dojo article in JSMag</title>
		<link>http://blog.rebeccamurphey.com/2009/10/08/dojo-article-in-jsmag/</link>
		<comments>http://blog.rebeccamurphey.com/2009/10/08/dojo-article-in-jsmag/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 04:37:06 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=217</guid>
		<description><![CDATA[I've been doing some work with Dojo lately for a client project, and wrote up an article about my experience with the library (coming from a jQuery background) for JSMag this month. If you're interested, definitely check the magazine out -- it's only five bucks, and there are some other great articles in there this [...]]]></description>
			<content:encoded><![CDATA[<p>I've been doing some work with Dojo lately for a client project, and wrote up an article about my experience with the library (coming from a jQuery background) for <a href="http://jsmag.com/latest">JSMag</a> this month. If you're interested, definitely check the magazine out -- it's only five bucks, and there are some other great articles in there this month too. I'm a particular fan of the article by Scott Gonzalez about building stateful plugins using the jQuery UI widget factory -- super-neat stuff that I wasn't aware of. Anyway, check it out, and let me know your thoughts. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/10/08/dojo-article-in-jsmag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inaugural North Carolina jQuery Camp</title>
		<link>http://blog.rebeccamurphey.com/2009/09/19/inaugural-north-carolina-jquery-camp/</link>
		<comments>http://blog.rebeccamurphey.com/2009/09/19/inaugural-north-carolina-jquery-camp/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 23:52:34 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=215</guid>
		<description><![CDATA[I'm just back from the inaugural North Carolina jQuery Camp at Viget Labs in Durham, N.C., and a couple of people have asked how it went, so I thought I'd write a quick post. I had a whim a few weeks ago to organize the camp; I envisioned an unstructured day where fellow jQuery developers [...]]]></description>
			<content:encoded><![CDATA[<p>I'm just back from the inaugural North Carolina jQuery Camp at <a href="http://www.viget.com">Viget Labs</a> in Durham, N.C., and a couple of people have asked how it went, so I thought I'd write a quick post. I had a whim a few weeks ago to organize the camp; I envisioned an unstructured day where fellow jQuery developers could get together and talk about how they use the library. I figured that since the jQuery Conference had sold out and had a huge waiting list, getting a couple dozen people together on a Saturday in Durham, N.C. wouldn't be that hard. </p>
<p>We had around 25 people show up to the camp today, from novices to experts, including Scott Gonzalez, a contributor to the jQuery UI library. True to my (utter lack of) vision, it was a very unstructured day, but productive and fun I think. My only experience with unconferences was at BarCamp RDU just a few weeks ago, so it took me a bit to get into full go-with-the-flow mode, but when I didn't know what to do, I just asked "what do I do now?" and usually someone would tell me.</p>
<p>We started out by writing some topic ideas up on the wall, and quickly had enough to get started. I split off with the novices to give an intro to the library, while the main room dug into the topics that had been suggested, starting with a talk by Scott about stateful plugins. Up next was Brian Landau from Viget, showing off the code for his mapping plugin and giving an overview of ScrewUnit; then, David Eisinger, also of Viget, showed us some simple strategies for improving perceived performance. </p>
<p>Lunch -- made possible by the generosity of Rich Orris, FireStream Media, Ignite Social Media, and DesignHammer -- was time for informal conversations and demonstrations. Here's Scott and someone whose name I don't remember doing some quality whiteboarding:</p>
<p><a href="http://www.flickr.com/photos/rdmey/3934960677/" title="IMG_7126 by rdmey, on Flickr"><img src="http://farm3.static.flickr.com/2655/3934960677_61ac1733ce.jpg" width="500" height="333" alt="IMG_7126" /></a></p>
<p>We came back from lunch with a reprise of my presentation from the jQuery Conference about using objects to organize your code, minus FAST FORWARD but otherwise largely intact. I was grateful to have more than 30 minutes this time, and we ended up having some good conversation about code organization in general. </p>
<p>From there it was on to some great show-and-tell -- people are doing excellent things with the library, and doing them with ease -- and then Scott wrapped up the day with an overview of jQuery UI. Probably the biggest hit of the day was Scott's "just one more thing ..." moment, when he showed us a whole new API for using the position method as a setter, coming soon to a plugin near you. Lots of oohs and aahs about that one.</p>
<p>I said at the end of the day that this first camp was really just a proof of concept -- yes, I can get 25 people to show up to talk about jQuery. I'm hoping to do another jQuery camp in January, perhaps. There are a few things I'd like to do differently next time. For one, I'd like to be a little bit more intentional about having more than one session that's suitable for beginners -- a lot of the presentations were super-interesting, but way over the heads of people just getting started. </p>
<p>Also, there were a number of people who signed up who didn't make it, which is a shame because I ordered food expecting a larger turnout. I'd asked people to let me know if they couldn't make it, but alas only a handful did. Next time, I think I'll charge a token amount to attend -- say $10 or so -- so people will feel a bit more committed. If they don't make it, at least their food will be paid for! Charging a few dollars will also help reduce the need for sponsors -- not that I don't love the sponsors, just that it was a bit of work and stress to line them up.</p>
<p>Finally, next time I'd like to be a little bit more intentional about setting up and promoting the event. This time around, I started promoting it before I even had a venue, and shortly after I secured a venue (thank you Viget!) all the slots were filled. Next time around, I might approach that a little bit differently, especially if I can line up a few different venue options.</p>
<p>That's my report. For more pictures, visit <a href="http://www.flickr.com/photos/rdmey/tags/ncjquerycamp/">Flickr</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/09/19/inaugural-north-carolina-jquery-camp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>On speaking at the 2009 jQuery Conference</title>
		<link>http://blog.rebeccamurphey.com/2009/09/16/on-speaking-at-the-2009-jquery-conference/</link>
		<comments>http://blog.rebeccamurphey.com/2009/09/16/on-speaking-at-the-2009-jquery-conference/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 20:32:42 +0000</pubDate>
		<dc:creator>Rebecca</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[speaking]]></category>
		<category><![CDATA[thoughts]]></category>

		<guid isPermaLink="false">http://blog.rebeccamurphey.com/?p=211</guid>
		<description><![CDATA[One of my personal goals for this year was to start being part of the solution to the dearth of female speakers at tech events. Though I've talked at a couple of smallish local events over the past few months, this past weekend I got to do it in a big way: I presented a [...]]]></description>
			<content:encoded><![CDATA[<p>One of my personal goals for this year was to start being part of the solution to the dearth of female speakers at tech events. Though I've talked at a couple of smallish local events over the past few months, this past weekend I got to do it in a big way: I presented a talk on <a href="http://blog.rebeccamurphey.com/organize-your-jquery">using objects to organize your jQuery code</a> to an audience of around 100 people, more by far than I've ever spoken to before. </p>
<p>[This post isn't so much about the talk itself as my first experience with talking at a conference. If you're interested in the talk, I encourage you to check out the slides, links, and code at the link above.]</p>
<p>I decided I wanted to try to talk at the jQuery conference after I saw the initial very smart, very male speaker lineup. I submitted my talk based on an article I wrote for <a href="http://jsmag.com">JSMag</a> earlier this year, and by the time it was all said and done, mine was the second most popular topic and I was slated to have 30 minutes in "the big room." </p>
<p>There is something sort of out-of-body about that moment when I am standing in front of a roomful of people right before I talk -- I had it when I gave my first Refresh talk, when I taught my first jQuery class, when I spoke at my first BarCamp RDU, and yet again this weekend. For that moment, in my head, I am a complete and utter case, and can't quite fathom that I thought this was a good idea. And then I start talking, and then it is OK. And then when it's over, people clap, and I like that part. </p>
<p>Back when I set out to start speaking more, I decided to take an improv class. For six weeks, we practiced being spontaneously funny, and at the end, we got up on stage in front of a bunch of strangers and tried to do it for real. Knowing what that feels like -- what it feels like to run up the aisle like you're excited when really you're terrified because you've never done this before and in real life you sit at a desk all day and talk to no one and what were you thinking? -- makes the thought of talking to a bunch of strangers about what you actually know how to do seem like a completely reasonable thing.</p>
<p>My experience this weekend was nothing short of excellent -- people I barely knew rallied around me throughout the weekend to help me improve my presentation (most notably Chris Williams, organizer of JSConf, to whom I owe many thanks for all the images -- especially the Liger). The audience graciously tolerated the part in the middle where I had to leave the podium to (very publicly) blow my nose. People asked great questions, and audience members gently pointed out things I might want to rethink. With the exception of one creepy off-the-wall comment about my "fine-boned features," the reaction was overwhelmingly positive.</p>
<p>Reliable sources told me that of 300 attendees, approximately 282 were men. I was the only woman to submit a talk. So this is the part where I encourage other women to do the same. I think women, on the whole (of course there are exceptions), are way more inclined than men to think they aren't good enough speakers, that they don't know a topic well enough to tell it to other people. Two truths: one, the speaking skills of the speakers I've seen have been all over the map; two, you'd be surprised how much you actually know about a topic, especially given the right audience. Go speak at a small event -- a local meetup, a Refresh, even a lunch-and-learn at your office. Get to know the people who do speak at events, and discover that they're people just like you. Go out on a limb and try something that's <em>really</em> outside your comfort zone, like improv, and learn about the clapping part that comes in the end. It's worth it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rebeccamurphey.com/2009/09/16/on-speaking-at-the-2009-jquery-conference/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
