<?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"
	>

<channel>
	<title>Pathfinder Development &#187; Brian Dillard</title>
	<atom:link href="http://www.pathf.com/blogs/author/brian-dillard/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pathf.com/blogs</link>
	<description>Running commentary about agile development, user experience design and Ajax.</description>
	<pubDate>Wed, 19 Nov 2008 15:24:09 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Icons are evil; so are menus - unless you do them right</title>
		<link>http://www.pathf.com/blogs/2008/11/icons-are-evil-so-are-menus-unless-you-do-them-right/</link>
		<comments>http://www.pathf.com/blogs/2008/11/icons-are-evil-so-are-menus-unless-you-do-them-right/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 22:37:35 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[Confluence]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[Flock]]></category>

		<category><![CDATA[User Experience]]></category>

		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1270</guid>
		<description><![CDATA[Menus and dropdowns seem like attractive design choices because they conserve screen real estate while providing users access to a potentially large number of commands. But if you resist the easy out of menus and dropdowns, you may find that your applications become far more usable.
Survey the software you use for yourself, both browser- and [...]]]></description>
			<content:encoded><![CDATA[<p>Menus and dropdowns seem like attractive design choices because they conserve screen real estate while providing users access to a potentially large number of commands. But if you resist the easy out of menus and dropdowns, you may find that your applications become far more usable.</p>
<p>Survey the software you use for yourself, both browser- and desktop-based. Think about which applications provide the most invisible, effortless interfaces. I doubt it will be the ones that hide commands in complex menus and dropdown systems.</p>
<p>For some negative examples, let's look at Firefox and its more social cousin, Flock. Each app offers an advanced bookmark management mechanism, but the usability of that mechanism suffers in each due to over-reliance on cryptic menus.</p>
<p><span id="more-1270"></span></p>
<p>Here's Firefox:</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/11/firefox.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/11/firefox.jpg" alt="Firefox" title="Firefox" width="300" height="185" /></a></p>
<p>Can you guess which bookmark management options are going to appear under each menu? Where, for example, would the command for adding a separator live? What about sorting your bookmarks? Can't figure it out? Welcome to the world of evil icons.</p>
<p>For comparison, here's Flock, the social browser derived from Firefox:</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/11/flock.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/11/flock.jpg" alt="Flock" title="Flock" width="300" height="160" /></a></p>
<p>Clearly, Flock provides friendlier menus; at least they've got text labels. With enough trial-and-error training, you'll probably be able to teach yourself which command lives under which menu.</p>
<p>Here's another example, this time from the webapp world: Confluence, the popular enterprise wiki package. Older versions of Confluence offered the by-now-familiar star icon. Click it, and a page would be added to your favorites. More recent versions, however, hide the "add favorite" option in one of several dropdown menus. Can you guess which?</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/11/confluence-hidden.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/11/confluence-hidden.jpg" alt="Confluence 1" title="Confluence 1" width="300" height="64" class="alignnone size-medium wp-image-1273" /></a></p>
<p>If you guessed the "Add" menu, for "add to favorites," you're wrong. It's under the "Tools" menu. Welcome to the world of evil menus.</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/11/confluence.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/11/confluence.jpg" alt="Confluence" title="Confluence" width="189" height="300" /></a></p>
<p>So where does that leave us? Must every single command available in an interface exist as an always-visible text link within the browser viewport? Of course not. But there are some best practices in choosing how to build our menus:</p>
<ul>
<li>Icons are great, but they should either be universally recognizable (such as a star or trash can) or paired with a text label.</li>
<li>Menu groupings should be intuitive. Use care in choosing the top-level labels and don't group disparate items under the same menu.</li>
<li>For frequently accessed functionality, consider leaving it as a dedicated clickable item on the page. There's nothing wrong with a mixture of icons and menus, the former for the most popular features and the latter for everything else.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/11/icons-are-evil-so-are-menus-unless-you-do-them-right/feed/</wfw:commentRss>
		</item>
		<item>
		<title>From JSP to Ruby on Rails: First thoughts on front-end coding conventions</title>
		<link>http://www.pathf.com/blogs/2008/11/from-jsp-to-ruby-on-rails-first-thoughts-on-front-end-coding-conventions/</link>
		<comments>http://www.pathf.com/blogs/2008/11/from-jsp-to-ruby-on-rails-first-thoughts-on-front-end-coding-conventions/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 21:00:01 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[HTML]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[JSP]]></category>

		<category><![CDATA[MVC]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1253</guid>
		<description><![CDATA[Now that I've got a few Ruby on Rails projects under my belt, I finally feel qualified to comment on Rails front-end coding conventions. As a UI specialist coming to Rails from the JSP world, I find a lot of room for improvement in the RoR approach to view-layer code. I love working on the [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I've got a few Ruby on Rails projects under my belt, I finally feel qualified to comment on Rails front-end coding conventions. As a UI specialist coming to Rails from the JSP world, I find a lot of room for improvement in the RoR approach to view-layer code. I love working on the non-view aspects of RoR projects, but I find I've got to do tons of cleanup at the ERB layer. Expect to see some open-source components from Pathfinder to help ease this pain. In the meantime, let me articulate my pain points:</p>
<h3>Code organization</h3>
<p>If I'm filling a front-end role on a Rails project, most of the files I need are in /app/views and /public. I dig that. Likewise, I appreciate the underscore naming conventions for partials. However, I wish /layouts weren't just another subdirectory of /app/views. Layouts are inherently different from standard view templates. A better hierarchy within /app/views would help drive this home. Likewise, I wish partials and full templates each had their own directory within a specific controller's view folder. That would help keep directories manageable on big projects. The /public directory, on the other hand, offers just the right amount of organization.</p>
<p><span id="more-1253"></span></p>
<h3>Markup and styles</h3>
<p>Scaffolds are awesome for rapid prototyping, but the markup and styles they spit out reflect a standard of front-end coding that's several years out of date. Plenty of plugins tackle this very problem, but I'm disappointed to find so little attention to view-layer code from the core version of such a respected application platform.</p>
<p>In an ideal world, a platform famed for its convention-over-configuration approach would ship with a decent reset.css and a solid baseline stylesheet with reusable utility styles that rely on class rather than id attributes to work their magic. I'm not talking about layout so much as simple problems that have long been solved in the web standards world: pure CSS pipe-delimited lists, table-free form layouts and the like.</p>
<p>So much Rails development is about tweaking the defaults just enough to achieve the results you need. That means lots of crappy auto-generated markup ends up in production. Rails can't be all things to all people, but it would be cool if it didn't pump out antiquated UI code by default.</p>
<h3>Macros and view-logic encapsulation</h3>
<p>Tab-based templating systems make it easy to separate view logic from application logic. Whether you're using JSTL or a custom tag library, JSP 2.0 offers a specific syntax for templating that's different from the syntax used for model and controller logic. Sure, JSP tags compile down to Java, but they look different from regular Java. And sure, you can use scriptlets in JSP, but you don't have to.</p>
<p>In Rails, however, ERB looks like plain old Ruby code. It's hard to tell at a glance whether the Ruby contained in a template is doing view stuff or jumping the shark to tackle controller and model stuff. This makes it very difficult for either humans or automated tools to do sniff tests on Rails code for separation of concerns at the view layer.</p>
<p>Helpers exacerbate the problem. In JSP, if you need to create a view-layer macro, you do it as a tag. In Rails, you do it as a helper. But those helpers live in the same place as other, unrelated helpers from the controller. The result is a mixture of view code and controller code within the same directories and even the same files.</p>
<p>If experience has taught me anything, it's that controller logic and even model logic like to leak into the view. Without strong conventions to prevent this, it's too easy to compromise your MVC architecture and hinder the maintainability of your application. JSP offers better encapsulation of the view layer - a clear advantage.</p>
<h3>JavaScript</h3>
<p>I've posted before about my experiences <a href="http://www.pathf.com/blogs/2008/06/jquery-rails-agile-plantcollections-database-project-now-live/">dropping jQuery into Rails</a> and making it work. I'm not a huge fan of the tight coupling between a specific JavaScript framework and the core server-side framework. Nor do I love the lack of built-in progressive enhancement on many of the Rails Ajax helpers. I get why it's attractive to people without dedicated front-end resources. But for anybody who wants to do a really sophisticated behavior layer, Rails Ajax helpers are more of a hindrance than a help. <a href="http://ennerchi.com/projects/jrails">jRails</a> and other projects offer a way to drop jQuery into a project and still access the Rails Ajax helpers, but I'd love to see a different approach to sophisticated Rails Ajax, one that doesn't create apps that break when JavaScript is unavailable.</p>
<h3>Conclusions</h3>
</p>
<p>Of course, I'm still a Rails noob and have probably missed all sorts of best practices that could help ameliorate the bad and accentuate the good. Let me know in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/11/from-jsp-to-ruby-on-rails-first-thoughts-on-front-end-coding-conventions/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The courage to redesign</title>
		<link>http://www.pathf.com/blogs/2008/11/the-courage-to-redesign/</link>
		<comments>http://www.pathf.com/blogs/2008/11/the-courage-to-redesign/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 22:12:54 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[Amazon]]></category>

		<category><![CDATA[Facebook]]></category>

		<category><![CDATA[FriendFeed]]></category>

		<category><![CDATA[Google]]></category>

		<category><![CDATA[iGoogle]]></category>

		<category><![CDATA[resesign]]></category>

		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1233</guid>
		<description><![CDATA[People are still griping about the recent redesigns of Facebook and iGoogle, but I think we should cheer on any company brave enough to disregard user feedback and embrace change.
Lots of big-name, highly successful sites eventually reach a state of paralysis in which they're too scared of alienating their customers to examine their interaction design [...]]]></description>
			<content:encoded><![CDATA[<p>People are still griping about the recent redesigns of <a href="http://www.facebook.com/group.php?gid=2298898409">Facebook</a> and <a href="http://www.macworld.co.uk/business/news/index.cfm?newsid=23235&pagtype=allchandate">iGoogle</a>, but I think we should cheer on any company brave enough to disregard user feedback and embrace change.</p>
<p>Lots of big-name, highly successful sites eventually reach a state of paralysis in which they're too scared of alienating their customers to examine their interaction design and information architecture from a fresh perspective.</p>
<h3>The cautionary tale of Amazon.com</h3>
<p>Look at Amazon: The online retailer <a href="http://www.pathf.com/blogs/2007/10/misuse-case-ama/">adopted DHTML navigation</a> just last year - at least 5 years after most other big sites - because its tab interface had grown so comically large. Nevertheless, huge chunks of the Amazon user experience are still massively broken:</p>
<ul>
<li>Once you've started down the checkout process, the site tries to keep you from getting back to your shopping cart to add or remove additional items. If you use your back button to do so, you've got to start the checkout process all over again.</li>
<li>Wish lists offer perhaps the most confusing, error-prone user interface I've ever had the displeasure to experience.</li>
<li>Link targets on a wide variety of UI controls are tiny and persnickety enough to elicit involuntary profanity.</li>
</ul>
<p><span id="more-1233"></span></p>
<p>Why does Amazon let its design blunders live on in perpetuity? It's simple: Redesigns confuse users, and confused users don't spend money. Your current customers have invested so much effort in learning to work around your site's shortcomings that a new interface stops them in their tracks. Even the most humane and usable UI refresh takes acclimation - and that may cost your site conversions and revenue in the meantime.</p>
<h3>The agony and the ecstasy of the redesign</h3>
<p>I learned this lesson the hard way during my days at <a href="http://www.internetretailer.com/internet/marketing-conference/40065-why-pg-shut-down-reflectcom.html">Reflect.com</a> and <a href="http://www.orbitz.com">Orbitz</a>, where A/B testing constantly shocked us by revealing that change, any change, causes key metrics to dip, at least temporarily. Redesign an unusable feature and test the old and new versions with your current customer base on the live site. Chances are, the old version will win in the short term. That's why it takes guts to even consider a top-to-tails redesign. If small changes can have a negative impact, big changes could be deadly.</p>
<p>To me, however, it seems as if the bigger danger lies in allowing your site's information architecture to become ossified. Eventually, new UI paradigms will offer your younger competitors an avenue for feature differentiation. I was at Orbitz when <a href="http://www.kayak.com">Kayak.com</a> launched, and I was sick with envy that a site could push the user experience of online travel into such new and compelling directions. I knew a company as large as mine could never rock the boat by switching to such an off-the-wall UI.</p>
<p>Sure, budget aggregator Kayak wasn't a direct competitor to an online travel agent like Orbitz. But if somebody had launched a full-service OTA with an interface as fresh as Kayak's, then <a href="http://www.expedia.com/">Expedia</a>, Orbitz and <a href="http://www.travelocity.com/">Travelocity</a> would have been forced to play catch-up. After all, it was UI differentiation that had originally allowed Orbitz to woo customers from other, more established competitors: Its matrix-based results pages provided a compelling new way to find cheap seats. Eventually, though, other sites copied that feature. Now, all the big OTAs match each other feature for feature.</p>
<h3>Beta sites: Hope for the future</h3>
<p>That's what's so impressive about today's crop of Web 2.0 upstarts. A young service such as FriendFeed can offer <a href="http://mashable.com/2008/09/18/friendfeed-beta-released/">an entirely separate, opt-in beta site</a> and tinker away at it without annoying current users. Then, once the geekier end of the user base has helped work out the kinks, the service can flip the switch and roll out its new features to everyone. That's exactly what Facebook did with its new interface, but at far greater risk than FriendFeed. Facebook may be obscenely overvalued, but it does function as a business. A redesign is far less scary for the relatively unmonetized FriendFeed.</p>
<p>Regardless of whether you're a social networking giant or a microblogging upstart, this kind of usability and design lab has become de rigueur. By acclimating your users to frequent change early on, you can help ensure that future refreshes don't send them packing. Amazon may be in a design coma, but your site shouldn't have to be. Have the courage to redesign early and often.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/11/the-courage-to-redesign/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web 2.0 context menus vs. Web 1.0 link lists: Style over usability?</title>
		<link>http://www.pathf.com/blogs/2008/10/web-20-context-menus-vs-web-10-link-lists-style-over-usability/</link>
		<comments>http://www.pathf.com/blogs/2008/10/web-20-context-menus-vs-web-10-link-lists-style-over-usability/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 18:59:37 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[Facebook]]></category>

		<category><![CDATA[Flickr]]></category>

		<category><![CDATA[FriendFeed]]></category>

		<category><![CDATA[Twitter]]></category>

		<category><![CDATA[Usability]]></category>

		<category><![CDATA[user experience design]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1206</guid>
		<description><![CDATA[As Ajax spreads new UI conventions to the masses, it's important to apply a critical eye to the usability of those conventions. Several big-name sites have launched extensive redesigns in the last few months, from Twitter and FriendFeed to Flickr and Facebook. Certain trends are solidifying, especially the use of context menus that are hidden [...]]]></description>
			<content:encoded><![CDATA[<p>As Ajax spreads new UI conventions to the masses, it's important to apply a critical eye to the usability of those conventions. Several big-name sites have launched extensive redesigns in the last few months, from <a href="http://www.twitter.com">Twitter</a> and <a href="http://www.friendfeed.com">FriendFeed</a> to <a href="http://www.flickr.com">Flickr</a> and <a href="http://www.facebook.com">Facebook</a>. Certain trends are solidifying, especially the use of context menus that are hidden until a user mouses over an item, then displayed as a series of icons, text or both.</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/flickr1.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/flickr1.jpg" alt="Flickr" title="Flickr" width="400" height="159" /></a></p>
<p>First up we have <string>Flickr</string>, whose homepage redesign emphasizes the social networking aspects of the service. A Recent Activity feed, modeled on Facebook's iconic News Feed, showcases favorites and comments from your contacts. The default view for each item displays its age. When the user hovers, though, the same real estate becomes home to two icons. One allows you to add your own comment; the other "mutes" activity related to that photo and removes it from your feed. Neither option is represented by an industry-standard icon, and no tooltip is provided. Even the status bar shows only an inscrutable URL: a hash sign.</p>
<p><span id="more-1206"></span></p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/twitter.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/twitter.jpg" alt="Twitter" title="Twitter" width="400" height="114" /></a></p>
<p>Next up we have <strong>Twitter</strong>, whose new homepage provides a similar user experience to that of Flickr, with two important differences: Rather than re-use existing real estate for its clickable context commands, Twitter re-purposes existing whitespace. And instead of cute, mysterious pictograms, Twitter uses industry-standard icons: a trash can and a star. For users schooled in the conventions of Web 2.0, it's obvious that the two icons, when clicked, will either assign "favorite" status to the item or delete the item altogether. For users without such a background, however, there are still no tooltips.</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/facebook-feed.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/facebook-feed.jpg" alt="Facebook" title="Facebook" width="400" height="188" /></a></p>
<p>Finally we have <strong>Facebook</strong>, whose own News Feed now offers mouseover context commands. Unlike Twitter and Flickr, however, the social networking giant rolls all context options up into a single Options menu which is represented by text AND an icon. Users who click on the word or image see links such as "More about Brian, "Less about Brian, "More Status Stories" or "Fewer Status Stories."</p>
<p>Based on all of these examples, I'd say only Twitter hits the Web 2.0 sweet spot where simple, clear icons communicate everything you need to know about a feature. Even then, it would be nice if tooltips provided even further context. Facebook's approach goes further than Twitter's in guaranteeing that users always know what's going to happen when they click. But it's too fussy. Hover to see that there's a menu, click on the menu header, then finally see the available commands and click on one of them. When there are many options, that makes sense. But when there are two (a paired set of more/less links) it seems like overkill.</p>
<p>Flickr provides the least usable variation on this design pattern. The absence of both recognizable icons and tooltips turns context commands into a guessing game.</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/friendfeed.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/friendfeed.jpg" alt="FriendFeed" title="FriendFeed" width="350" height="143" /></a></p>
<p>In terms of usability, however, there's another design pattern that trumps all of these options for clarity and usability: <strong>FriendFeed</strong>, which takes a very different approach to context commands. Items in FriendFeed now offer a very Web 1.0 grocery list of actions, all spelled out plainly in text and all visible regardless of hover state. Newbies and experts alike have instant access to popular commands such as "Comment," "Like" and "Hide." There are no wordless icons and no hover states. The only menu option that involves hide/show is the "More" submenu at the end of the list of options. Here, a down-arrow clearly indicates that this is  dropdown. As expected, it contains additional, less popular commands for linking or resharing entries.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/10/web-20-context-menus-vs-web-10-link-lists-style-over-usability/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Where minimalism fails: The problem with Apple&#8217;s less-is-more approach</title>
		<link>http://www.pathf.com/blogs/2008/10/where-minimalism-fails-the-problem-with-apples-less-is-more-approach/</link>
		<comments>http://www.pathf.com/blogs/2008/10/where-minimalism-fails-the-problem-with-apples-less-is-more-approach/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 18:26:57 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[apple]]></category>

		<category><![CDATA[hardware]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPod]]></category>

		<category><![CDATA[laptop]]></category>

		<category><![CDATA[minimalism]]></category>

		<category><![CDATA[mouse]]></category>

		<category><![CDATA[notebook]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1199</guid>
		<description><![CDATA[
So I'm watching the big Apple notebook event and getting totally excited about the impressive new graphics capabilities. Finally I'll be able to get decent visuals on World of Warcraft on a Mac laptop. Then we get to the part about the new trackpads and my excitement wanes. Once again, Apple is opting for ultra-minimalist [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/macbook.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/macbook.jpg" alt="MacBook" title="MacBook" width="250" height="182" class="right" /></a></p>
<p>So I'm watching the big <a href="http://www.macworld.com/article/136009/2008/10/liveupdate.html">Apple notebook event</a> and getting totally excited about the impressive new graphics capabilities. Finally I'll be able to get decent visuals on <a href="http://www.worldofwarcraft.com">World of Warcraft</a> on a Mac laptop. Then we get to the part about the new trackpads and my excitement wanes. Once again, Apple is opting for ultra-minimalist hardware and then using software to compensate (poorly) for that design choice.</p>
<p>Here's Steve Jobs:</p>
<blockquote><p>We've got a new trackpad for notebooks. It's a gorgeous, large, multitouch glass trackpad for notebooks. It's 39 percent larger tracking area than before, it's multi-touch for gestures, it's glass for silky-smooth travel. And we've optimized the coefficient of friction on the glass, so it's really beautiful. And the entire trackpad is the button. It gives you more area on the trackpad and keeps you from hunting for that button. You can get multi-button support from software. And we've added some new four-finger gestures that are really nice.</p></blockquote>
<p>Four-finger gestures may be really nice, but I'd opt for two hardware buttons any day. Whether you're playing video games or simply using productivity and development apps, you should be able to summon context menus without having to resort to arcane gestures. Apple's obsession with scaling hardware down to its essence may result in beautiful products, but usability almost always suffers. Need some more examples?</p>
<p><span id="more-1199"></span></p>
<ul>
<li>
<p><strong>iPod volume controls</strong>: Ever since the original model came out in 2001, users have had to cope with the iPod's irritating lack of a physical volume control. If your music library's like mine, the volume levels change drastically between tracks - even when you tell iTunes to level things. It's pretty annoying when the track changes from a quiet one to a painfully loud one while you're busy navigating some random menu. You've either got to rip your earphones out of your ears or painstakingly navigate back to "Now Playing" so you can once again adjust the volume. Then there's the single button that toggles between volume control, fast-forward, star ratings and media info. There's nothing more annoying than trying to fast-forward through a track using the slider control only to accidentally crank the volume all the way up and deafen yourself.</p>
</li>
<li>
<p><strong>Mighty Mouse</strong>: Worst mouse I've ever purchased - and also the most overpriced. The promos claimed that the single giant "button" would create a right-click or a left-click depending on how I pressed it. In reality, no matter how carefully I tried to attune my muscle memory, half of my right-clicks ended up as left-clicks instead. In the end, I disabled right- and left- click capabilities and went back to using the stupid option key. Then I really wised up, threw the Mighty Mouse in the garbage and bought an extremely ugly but extremely functional Microsoft notebook mouse.</p>
</li>
<li>
<p><strong>iPhone phone interface</strong>: The iPhone works great as an Internet device, but it's a lousy phone - and not just because of AT&T's immature 3G network. No, the real problem with the iPhone-as-phone is that its menu system is such a minimalist trainwreck. I can summon my "Favorites" list with a double-tap of the phone's single hardware button. But to get to any of the other sub-menus within the Phone application, I must launch the app, get my bearings - because the app retains whatever sub-menu I was using last time around - and then click an icon to get to Recents, or Voicemail, or Keypad. Actions that required a single click on a dedicated hardware button on my crappy old Motorola phone take three clicks and a lot of decision-making on the iPhone. Then there's the menu system once you're actually in the middle of a phone call - you know, the one that requires you to choose "Keypad" from a list of options before you can even respond to a standard touch-tone interface.</p>
</li>
</ul>
<p>My point - and I do have one - is that minimalism should be a means to an end; the end itself should be usability. Simplifying a device's hardware does no good if it means forcing the user to think about how the software interface works. I'll almost certainly purchase one of these notebooks - possibly several. But as with so many Apple products, I'll curse softly nearly every time I use it. Apple's products are the best thing going in the notebook market, but they could still be so much better.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/10/where-minimalism-fails-the-problem-with-apples-less-is-more-approach/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Blackbird takes the pain out of JavaScript logging</title>
		<link>http://www.pathf.com/blogs/2008/10/blackbird-takes-the-pain-out-of-javascript-logging/</link>
		<comments>http://www.pathf.com/blogs/2008/10/blackbird-takes-the-pain-out-of-javascript-logging/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 16:23:06 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Javascript Libraries]]></category>

		<category><![CDATA[logging]]></category>

		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1190</guid>
		<description><![CDATA[
I'm excited to announce the arrival of Blackbird, an open-source JavaScript logging and profiling utility written by G. Scott Olson, a former colleague from my days at Orbitz Worldwide. 
A previous iteration of Blackbird provided no-nonsense, cross-browser logging on a variety of projects within Orbitz. Since that iteration, known as jsLogger, Scott has re-written the [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/blackbird.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/blackbird.jpg" alt="Blackbird screenshot" title="Blackbird" width="300" height="162" class="right" /></a></p>
<p>I'm excited to announce the arrival of <a class="b" href="http://www.gscottolson.com/blackbirdjs/">Blackbird</a>, an open-source JavaScript logging and profiling utility written by <a href="http://www.gscottolson.com/">G. Scott Olson</a>, a former colleague from my days at Orbitz Worldwide. </p>
<p>A previous iteration of Blackbird provided no-nonsense, cross-browser logging on a variety of projects within Orbitz. Since that iteration, known as jsLogger, Scott has re-written the code from the ground up; provided tons of useful new features, including custom namespacing and a spiffy new graphical interface; and released it under an MIT license.</p>
<p>Why, you might ask, in the age of Firebug, would anybody need a JavaScript logging utility? Simple:</p>
<ul>
<li>Blackbird works in a wide variety of modern browsers. Write one style of log statement for every browser.</li>
<li>Blackbird can be deployed to production. By stubbing out its public API with empty functions, you can leave your log statements in production code. (I'm not endorsing this approach to code maintenance, just pointing out that Blackbird makes it easy.)</li>
<li>Blackbird does one thing and does it well. It's not a debugger, it's just a logger and profiler.</li>
<li>Blackbird doesn't interfere with Firebug's <code>console.log</code> utility, but it does improve on its interface. You can hide or show the Blackbird modal with a single, customizable keystroke. You can also choose from four levels of logging (debug, info, warning and error) and atomically toggle their visibility within the console.</li>
</ul>
<p>The <a href="http://code.google.com/p/blackbirdjs/">Blackbird project now lives at Google Code</a>, where you can download it and learn about how to contribute.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/10/blackbird-takes-the-pain-out-of-javascript-logging/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HTML5, Ajax history management, and The Ajax Experience 2008 Boston</title>
		<link>http://www.pathf.com/blogs/2008/10/html5-ajax-history-management-and-the-ajax-experience-2008-boston/</link>
		<comments>http://www.pathf.com/blogs/2008/10/html5-ajax-history-management-and-the-ajax-experience-2008-boston/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 19:38:24 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Ajax Experience]]></category>

		<category><![CDATA[Ajax history management]]></category>

		<category><![CDATA[events]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Really Simple History]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1186</guid>
		<description><![CDATA[
The Ajax Experience last week in Boston yielded lots of exciting developments on the Ajax history management front:


My talk itself drew a crowd of 110 people or so despite its 8.10 a.m. start time. I received good questions from the audience and didn't notice too many people heading for the doors when they realized how [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/10/brain-dillard.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/brain-dillard.jpg" alt="Brian, a.k.a. Brain, Dillard" title="Brian, a.k.a. Brain, Dillard" width="111" height="150" class="right" /></a></p>
<p><a href="http://www.pathf.com/blogs/2008/09/the-ajax-experience-2008-hope-to-see-you-in-beantown/">The Ajax Experience</a> last week in Boston yielded lots of exciting developments on the Ajax history management front:</p>
<ul>
<li>
<p><a href="http://ajaxexperience.techtarget.com/east/html/client.html#BDillardBrowser">My talk itself</a> drew a crowd of 110 people or so despite its 8.10 a.m. start time. I received good questions from the audience and didn't notice too many people heading for the doors when they realized how deep into the nitty-gritty technical details I was getting. Instead of using Keynote or Powerpoint for my slides, I built a basic DHTML application. That way, one artifact could serve as both my content and a demo of <a href="http://code.google.com/p/reallysimplehistory/">Really Simply History</a>, the Ajax history and back-button library I maintain. <a href="http://labs.pathf.com/ajax/tae2008boston/">You can view the application - and the slides - at Pathfinder Labs.</a></p>
</li>
<li>
<p>I did not meet<a href="http://www.pathf.com/blogs/2008/09/a-mea-culpa-and-a-launch-date-for-really-simple-history-08/"> my goal of releasing an alpha of Really Simple History 0.8 in conjunction with the conference</a>. But I did accomplish a ton of work on the library during the build-up to my talk. I'm now hard at work finalizing the alpha and preparing updates to the project's Google Code-hosted homepage.</p>
</li>
<li>
<p>The most exciting Ajax history development was the face time I enjoyed with <a href="http://nathanhammond.com/">Nathan Hammond</a>, creator of <a href="http://trac.nathanhammond.com/jssm">JavaScript State Manager (JSSM)</a>, and <a href="http://www.codinginparadise.org/">Brad Neuberg</a>, original creator of Really Simple History. After my talk we enjoyed an impromptu Ajax back-button summit and hammered out a shared agenda for the future of both my library and the topic in general. I'm pleased to announce that Nathan will be coming on as an RSH co-maintainer with the goal of merging RSH 0.8 and JSSM into a single, stable 1.0 library. I'm also excited that Brad, Nathan and I - plus other authors of Ajax history libraries who wish to participate - will be issuing a position paper on the current history implementation in the HTML 5 spec. Ajax history experts, please <a href="http://www.pathf.com/contact-us/">contact me via Pathfinder</a> if you want to weigh in.</p>
</li>
<li>
<p>As for <a href="http://ajaxexperience.techtarget.com/html/index.html">the conference itself</a>, it was my first time attending The Ajax Experience and I really enjoyed it. The topics were many, varied and well-presented. My favorites included <a href="http://www.crockford.com/">Douglas Crockford</a>'s discussion of JavaScript's good parts, which could have been a simple book promo but turned out to be far more; the panel discussion between the leaders of YUI, Dojo, jQuery and Prototype moderated by the inimitable <a href="http://www.quirksmode.org/book/">PPK</a>; and my colleage Dietrich's <a href="http://www.pathf.com/blogs/2008/10/tae-boston-2008-the-unsexy-presentations/">un-sexy</a> but vital look at <a href="http://ajaxexperience.techtarget.com/east/html/server.html#DKappeGWT">how to resurface J2EE apps for Ajax using the Google Web Toolkit</a>.</p>
<p>I have to say, the crowd here felt like my tribe. The guys running around with the word "JavaScript" shaved into their hair put a smile on my face. Ajax developers are often third-class citizens at other conferences. They're either jammed together with designers and user experience folks, or thrown into the midst of Java and Ruby developers. That wasn't the case here, and I dug it highly.</p>
<p>My least favorite aspect of the conference had nothing to do with the crowd or the content; it was the depressing lack of vegan food. One meal was 90% vegan, but most were 0%. Given the conference center's distance from civilization, it would have been nice if attendees' diverse dietary needs had been taken into consideration. On the plus side, I think I lost five pounds.</p>
</li>
</ul>
<p>Many thanks to the folks from Tech Target for the awesome speaker support. My name, so amusingly misspelled on the monitor outside the ballroom where I spoke, had been corrected by the time I took the podium.</p>
<p>And special thanks to Ben, Dion and everyone at Ajaxian for throwing such a jam-packed event, letting me speak at it, and doing so much for the Ajax community over the years.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/10/html5-ajax-history-management-and-the-ajax-experience-2008-boston/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Ajax Experience 2008: Hope to see you in Beantown</title>
		<link>http://www.pathf.com/blogs/2008/09/the-ajax-experience-2008-hope-to-see-you-in-beantown/</link>
		<comments>http://www.pathf.com/blogs/2008/09/the-ajax-experience-2008-hope-to-see-you-in-beantown/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 19:24:40 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Ajax Experience]]></category>

		<category><![CDATA[events]]></category>

		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1176</guid>
		<description><![CDATA[
I'm posting today from Boston, where my colleague Dietrich Kappe and I are proud to be presenting at The Ajax Experience 2008.
At 5.10 p.m. tomorrow (Tuesday 30 September), Dietrich will present "Saving Your Investment: Transforming J2EE Applications into Web 2.0 Using GWT." This 90-minute session will introduce noobs to the Google Web Toolkit; school experienced [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/09/theajaxexperience.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/09/theajaxexperience.jpg" alt="The Ajax Experience 2008 Boston" title="The Ajax Experience 2008 Boston" width="300" height="216" class="right" /></a></p>
<p>I'm posting today from Boston, where my colleague Dietrich Kappe and I are proud to be presenting at <a href="http://ajaxexperience.techtarget.com/east/">The Ajax Experience 2008</a>.</p>
<p>At 5.10 p.m. tomorrow (Tuesday 30 September), Dietrich will present <a href="http://ajaxexperience.techtarget.com/east/html/server.html#DKappeGWT">"Saving Your Investment: Transforming J2EE Applications into Web 2.0 Using GWT."</a> This 90-minute session will introduce noobs to the Google Web Toolkit; school experienced GWT developers in the security implications of leaky client-side business logic; and delight business folks and bean-counters alike with the money-savings possibilities of retrofitting a legacy webapp instead of building a new one from scratch.</p>
<p>At 8.10 a.m. the following day (Wednesday 1 October), I will present <a href="http://ajaxexperience.techtarget.com/east/html/client.html#BDillardBrowser">"Making Friends with the Browser: Ajax, Back Buttons and Bookmarks."</a> In it, I'll look at the state of Ajax history management, from new libraries such as the <a href="http://nathanhammond.com/jssm">JavaScript State Manager</a> and <a href="http://code.google.com/p/dshistory/">dsHistory</a> to my own project, Really Simple History. I'll discuss the problems and tradeoffs inherent in any browser history manager. I'll also examine the impact of new browsers such as Google Chrome and Microsoft Internet Explorer 8 on this small, rapidly evolving corner of the Ajax world.</p>
<p>We look forward to seeing some of you there and reporting back about the rest of the conference.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/09/the-ajax-experience-2008-hope-to-see-you-in-beantown/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What does your CSS Swiss Army knife look like?</title>
		<link>http://www.pathf.com/blogs/2008/09/what-does-your-css-swiss-army-knife-look-like/</link>
		<comments>http://www.pathf.com/blogs/2008/09/what-does-your-css-swiss-army-knife-look-like/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 19:15:50 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Progressive Enhancement]]></category>

		<category><![CDATA[Web Standards]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1158</guid>
		<description><![CDATA[
CSS 2.1 is more like a Swiss Army knife than a fully stocked toolbox. We can accomplish a lot, but we have to get creative with the standard attachments. Floats, relative positioning, the box model - each tool must performs double or triple duty because they're the only ones we've got.
When we do discover a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pathf.com/blogs/wp-content/uploads/2008/09/swissarmy.jpg"><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/09/swissarmy.jpg" alt="Swiss Army knife" title="Swiss Army knife" width="90" height="90" class="right" /></a></p>
<p>CSS 2.1 is more like a Swiss Army knife than a fully stocked toolbox. We can accomplish a lot, but we have to get creative with the standard attachments. Floats, relative positioning, the box model - each tool must performs double or triple duty because they're the only ones we've got.</p>
<p>When we do discover a clever way to accomplish a common task using these limited tools, we're likely to employ that technique over and over. I'm not talking about <a href="http://www.blueprintcss.org/">CSS frameworks</a> here; those help out more at the macro level. I'm talking about repeatable techniques that can be applied at the micro level. When done right, these simple techniques can feel like entirely new Swiss Army attachments rather than intelligent application of existing blades.</p>
<p>Whenever I start out on a new client project, I start off with the following plug-and-play components:</p>
<p><span id="more-1158"></span></p>
<ol>
<li>
<p><strong>A reset stylesheet:</strong> Sometimes I plug <a href="http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/">Eric Meyer's latest reset</a> in wholesale, while sometimes I pick and choose which parts make sense for my project. Regardless, it's absolutely essential to erase default styling and provide a common, cross-browser foundation on which to build.</p>
</li>
<li>
<p><strong>Semantic, cross-browser float-clearing:</strong> I <a href="http://www.pathf.com/blogs/2007/09/developers-note-2/">posted about this topic a year ago</a>, generating plenty of debate. Whether you're using my Orbitz-inspired grocery-list-of-selectors approach or a generic <code>clearfix</code> class, you've got to tackle this problem if you employ float-based layout - until, that is, some future CSS spec implements a <code>float-clear</code> property.</p>
</li>
<li>
<p><strong>Standard-issue pipe-delimited lists:</strong> If you're representing lists as paragraphs full of text punctuated by hard-coded pipe characters (|), you're probably not paying much attention to web standards. A set of CSS rules like the following makes it dead simple accomplish the same effect semantically with borders. True, Internet Explorer 6/7's lack of support for the <code>first-child</code> pseudo-class means you'll have to create an actual class called <code>first-child</code> and apply it to your initial list element. Still, once you adjust border colors and spacing to fit your site design, this solution works anywhere. Variations can even allow for pipe-delimited definition lists.</p>
<pre>
/*
	standard pipe-delimited list: add a class
	of &quot;first-child&quot; to the first element
	for IE either via script or in the markup
*/

/*
	- the 0 margin and padding are unnecessary if
	  you&#x27;re using a standard reset stylesheet
	- you'll need to clear floats inside of ul.piped
	  using whatever your preferred method is
*/
ul.piped {
	margin: 0;
	padding: 0;
}
ul.piped li {
	float: left;
	margin-left: 8px;
	padding-left: 8px;
	border-left: 1px solid #000;
	list-style: none;
}
ul.piped li:first-child,
ul.piped li.first-child{
	margin-left: 0;
	padding-left: 0;
	border-left: 0;
}
</pre>
</li>
<li>
<p><strong>Simple hide/show utility classes:</strong> Unless you're using an effects library to create visual transitions, it's easier to toggle classes on hide/show elements than to manipulate their style properties directly. The only problem is differentiating between block and inline elements when you're ready to show them again. That's where the <code>block</code>, <code>inline</code>, <code>noneBlock</code> and <code>noneInline</code> classes come in. Your JavaScript code just needs to know that elements with a class of <code>block</code> get toggled to <code>noneBlock</code> and vice-versa; same for elements with a class of <code>inline</code> and <code>noneInline</code>.</p>
<pre>
/* classes to hide and show elements programmatically*/

.inline {
	display: inline;
}
.block {
	display: block;
}
.noneInline,
.noneBlock {
	display: none;
}
</pre>
</li>
<li>
<p><strong>A style-as-link class for JavaScript actions:</strong> It's easier - not to mention more semantic - to trigger JavaScript code from click events on divs, spans or other non-anchor elements. That way, you don't have to deal with a dummy <code>href</code> value or cancel out the link's default action. Besides, the <code>&lt;a href=&quot;&quot;&gt;&lt;/a&gt;</code> tag is for taking you to new pages, not performing an action within the existing page.</p>
<p>Some JavaScript coders ignore these advantages because they want the built-in styling shortcut of the <code>a</code> tag: cursors and hover states. As the code below demonstrates, however, it's dead simple to achieve the same visual effects with some simple CSS. Modern browsers can apply the <code>hover</code> pseudo-class to most any element. Ditto custom cursors.</p>
<pre>
a,
.styleAsLink{
	color: #08c;
	text-decoration: none;
}
a:hover,
.styleAsLink:hover{
	color: #444;
	text-decoration: underline;
	cursor: pointer;
}
</pre>
<p>Once you've created a <code>styleAsLink</code> class, you can replace this type of code:</p>
<pre>
&lt;a href=&quot;#&quot;
onclick=&quot;alert(&#x27;Isn&#x27;t it annoying to have to return
false every time?&#x27;); return false;&quot;&gt;
	this is an actual link
&lt;/a&gt;
</pre>
<p>... with this:</p>
<pre>
&lt;div class=&quot;styleAsLink&quot;
onclick=&quot;alert(&#x27;In the real world the click event
should be applied unobtrusively!&#x27;);&quot;&gt;
	this is a pseudo-link
&lt;/div&gt;
</pre>
<p>One caveat: This technique is useful for links that serve no other function than to trigger JavaScript code. Don't employ it in the case of a progressively enhanced link that triggers a script when JavaScript is available but takes you to a new page when it's not. A simple rule of thumb: If the link exists in your actual markup, it should remain a link. If it's inserted into the DOM wholesale by JavaScipt, it should be a pseudo-link.</p>
</li>
</ol>
<p>Enough about my own personal Swiss Army attachments. How do you get all <a href="http://en.wikipedia.org/wiki/MacGyver">MacGyver</a> with your CSS? Let us know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/09/what-does-your-css-swiss-army-knife-look-like/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A mea culpa, and a launch date, for Really Simple History 0.8</title>
		<link>http://www.pathf.com/blogs/2008/09/a-mea-culpa-and-a-launch-date-for-really-simple-history-08/</link>
		<comments>http://www.pathf.com/blogs/2008/09/a-mea-culpa-and-a-launch-date-for-really-simple-history-08/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 19:47:41 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Really Simple History]]></category>

		<category><![CDATA[The Ajax Experience]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1149</guid>
		<description><![CDATA[Time to come clean: I've been a terrible project lead on Really Simple History since version 0.6 launched last fall. The problem has been twofold:

lack of documentation
lack of time

The essential functionality of RSH works well in most supported browsers, but there are several special cases that have to be coded around in your actual application. [...]]]></description>
			<content:encoded><![CDATA[<p>Time to come clean: I've been a <strong>terrible</strong> project lead on Really Simple History since version 0.6 launched last fall. The problem has been twofold:</p>
<ol>
<li>lack of documentation</li>
<li>lack of time</li>
</ol>
<p>The essential functionality of RSH works well in most supported browsers, but there are several special cases that have to be coded around in your actual application. Even basic usage, however, is documented mostly through example, not through tutorial-style, narrative prose. This has resulted in lots of noise in the issue tracker from folks seeking guidance on how to use the library. For all the folks whose questions and bug reports have gone unanswered, I offer a sincere and heartfelt apology. And to the more experienced users who stepped up to answer questions and help out, I offer heartfelt thanks.</p>
<p>The launch of Safari 3 caused some serious problems because code created to work around Safari 2's deficiencies caused things to break in Safari 3. I should have accepted suggested patches from some gallant RSH users and pushed out a new version months ago. But to be honest, I was so swamped with paid client work for Pathfinder that I couldn't find the time. I've learned my lesson about brittle, browser-specific workarounds. The next version of the library will fail far more gracefully.</p>
<p>Speaking of the next release: RSH 0.8 is nearing completion. I expect to publish an alpha version to coincide with <a href="http://ajaxexperience.techtarget.com/east/html/client.html#BDillardBrowser">my presentation October 1 at The Ajax Experience</a>. My talk covers lots of interesting developments in Ajax history management, and I figured I should, you know, deliver the goods to my users before getting up on that stage.</p>
<p><span id="more-1149"></span></p>
<p>I'll post soon with some information about the new technical direction RSH has taken, but here's a taste of what's to come. RSH 0.8 will offer the following:</p>
<ul>
<li>a smaller footprint</li>
<li>a new API</li>
<li>easier configurability</li>
<li>less complexity for mainstream use cases</li>
<li>explicit support for IE8, Safari 3, Firefox 3, Flock and Chrome</li>
<li>more modularity and pluggability thanks to functional programming patterns espoused by Douglas Crockford</li>
<li>easier integration with popular Ajax toolkits</li>
<li>bug fixes</li>
</ul>
<p>My vision for 1.0 centers around a full test suite, configurable downloads, expansive documentation and better mobilization of the RSH community. By the time we get to 1.0, I want to make sure there's no longer a single bottleneck for continuing development. I look forward to getting on with it starting at The Ajax Experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/09/a-mea-culpa-and-a-launch-date-for-really-simple-history-08/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting things done with Flock and Meebo</title>
		<link>http://www.pathf.com/blogs/2008/09/getting-things-done-with-flock-and-meebo/</link>
		<comments>http://www.pathf.com/blogs/2008/09/getting-things-done-with-flock-and-meebo/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 20:01:02 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[Adium]]></category>

		<category><![CDATA[Facebook]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[Flock]]></category>

		<category><![CDATA[getting things done]]></category>

		<category><![CDATA[GTD]]></category>

		<category><![CDATA[Meebo]]></category>

		<category><![CDATA[NetNewsWire]]></category>

		<category><![CDATA[productivity]]></category>

		<category><![CDATA[work life balance]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1138</guid>
		<description><![CDATA[
During a recent GTD weekly review, I suddenly realized how many distractions had worked their way into my daily office routine: personal email, personal instant messaging, entertainment feeds, Facebook. I suspect such time-wasters pose a bigger danger to web developers than to other professionals, if only because the programs they run in are so central [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/09/flock-and-meebo.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/09/flock-and-meebo.jpg" alt="Screenshot of Flock and Meebo" title="Flock and Meebo" width="200" height="194" class="right" /></a></p>
<p>During a recent <a href="http://en.wikipedia.org/wiki/Getting_Things_Done">GTD</a> weekly review, I suddenly realized how many distractions had worked their way into my daily office routine: personal email, personal instant messaging, entertainment feeds, Facebook. I suspect such time-wasters pose a bigger danger to web developers than to other professionals, if only because the programs they run in are so central to our work. I run <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> for web development, <a href="http://www.adiumx.com/">Adium</a> for instant messaging, and <a href="http://www.newsgator.com/INDIVIDUALS/NETNEWSWIRE/">NetNewsWire</a> for industry news all day out of necessity. If I allow my personal distractions to jump out at me from those programs, my productivity plummets.</p>
<p>This weekend, I worked hard to de-tangle my professional and personal lives. My tools? <a href="http://flock.com/">Flock</a>, the Mozilla-based "social browser," and <a href="http://www.meebo.com/">Meebo</a>, the browser-based IM aggregation service. My goal was to separate all personal bookmarks and RSS feeds from NetNewsWire and Firefox into Flock, then move all my personal IM accounts from Adium to Meebo. The end result was a self-imposed firewall between productive time and fun time. (Thanks to <a href="http://lifehacker.com/">many a Lifehacker article</a> for the basic idea, if not the implementation.)</p>
<p><span id="more-1138"></span></p>
<h3>Getting started with Flock</h3>
<p><a href="http://en.wikipedia.org/wiki/Flock_(web_browser)">Flock</a> represents a noble attempt to shoehorn social networks and other web utilities into the chassis of a Mozilla-based browser. Sure, many of its features could be achieved in a standard Firefox install. But I didn't want to have to run two copies of Firefox, one for work and one for play, and manage separate user profiles for each. Besides, my goal was to create a hub for my online social activities, so why not use a browser specifically designed for that purpose?</p>
<p>I also could have moved my social stuff to Safari, but that would have required adjusting to the quirks of a browser I'd previously employed only for cross-browser development. <a href="http://flock.com/beta/download/">Flock 2 beta</a> is essentially a tricked-out Firefox 3, so it offers a pretty seamless transition for this Mozilla. It even runs my essential Firefox 3 extensions, such as <a href="http://foxmarks.com/">Foxmarks</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/1122">Tab Mix Plus</a>. With those in place, Flock looks like a souped-up sedan version of Firefox - slower, sure, but with more bells and whistles and a pretty coat of paint.</p>
<p>One feature that especially interested me was Flock's RSS integration. Sure, Firefox does this, too, but Flock's interface is nicer. You can interact with your feeds in a familiar two-pane interface rather than simply viewing headlines from a Live Bookmark. Flock's UI doesn't yet match the convenience of the keyboard-friendly NetNewsWire, but that's fine. I can live without power-user features when I'm just perusing <a href="http://consumerist.com/">The Consumerist</a> or <a href="http://whedonesque.com/">Whedonesque</a>.</p>
<p>After a few days of using Flock to browse Facebook, scan <a href="http://friendfeed.com/armchairdj">FriendFeed</a>, check Gmail, update <a href="http://twitter.com/armchairdj">Twitter</a> and attend to my online banking, I'm sold. I don't really use the widgets on the My World splash page very much, but the integrated toolbar for interacting with Web 2.0 destinations works seamlessly. It's nice to be able to check for unread mail without firing up the entire Gmail interface. And I'm certain I'll use some of the blogging tools pretty frequently. One downside, though: You can't adjust fonts in the People Sidebar and other Flock-specific XUL widgets. My poor, aching eyes will forgive this misstep for now.</p>
<h3>Getting started with Meebo</h3>
<p>Instant messaging wastes as much time as it saves. Commingling of friends and coworkers on the same buddy list has always been dangerous. But even if you're careful, you'll get bleedthrough. Today's valued colleague often becomes tomorrow's high-maintenance friend once somebody switches jobs. Unless you want to give everybody you've ever known equal power to interrupt your work, you need a strategy for separating IM accounts. Creating a new account each time you start a job isn't enough. Hence my decision to segregate my accounts into two separate programs.</p>
<p>Cross-platform IM clients continue to proliferate, but web-based Meebo offers an interesting take on the concept. With its clean interface, soothing palette and lightning-fast Ajax interface, Meebo applies tried-and-true Web 2.0 design techniques to dowdy old chat. I used to have five IM accounts in my local Adium instance, but now I've moved four of them into Meebo. When I want to chat with friends, I can fire up Flock and open a Meebo tab. But when I need to focus on work, I can just shut it down and leave Adium open for agile team interactions at Pathfinder.</p>
<p>As with Flock, there's nothing about this setup that I couldn't have accomplished without Meebo. I could manually log off my non-business IM accounts whenever I want to focus on work. But I'm sufficiently prone to procrastination that such measures don't work. I need to trick myself psychologically, creating a completely different context for work chat and personal chat. Warm, inviting Meebo generates some much-needed contrast with cold, functional Adium.</p>
<p>
<h3>Now the hard part: Sticking to the rules</h3>
</p>
<p>Of course, prying apart the personal and the professional does no good if you're constantly firing up your fun apps alongside the work ones. Now that I've segregated all my time-wasting feeds, distracting chatter and enticing games, I've got to stick to the single rule that makes everything work: Only run Flock-plus-Meebo at specific intervals. I'm giving myself 15 minutes during morning coffee, 30 minutes at lunch, and unlimited time once I'm home at night.</p>
<p>It may seem counter-intuitive to get down to work with the help of two applications designed primarily for fun. But the work/play firewall helps me stay disciplined.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/09/getting-things-done-with-flock-and-meebo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Four blatant iPhone usability blunders (and one constant annoyance)</title>
		<link>http://www.pathf.com/blogs/2008/09/four-blatant-iphone-usability-blunders-and-one-constant-annoyance/</link>
		<comments>http://www.pathf.com/blogs/2008/09/four-blatant-iphone-usability-blunders-and-one-constant-annoyance/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 17:14:38 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[UXD]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[Mobile]]></category>

		<category><![CDATA[Safari]]></category>

		<category><![CDATA[Usability]]></category>

		<category><![CDATA[user experience design]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1128</guid>
		<description><![CDATA[
I've been an iPhone 3G owner for about six weeks now - six weeks of love, loathing, cool apps and connectivity problems. Rather than complain about poor network coverage, though, I'd like to delve into some of the vexing usability problems that hamper the phone's user experience.
No ability to disable autocorrect completely
Like pretty much every [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.flickr.com/photos/otakuchick/1938510172/'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/09/1938510172_9250a8f6b9.jpg" alt="photo of a broken iPhone" title="iPhone" width="375" height="500" class="right" /></a></p>
<p>I've been an iPhone 3G owner for about six weeks now - six weeks of love, loathing, cool apps and connectivity problems. Rather than complain about poor network coverage, though, I'd like to delve into some of the vexing usability problems that hamper the phone's user experience.</p>
<h3>No ability to disable autocorrect completely</h3>
<p>Like pretty much every autocorrect feature ever built, the iPhone's does more harm than good. It always thinks it knows best. If you don't watch it like a hawk, it will render everything you type completely nonsensical. Proper nouns, abbreviations, profanity - all get turned into gibberish by this well-meaning but deeply flawed function. And god forbid you try to use the classic email e.e. cummings mode in which uppercase letters don't exist. The iPhone literally will not let you output the word "iPhone" without throwing in that capital "P." It's maddening.</p>
<p>If the purpose of autocorrect is to allow you to type quickly without having to monitor your output, it fails miserably. On the iPhone, if you want what you type to show up verbatim on the screen, you have to pause at the end of each word to ensure that the OS is not about to substitute its own wisdom for your actual intent. I would honestly rather type on a 1999-era StarTAC numeric keypad.</p>
<p>None of this would be as galling if there were a setting to turn this feature off. But there isn't. <a href="http://www.coderetard.com/2008/06/12/how-to-turn-off-auto-correct-on-the-iphone/">Elaborate, unwieldy workarounds have been suggested</a> - all because Apple users know that the folks in Cupertino often paternalistically ignore their users. Microsoft's OS and apps may suck, but you can usually customize the hell out of them. Not so Apple's.</p>
<p><span id="more-1128"></span></p>
<h3>No saved password feature</h3>
<p>Everybody and their brother has complained about the iPhone's virtual keyboard. Aside from the autocorrect feature, I think it's actually pretty good for composing email or SMS messages. But for passwords, it blows.</p>
<p>If you've got a strong password, chances are it's a combination of upper- and lowercase letters, numbers and special characters. That means you've got to switch back and forth between screen modes constantly. (And don't get me started on the way the iPhone automatically switches from numeric to alpha mode when you hit certain special characters.) Sure, it's nice that the phone shows you the most recently typed character in any password field so you can verify it's correct. But it's still such a painful, error-prone experience that once I've typed a password into my iPhone once, I want the phone to remember it forever.</p>
<p>No dice.</p>
<p>Mobile Safari has no built-in password manager. Sure, you could install an app like <a href="http://www.iphonealley.com/news/ipassword-brings-web-form-auto-fill-to-iphone">1Password</a> to get this functionality, but that means paying $29.95 for a feature that should be baked into any web browser - especially one that makes typing strong passwords such a maddening experience. Lots of iPhone users are downgrading to simple alphabetical passwords just so they can make this process less painful. That's a real blow to web security - especially the security of Apple accounts, whose passwords you've got to type over and over and over again on the iPhone just to perform such simple tasks as updating free applications.</p>
<h3>No love for existing mobile stylesheets</h3>
<p>I get it: Mobile Safari isn't like the other mobile browsers. It's got all the features of a real browser and can display web pages as they were originally designed.</p>
<p>But should it?</p>
<p>Pan-and-scan browsing makes for an incredibly frustrating user experience. Visual hierarchies that work wonderfully in an 800x600 or 1024x768 desktop viewport completely fail when they're reduced to the size of a deck of playing cards. Zooming in on little sections of the screen doesn't alleviate the problem. Mobile Safari's scaling abilities are impressive, but they're no substitute for a properly optimized interface.</p>
<p>Sure, you can serve up custom styles for Mobile Safari's viewport, you've got to use an extremely specific media queries. Normal mobile stylesheets are ignored:</p>
<pre>
&lt;link href=&quot;mobile.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;handheld&quot; /&gt;
</pre>
<p>Instead, you've got to go the extra mile:</p>
<pre>
&lt;link media=&quot;only screen and (max-device-width: 480px)&quot; href=&quot;iPhone.css&quot; type=&quot;text/css&quot; rel=&quot;stylesheet&quot; /&gt;
</pre>
<p>Why ignore the hard work of sites that have bothered to develop a mobile stylesheet? Why not at least offer a setting that will enable these stylesheets on a site-by-site basis? Failing that, could we at least have the ability to disable CSS altogether for certain sites? For the minority of sites with a lovely iPhone interface, Mobile Safari offers a great user experience. For almost everything else, it blows.</p>
<h3>No default keypad in phonecall mode</h3>
<p>Almost every phone number in the world is hooked up to some sort of touch-tone interface. From giant corporate phone trees to individual voicemail accounts, we live in a world where the lingua franca consists of 0-9, # and *.</p>
<p>So why doesn't the iPhone expose a numeric keypad by default during phone calls? To type an extension or navigate a phone tree or hit "0" to skip a voicemail greeting, one must stare at a row of icons for such rarely used functions as three-way calling, press the icon for the numeric keypad, and only then see the desired digits to tap. Sure, it's only one extra click. But considering this is the mainstream use case for most phone calls, shouldn't it be easier? Couldn't Apple at least offer a preference to show the keyboard, rather than the special features, by default?</p>
<h3>No memory of wi-fi network preferences</h3>
<p>If I don't have a WEP password to my neighbor's wi-fi network, I'm never going to be able to connect to it. But the iPhone has no capacity to remember that choice. If I have "Ask to Join Networks" turned on in my settings, it will ask me to join every network it finds. If I say "no" to a specific network, it'll keep asking me every time I launch an Internet-aware application within range of that network. My only choice is to turn off "Ask to Join Networks" altogether ... which means I won't be notified when my phone finds a network with unrestricted access. All it would take is a simple "ignore the existence of this network forever" button to banish a constant annoyance.</p>
<p>Does this irritant rise to the level of usability blunder? No. But it sure gets my teeth grinding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/09/four-blatant-iphone-usability-blunders-and-one-constant-annoyance/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Implementing linked multiselects with jQuery, LiveQuery, and Low Pro: Part 2: First pass at the actual code</title>
		<link>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-2-first-pass-at-the-actual-code/</link>
		<comments>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-2-first-pass-at-the-actual-code/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 19:54:33 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1115</guid>
		<description><![CDATA[
In last week's post, I introduced the linked multiselect widget I was asked to implement on a tight deadline for an unexpected project assignment. I showed some demo code in action and discussed the user experience issues that shaped my requirements. This week, I'll walk through the actual code - or at least my first [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/08/lowproforjquery.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/08/lowproforjquery.jpg" alt="Low Pro for jQuery" title="Low Pro for jQuery" width="150" height="127" class="right" /></a></p>
<p>In <a href="http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-1-requirements-and-interaction-design/">last week's post</a>, I introduced the linked multiselect widget I was asked to implement on a tight deadline for an unexpected project assignment. I showed <a href="http://labs.pathf.com/ajax/blogposts/08182008/demo.html">some demo code in action</a> and discussed the user experience issues that shaped my requirements. This week, I'll walk through the actual code - or at least my first pass at it.</p>
<p>Like a lot of developers who should know better, I sometimes shirk the technical design phase on quick projects, then regret it later. The code I handed off for this project got the job done, but it wasn't very DRY or elegant. Luckily, I've continued to refine it into something I'm not ashamed to blog about. Next week, I'll show off the final, refactored code and try to draw some conclusions about the entire experience. But first - the original, unrefactored code:</p>
<p><span id="more-1115"></span></p>
<h3>The good</h3>
<p>Working with new jQuery plugins always makes a project more interesting. I decided now was the time to get started with Dan Webb's <a href="http://www.danwebb.net/2008/1/31/low-pro-for-jquery">Low Pro for jQuery</a>, a library that adds class-based inheritance and other syntactic conveniences to the <code>jQuery</code> object, including an <code>attach</code> method for linking DOM nodes to prepackaged behaviors. The best, most reusable code I wrote for my initial pass at this project was constructed using Low Pro.</p>
<p>One requirement for my project was the creation of a simple color fade effect to signal DOM updates to the user. Using Low Pro, I was able to abstract this single behavior into its own reusable class for deployment within my larger application. The code looks like this:</p>
<pre>
//a reusable class to add
//a classic Web 2.0 yellow fade
//to DOM elements that have changed
SignalChange = $.klass({
  defaults: {
    //length of the fadeout
    duration: 1250
    //baseline and highlight colors
    , defaultBorderColor: &quot;#ccc&quot;
    , defaultBackgroundColor: &quot;#eee&quot;
    , highlightBorderColor: &quot;#000&quot;
    , highlightBackgroundColor: &quot;#ffa&quot;
  }
  , initialize: function(options) {
    var opts = $.extend({}, this.defaults, options);
    $.extend(this, opts);//just copy over all the options
  }
  , onredraw: function() {
    var that = this;
    this.element
      //cancel previous events of this type
      .stop(&quot;onredraw&quot;)
      .css({
        backgroundColor: that.highlightBackgroundColor
        , borderColor: that.highlightBorderColor
      })
      .animate({
        backgroundColor: that.defaultBackgroundColor
        , borderColor: that.defaultBorderColor
      }, this.duration)
    ;
  }
});

$(&#x27;.multiselect .scrollbox&#x27;).attach(SignalChange);
</pre>
<p>jQuery pros will notice that the CSS magic in my <code>onredraw</code> method relies on <a href="http://plugins.jquery.com/project/color">jQuery Color Animations</a>, a tiny little add-on by jQuery creator John Resig that extends the library's core FX mechanism to handle color transformations. In fact, I had to hack the plugin itself, since it handles borderBottomColor, borderLeftColor, borderRightColor and borderTopColor - but not borderColor. Strange, that, but I got over it. I wanted my color fade effect to support borders as well as backgrounds, and it seemed easier to add a single item to an array in the plugin than to handle each section of the border separately in my own behavior.</p>
<p>The syntax of Low Pro's <code>klass</code> method looks pretty similar to Prototype's <code>Class</code> mechanism, which makes sense. The <a href="http://www.danwebb.net/lowpro">original Low Pro</a> is a library for making Prototype more like jQuery, while Low Pro for jQuery is designed to give Prototype-style support for large, complex and subclassable objects to jQuery.</p>
<p>Notice some of the elegance in Webb's syntax: Any method that conforms to the <code>onwhatever</code> naming convention is assumed to be an event listener - even if it's a custom event such as my own <code>onredraw</code>. Once I've pointed my <code>SignalChange</code> behavior at a DOM node using the <code>attach</code> method, I just need to fire that event to trigger my custom listener. The same is true for native events.</p>
<p>Given the simplicity of my behavior, it could easily have been constructed as a plain old jQuery plugin. But even for such a low-level behavior, Low Pro offers some advantages:</p>
<ul>
<li>If <a href="http://brandonaaron.net/docs/livequery/">Live Query</a> is running, then any calls to Low Pro's <code>attach</code> method are routed through Live Query so they'll be applied to all matching DOM nodes, even those constructed subsequently via DHTML or Ajax.</li>
<li>I can also subclass my behavior more easily using Low Pro than jQuery's built-in plugin mechanism.</li>
</ul>
<p>This inheritance becomes all the more important when your behaviors are more complex, with multiple linked event listeners. Because you can just subclass a Low Pro klass, you don't need to overload it with some insane options hash. You can just create a new subclass for each slightly different implementation. I'll take advantage of this mechanism in the refactored code I show off next week.</p>
<h3>The not-so-good</h3>
<p>In the meantime, I have to take responsibility for the other Low Pro klass I created in this initial version: <code>Subscriptions</code>, which you can <a href="http://labs.pathf.com/ajax/blogposts/08182008/js/application.js">view in full in the source code.</a> Before I get into this code's deficiencies, let's look at what it does right:</p>
<ul>
<li>
<p>It makes great use of jQuery Templates to simplify the construction of DOM nodes. Templates such as the following keep me from having to concatenate strings to create my on-the-fly markup:</p>
<pre>
  this.tmplMemberView = $.template(
    &#x27;&lt;div class=&quot;item&quot;&gt;&#x27; +
      &#x27;${name}&#x27; +
      &#x27; &lt;span class=&quot;info&quot;&gt;(&#x27; +
      &#x27;${groupCount:pluralize(group)})&lt;/span&gt;&#x27; +
      &#x27;&lt;/div&gt;&#x27;
  )
</pre>
<p>I even added some useful helper methods to the <code>template</code> method so I could customize the formatting of my templates:</p>
<pre>
//add some additional template helpers
//for the template plugin;
//use these to format our markup
$.extend($.template.helpers, {
  addConditionalClass: function(value, trueClass, falseClass) {
    return value === true ? trueClass : falseClass;
  }
  , addIfTrue: function(value, conditionalText) {
    return value === true ? conditionalText : &#x27;&#x27;;
  }
  , addIfFalse: function(value, conditionalText) {
    return value === false ? conditionalText : &#x27;&#x27;;
  }
  //only works for standard plurals
  , pluralize: function(value, label) {
    return value + &quot; &quot; + label + (value != 1 ? &quot;s&quot; : &quot;&quot;);
  }
  , count: function(value, label) {
    var r = value.length || 0;
    if (label) {
      r = $.template.helpers.pluralize.call(this, r, label);
    }
    return r;
  }
});
</pre>
</li>
<li>
<p>It leverages Live Query to attach permanent behaviors to DOM nodes that get destroyed and recreated many times over the application lifecycle.</p>
</li>
<li>
<p>It does a good job of wiring up the complex interactions between two interdependent linked multiselects.</p>
</li>
</ul>
<p>However, my code accomplishes most of these things in a most inelegant way. Looking back, I should have modeled a more complex object hierarchy with some sort of reusable <code>LinkedMultiselect</code> object. My Subscriptions object should have been responsible solely for wiring together two of these <code>LinkedMultiselect</code>s and enforcing data dependencies between them.</p>
<p>By starting with one great big all-encompassing class, I ended up having to everything four times: once each for the "selected" and "unselected" states of each of the two linked multiselects. The result is code like this, in which I have to create a single method and then create four more methods to bind it to different circumstances:</p>
<pre>
, getSubGroup: function(coll, prop, state) {
  return $.grep(coll, function(n) {
    return n[prop] === state;
  });
}
, getSubscribedMembers: function() {
  return this.getSubGroup(this.members, &quot;subscribedNow&quot;, true);
}
, getUnsubscribedMembers: function() {
  return this.getSubGroup(this.members, &quot;subscribedNow&quot;, false);
}
, getEligibleGroups: function() {
  return this.getSubGroup(this.groups, &quot;eligibleNow&quot;, true);
}
, getIneligibleGroups: function() {
  return this.getSubGroup(this.groups, &quot;eligibleNow&quot;, false);
}
</pre>
<p>By now, we've all been exposed to enough proper object-oriented JavaScript to do better than this. I know I certainly have, but I fell into the trap of coding rather than designing first. I look forward to showing you the refactored version next week.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-2-first-pass-at-the-actual-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Implementing linked multiselects with jQuery, LiveQuery, and Low Pro: Part 1: Requirements and interaction design</title>
		<link>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-1-requirements-and-interaction-design/</link>
		<comments>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-1-requirements-and-interaction-design/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 23:10:31 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[Low Pro]]></category>

		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1106</guid>
		<description><![CDATA[
Last week I spent a couple of days lashing together a UI widget for a project that needed a little Ajax assistance. As always, I looked for an opportunity to learn something along the way, so I got signoff on using jQuery and some plugins I hadn't previously employed.
The result? A down-and-dirty mini-project that let [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/08/demo.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/08/demo.jpg" alt="Linked multiselect demo" title="Linked multiselect demo" width="300" height="240" class="right" /></a></p>
<p>Last week I spent a couple of days lashing together a UI widget for a project that needed a little Ajax assistance. As always, I looked for an opportunity to learn something along the way, so I got signoff on using jQuery and some plugins I hadn't previously employed.</p>
<p>The result? A down-and-dirty mini-project that let me test drive <a href="http://plugins.jquery.com/project/color">Color Animations</a>, <a href="http://dev.iceburg.net/jquery/jqModal/">jqModal</a> and <a href="http://www.danwebb.net/2008/1/31/low-pro-for-jquery">Low Pro for jQuery</a> while employing tried-and-true solutions such as <a href="http://www.stanlemon.net/index/articles/jquery-templates.html">jQuery Templates</a> and <a href="http://brandonaaron.net/docs/livequery/">Live Query</a>. What's more, the requirements for the widget itself left room for some careful consideration of user experience design.</p>
<p>In the end, I built a client-side demo in just a few days and handed it off to the project lead for integration with a complex back end. Now I'm free to refine my deadline-constrained code into something a little more OO and share the results.</p>
<p>This week, I'll talk about the project's complex usability requirements and Pathfinder's user-centered solution to those requirements. Next week, I'll walk you through our first pass at building custom code, roping in open-source libraries and making it all work together on a tight deadline. Finally, I'll walk you through the refactoring process so you can see the final, properly factored and reusable version.</p>
<p><span id="more-1106"></span></p>
<h3>Requirements</h3>
<p>The requirements centered around a subscription management interface in which members could be subscribed to a product, but only if they belonged to an eligible subscription group. Each member could belong to multiple groups, but at least one of those groups had to be eligible for subscription before the member could be subscribed to the product.</p>
<p>The workflow for this particular screen was for the user to choose which customer groups were eligible for any given subscription, and which customers within those eligible groups should actually be subscribed. (Group memberships themselves were handled on a different page.) Upon hitting our page, the user should be able to do the following:</p>
<ol>
<li>see eligible and ineligible groups at a glance</li>
<li>see unsubscribed and subscribed members at a glance</li>
<li>move groups from ineligible to eligible status</li>
<li>move eligible members from unsubscribed to subscribed status</li>
<li>see the results of any group eligibility change reflected immediately in the member subscription portion of the interface</li>
<li>see a visual indicator of any action's trickle-down effects</li>
<li>see all pending changes before submitting the form</li>
<li>see the number of members in any group - and a complete list of those members</li>
<li>see the number of groups to which each member belongs</li>
</ol>
<h3>Interface and interaction design</h3>
<h4>Multiselect vs. linked multiselect</h4>
<p>The obvious design pattern here was a pair of multiselects, one for groups and one for members. Changes in the groups multiselect would propagate to the member multiselect. This sounded fine in theory, but we quickly learned that not all multiselects are created equal.</p>
<p>To differentiate between the selected and unselected items in a typical multiselect, you must employ a visual highlight. If you also want to call out changes that are pending in the current session, you must employ another visual highlight. Often, you end up with an eyesore: Either a visually chaotic collection of background colors (one each for initially selected, newly selected, initially unselected, and newly deselected) or an equally difficult-to-parse mixture of checkboxes and highlights (checkboxes for on/off, and a highlight to indicate pending changes).</p>
<p>Our solution to this problem was to use another time-honored design pattern: the linked multiselect. In this type of interface, each collection of selectable items is rendered as two physically distinct lists; the unselected items live in one list and the selected items in another. The user physically moves items between the two lists, either by clicking arrow icons or by dragging and dropping. (Due to time constraints, drag and drop isn't part of our current implementation.)</p>
<p>The advantages to this solution include the following:</p>
<ul>
<li>The user can see, at a glance, which items are selected and which aren't. Items in each state are physically separate rather than intermixed.</li>
<li>With screen geography taking care of one type of differentiation (on or off), color can be used for the other type (added or removed). We chose green to indicate newly selected items and red to indicate deselected items.</li>
<li>Thanks to the use of color and geography for the two visual differentiators, no checkboxes or other form fields need be employed. The entire component can be built as a widget and serialized into hidden form fields behind the scenes. Ordinarily, I would follow the principles of progressive enhancement and avoid this kind of JavaScript-dependent interface. But the specs for this project called for a JavaScript-capable modern browser, so I got away with it.</li>
</ul>
<p>The design pattern for linked multiselects is pretty well understood, but our implementation needed to support an additional dependency between one linked multiselect (the groups interface) and another (the members interface). Moving items from selected to unselected within the groups interface would cause items within the member interface to appear or disappear. We therefore had to repopulate the member multiselects in response to events within the group multiselects. We decided to call out these trickle-down effects with a tried &amp; true Web 2.0 color fade effect.</p>
<p>As a courtesy to users, we also decided to retain the previous subscription state of members whose group eligibility was removed. This would alleviate a lot of tedium for users who accidentally changed a group's eligibility and then had to change it back.</p>
<p>Our tertiary requirements added complexity to the project. Because members could belong to multiple groups, we had to display the number of groups next to each member's name. That way, if the user needed to make sure a given member would remain subscribed, he could check how many groups that user belonged to before marking any of those groups ineligible.</p>
<p>Because our linked multiselects divided the members of a group into two boxes, we had removed the ability to see a group's entire membership at a glance. We therefore had to provide an alternate way to achieve this requirement. Our solution was the use of a modal dialog, a link to which appeared next to each group name. These links added some visual complexity to the multiselect, but we mitigated the visual noise with font size and color.</p>
<h3>See the code in action</h3>
<p><a class="b" href="http://labs.pathf.com/ajax/blogposts/08182008/demo.html">You can see the results of our interaction design by playing with our demo code</a>. As a case study, I loaded up a collection of characters from Marvel Comics's "X-Men" franchise. As any fans of the mutant superheroes knows, the X-writers are famous for introducing scads of new characters and trading them between teams like a professional sports league. Using the X-characters allowed me to correctly model the many-to-many relationship between groups and members as they existed in my requirements.</p>
<p><strong>Next time, we'll take a look at the actual code. In the meantime, you can check out the code on your own by viewing source on the above demo.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/08/implementing-linked-multiselects-with-jquery-livequery-and-low-pro-part-1-requirements-and-interaction-design/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Working effectively as a team of one: Five tips for front-end developers on Agile teams</title>
		<link>http://www.pathf.com/blogs/2008/08/working-effectively-as-a-team-of-one-five-tips-for-front-end-developers-on-agile-teams/</link>
		<comments>http://www.pathf.com/blogs/2008/08/working-effectively-as-a-team-of-one-five-tips-for-front-end-developers-on-agile-teams/#comments</comments>
		<pubDate>Mon, 11 Aug 2008 22:33:15 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[front end]]></category>

		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1098</guid>
		<description><![CDATA[Most UI engineers - a.k.a. front-end folks - have worked in environments where they're a shared resource of one person. I often did so early in my career, when I played "webmaster" to a team of writers, editors and visual designers at various online publications.
Now that I'm the Ajax lead at a small, Agile software [...]]]></description>
			<content:encoded><![CDATA[<p>Most UI engineers - a.k.a. front-end folks - have worked in environments where they're a shared resource of one person. I often did so early in my career, when I played "webmaster" to a team of writers, editors and visual designers at various online publications.</p>
<p>Now that I'm the Ajax lead at a small, Agile software development firm, I'm no longer the only technical person in the room. But I'm still just as specialized. It's not that my JavaScript, CSS and JSP skills are any more important than somebody else's SQL, Java or Swing skills. It's just that I'm a team of one, so utilizing me effectively takes a little more planning. Everybody at Pathfinder wears multiple hats, but I was hired specifically to wear the same hat all the time.</p>
<p>Many projects at Pathfinder seek my input, but my attention can only be parceled up into so many chunks. I can't serve as an actual development resource on every project. Over time, I've realized that the following strategies help me deliver the value I need for my company:</p>
<p><span id="more-1098"></span></p>
<ol>
<li>
<h3>Teach them how to fish</h3>
<p>This one's a gimme, but it takes discipline to stick with it. It's so easy to say "yes" when you're asked to do something you've done 100 times before and know how to do quickly. You'll make project managers and clients happy, but you're really shooting the organization in the foot. If you're a shared resource of one, you should do almost no solo development work. Every "yes" should be a "yes" to pair programming only.</p>
</li>
<li>
<h3>Get involved in the process</h3>
<p>If web applications were cakes, Ajax wouldn't be the frosting, it would be the baking powder. You can't just layer it on at the end. In an Agile environment where few projects necessitate a dedicated front-end resource, it's easy to forget about UI concerns until late in the process. By then, prior decisions can make Ajax components far more difficult and time-consuming to implement. One-person UI teams should try to keep tabs on every project in the pipeline. Demand to be included in initial requirements-gathering sessions and check in during as many subsequent iteration kickoffs as possible. By making recommendations early and frequently, you'll save lots of time and money later.</p>
</li>
<li>
<h3>Don't start coding without some sort of road map</h3>
<p>Iterative development is great, but it's harder on the front end. The user interface is the layer most likely to change dramatically based on client feedback. But UI code is also expensive to produce. Prototypes, wireframes and proper business analysis should all come before a single line of JavaScript gets written. Comps and interaction plans are easy to throw away. A thousand lines of Prototype classes and jQuery plugins, not so much.</p>
</li>
<li>
<h3>Start simple, stupid</h3>
<p>Progressive enhancement can actually help with #3 above. On early iterations, build simple HTML controls rather than complex Ajax components. Make sure the application is well factored into individual screens and features before you enhance your first-pass markup into complicated widgets. If you're following the principles of progressive enhancement, your initial "dumb" markup will continue to serve users with screen readers, low-tech mobile browsers or draconian IT-department JavaScript restrictions. Nothing will get thrown away</p>
</li>
<li>
<h3>Learn the entire stack</h3>
<p>User interface development has finally earned recognition as a discrete discipline of its own. Don't let that dissuade you from learning new technologies, especially ones far removed from the UI. Write a Rails app from scratch in your free time. Learn some hardcore PHP plumbing instead of just futzing with WordPress tags. Rewrite one of your custom JSP tags in pure Java instead of JSTL. Install MySQL and have a field day. In short, learn to be a more flexible, less specialized resource. The more places you can be plugged into a project team, the more likely your company will eventually hire additional front-end resources. Then you'll no longer be a shared resource of one.</p>
</li>
</ul>
<p>How about you, front-end readers? How do you make sure you're getting used effectively in Agile environments? Let us know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/08/working-effectively-as-a-team-of-one-five-tips-for-front-end-developers-on-agile-teams/feed/</wfw:commentRss>
		</item>
		<item>
		<title>More on Crockford&#8217;s and Flanagan&#8217;s approaches to JavaScript</title>
		<link>http://www.pathf.com/blogs/2008/08/more-on-crockfords-and-flanagans-approaches-to-javascript/</link>
		<comments>http://www.pathf.com/blogs/2008/08/more-on-crockfords-and-flanagans-approaches-to-javascript/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 18:03:28 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1082</guid>
		<description><![CDATA[
In my recent review of "JavaScript: The Good Parts," I compared this new Douglas Crockford treatise with David Flanagan's canonical "JavaScript: The Definitive Guide." I subsequently stumbled upon a perfect example of the authors' divergent approaches to my native programming language.
Here's Flanagan discussing the dreaded with statement:

Despite its occasional convenience, use of the with statement [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/08/buffy.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/08/buffy.jpg" alt="Buffy the Vampire Slayer" title="Buffy the Vampire Slayer" width="97" height="150" class="right" /></a></p>
<p>In <a href="http://www.pathf.com/blogs/2008/07/book-review-javascript-the-good-parts-by-crockford/">my recent review</a> of <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&s=books&qid=1217956216&sr=8-1">"JavaScript: The Good Parts,"</a> I compared this new Douglas Crockford treatise with David Flanagan's canonical <a href="http://www.amazon.com/JavaScript-Definitive-Guide-David-Flanagan/dp/0596101996/ref=sr_1_1?ie=UTF8&s=books&qid=1217956227&sr=8-1">"JavaScript: The Definitive Guide."</a> I subsequently stumbled upon a perfect example of the authors' divergent approaches to my native programming language.</p>
<p>Here's Flanagan discussing the dreaded <code>with</code> statement:</p>
<blockquote>
<p>Despite its occasional convenience, use of the <code>with</code> statement is frowned upon. JavaScript code that uses <code>with</code> is difficult to optimize and may therefore run more slowly than the equivalent code written without the <code>with</code> statement. Furthermore, function definitions and variable initializations within the body of a <code>with</code> statement can have surprising and counterintuitive behavior.* For these reasons, it is recommended that you avoid the <code>with</code> statement.</p>
<p>* This behavior, and the reasons behind it, are too complicated to explain here.</p>
</blockquote>
<p>And here's Crockford:</p>
<blockquote>
<p>JavaScript has a <code>with</code> statement that was intended to provide a shorthand when accessing the properties of an object. Unfortunately, its results can sometimes be unpredictable, so it should be avoided.</p>
<p>The statement:</p>
<pre class="interior">
with (obj) {
    a = b;
}
</pre>
<p>does the same thing as:</p>
<pre class="interior">
if (obj.a === undefined) {
    a = obj.b === undefined ? b : obj.b;
} else {
    obj.a = obj.b === undefined ? b : obj.b;
}
</pre>
<p>So, it is the same as one of these statements:</p>
<pre class="interior">
a = b;
a = obj.b;
obj.a = b;
obj.a = obj.b;
</pre>
<p>It is not possible to tell from reading the program which of those statements you will get. It can vary from one running of the program to the next. It can even vary while the program is running. If you can't read a program and understand what it is going to do, it is impossible to have confidence that it will correctly do what you want.</p>
<p>Simply by being in the language, the <code>with</code> statement significantly slows down JavaScript processors because it frustrates the lexical binding of variable names. It was well intentioned, but the language would be better if it didn't have it.</p>
</blockquote>
<p>The difference between these approaches to the same topic can't help but remind me of a favorite episode of <a href="http://www.imdb.com/title/tt0118276/">"Buffy the Vampire Slayer"</a>:</p>
<blockquote>
<p><strong>Oz</strong>: [to Faith] I'm wondering about your position on werewolves.</p>
<p><strong>Willow</strong>: [proudly] Oz is a werewolf.</p>
<p><strong>Buffy</strong>: It's a long story.</p>
<p><strong>Oz</strong>: I got bit.</p>
<p><strong>Buffy</strong>: Apparently not that long.</p>
<p>--<a href="http://www.imdb.com/title/tt0533422/quotes">BtVS S03E03: "Faith, Hope &amp; Trick"</a></p>
</blockquote>
<p>There's value in exhaustively documenting a language. But without concrete examples of why something's bad, programmers - obstinate autodidacts that they are - probably won't heed your advice. The Crockford book doesn't always provide such persuasive logic, but it usually does, making it ideal for JavaScript noobs who need to understand how to use the language safely and effectively.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/08/more-on-crockfords-and-flanagans-approaches-to-javascript/feed/</wfw:commentRss>
		</item>
		<item>
		<title>&#8220;Ajax overhaul, Part 4: Retrofit existing sites with jQuery and Ajax forms&#8221; now live at IBM developerWorks</title>
		<link>http://www.pathf.com/blogs/2008/08/ajax-overhaul-part-4-retrofit-existing-sites-with-jquery-and-ajax-forms-now-live-at-ibm-developerworks/</link>
		<comments>http://www.pathf.com/blogs/2008/08/ajax-overhaul-part-4-retrofit-existing-sites-with-jquery-and-ajax-forms-now-live-at-ibm-developerworks/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 18:16:21 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[user experience design]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1081</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><img border="0" alt="IBM" title="IBM" src="http://blogs.pathf.com/photos/uncategorized/2008/03/05/ibm.jpg" class="right"" /></p>
<p>Last week, IBM developerWorks published the fourth installment in my jQuery/UxD tutorial series. <a href="http://www.ibm.com/developerworks/web/library/wa-aj-overhaul4/index.html">Ajax overhaul, Part 4: Retrofit existing sites with jQuery and Ajax forms</a> shows how to turn a multi-page checkout process into a single-screen interface using two jQuery plugins: <a href="http://www.malsup.com/jquery/form/">jQuery Form</a> and <a href="http://docs.jquery.com/UI/Tabs">jQuery UI Tabs</a>. As with previous installments, I tried to show not only how to use open-source JavaScript libraries, but why. Ajax integrates into existing webapps best when it's used to improve their user experience design rather than just thrown in for its own sake. In the example application I constructed for this series, Ajax was used to simplify the shopping process rather than complicate it needlessly. As always, I focused on progressive enhancement so that the overhauled interface didn't leave any users behind. This is the final installment of this series, at least for now. I hope to publish on additional topics at <a href="http://www.ibm.com/developerworks/">developerWorks</a> soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/08/ajax-overhaul-part-4-retrofit-existing-sites-with-jquery-and-ajax-forms-now-live-at-ibm-developerworks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book review: &#8220;JavaScript: The Good Parts&#8221; by Crockford</title>
		<link>http://www.pathf.com/blogs/2008/07/book-review-javascript-the-good-parts-by-crockford/</link>
		<comments>http://www.pathf.com/blogs/2008/07/book-review-javascript-the-good-parts-by-crockford/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 18:04:28 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1058</guid>
		<description><![CDATA[I heart David Flanagan. I'm making my way through "The Ruby Programming Language" this summer. Its exhaustiveness really satisfies. But a decade ago, my programming Bible was Flanagan's "JavaScript: The Definitive Guide". As I transitioned from a career in content to a career in code, "the Rhino book" taught me everything I needed to know [...]]]></description>
			<content:encoded><![CDATA[<p>I heart <a href="http://www.davidflanagan.com/">David Flanagan</a>. I'm making my way through <a href="http://www.amazon.com/gp/product/0596516177?ie=UTF8&tag=davidflanagancom&link_code=as3&camp=211189&creative=373489&creativeASIN=0596516177">"The Ruby Programming Language"</a> this summer. Its exhaustiveness really satisfies. But a decade ago, my programming Bible was Flanagan's <a href="http://www.amazon.com/gp/product/0596101996?ie=UTF8&tag=davidflanagancom&link_code=as3&camp=211189&creative=373489&creativeASIN=0596101996">"JavaScript: The Definitive Guide"</a>. As I transitioned from a career in content to a career in code, "the Rhino book" taught me everything I needed to know about object-oriented JavaScript, DOM scripting and the other building blocks of today's Ajax landscape. I've bought a hard copy of each of the book's five editions. It remained, until recently, the only JavaScript book I'd recommend.</p>
<p><a href='http://www.pathf.com/blogs/wp-content/uploads/2008/07/javascript-the-good-parts.jpg'><img src="http://www.pathf.com/blogs/wp-content/uploads/2008/07/javascript-the-good-parts.jpg" alt="JavaScript: The Good Parts by Douglas Crockford (cover image)" title="javascript-the-good-parts" width="240" height="240" class="right" /></a></p>
<p>That all changed with the recent publication of <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1217280892&sr=8-1">"JavaScript: The Good Parts"</a> by Yahoo's Douglas Crockford. Crockford probably needs no introduction. His <a href="http://www.crockford.com">incisive website</a> and <a href="http://blog.360.yahoo.com/douglascrockford">frequent blog posts</a> have championed JavaScript's power and potential while calling out its drawbacks and frequent misuse. Now, with "JavaScript: The Good Parts," he has managed to provide a reference as useful for JavaScript pros as it is for novices. Part language primer, part apologia and part critique, Crockford's book draws from and extends many of his long-gestating themes about how to use JavaScript - and how not to use it.</p>
<p><span id="more-1058"></span></p>
<p>The author's premise is so simple and intuitive that it sounds like rubbish until you suddenly realize that this is how all programming languages should be taught:</p>
<blockquote>
<p>When I was a young journeyman programmer, I would learn about every feature of the languages I was using, and I would attempt to use all of those features when I wrote. ...</p>
<p>Eventually I figured out that some of those features were more trouble than they were worth. Some of them were poorly specified, and so were more likely to cause portability problems. Some resulted in code that was difficult to read or modify. Some induced me to write in a manner that was too tricky and error-prone. And some of those features were design errors. Sometimes language designers make mistakes.</p>
<p>Most programming languages contain good parts and bad parts. I discovered that I could be a better programmer by using only the good parts and avoiding the bad parts. After all, how can you build something good out of bad parts?</p>
</blockquote>
<p>Crockford has no problem applying this thesis to JavaScript - an exercise he already nailed once in his seminal essay <a href="http://javascript.crockford.com/javascript.html">"JavaScript: The World's Most Misunderstood Programming Language."</a> He describes JavaScript as "Lisp in C's clothing" - a powerful dynamic language that was rushed to market and stuck with a gimmicky name but achieved almost instant ubiquity thanks to the success of the web browser. Crockford doesn't condemn those features, such as non-classical inheritance, that set JavaScript apart from other popular languages. In fact, he bemoans the concessions JavaScript made to the Java crowd - puzzling syntactic choices that obscure the language's true nature.</p>
<p>Once he's established his guiding principles, Crockford spends several chapters cataloging JavaScript's "good parts." And that's pretty much the entire book, save for some excellent appendices. (More on those later.)</p>
<p>So what are those good parts? Crockford seeks to showcase the power and expressiveness of JavaScript's prototypal inheritance, first-class functions, closures, dynamic objects, and object/array literal syntax. To get there, he first describes the language's low-level features: types and operators, statements and syntax. Here, as always, he weighs every sentence carefully, making sure it can introduce new concepts to the uninitiated while also bolstering the understanding of folks who've previously encountered said concepts.</p>
<p>Throughout, he employs the plain, concise and often wry style for which he's known. If you read this book aloud, it would sound like the lectures of a particularly smart, snarky college professor. Even throwaway code samples sparkle with personality; <a href="http://en.wikipedia.org/wiki/Lost_(TV_series)">"Lost"</a> junkies, for instance, will enjoy playing "spot the Oceanic 815 reference."</p>
<p>Where necessary, Crockford offers simple solutions, in code, to overcome some of the trickier aspects of the language's inheritance and reuse patterns. His persuasive explanation of how to untangle prototypal inheritance - rather than building classical inheritance structures atop it - mark him as a programmer who's thought deeply about his craft. So much software development boils down to repeating the same steps one has carried out countless times before. Crockford leads by example, showing how  to rethink received wisdom and rewire one's own algorithms. Such introspection about the <i>process</i> of programming should inspire all but the most haphazard of developers.</p>
<p>I love how this book simply ignores so many small, low-value features of the language. Crockford basically ignores the existence of <code>Function.call</code> in favor <code>Function.apply</code>. He never explains why, but it's obvious: When seeking to bind a function to a new object context, most programmers have to stop and think to remember which of these methods binds arguments as an array rather than as a list of parameters. Why learn both when simple convention can allow one to suffice?</p>
<p>I've been writing JavaScript for a decade, and I'm still impressed with the meat-and-potato chapters of this book. In just 170 pages, Crockford shows developers how to use JavaScript the right way. Is the aforementioned Rhino book still a valuable and exhaustive resource? Yes. But for someone looking to dive into JavaScript for the first time, "JavaScript: The Good Parts" offers advice and perspective to go along with language documentation.  Reading it, I felt like I was encountering the language for the first time - and understanding it better than ever.</p>
<p>That said, Crockford's appendices may provide the most value to longtime JavaScript coders. There, he documents both the "awful parts" and the simply "bad parts" of the language in some detail. These sections work best when Crockford provides concrete evidence to support his assessments, as when he explains the danger blockless statements pose:</p>
<blockquote>
<p>An <code>if</code> or <code>while</code> or <code>do</code> or <code>for</code> statement can take a block or a single statement. The single statement form is another attractive nuisance. It offers the advantage of saving two characters, a dubious advantage. It obscures the program's structure so that subsequent manipulators of the code can easily insert bugs. For example:</p>
<pre class="interior">
if (ok)
    t = true;
</pre>
<p>can become:</p>
<pre class="interior">
if (ok)
    t = true;
    advance(  );
</pre>
<p>which looks like:</p>
<pre class="interior">
if (ok) {
    t = true;
    advance(  );
}
</pre>
<p>but which actually means:</p>
<pre class="interior">
if (ok) {
    t = true;
}
advance(  );
</pre>
<p>Programs that appear to do one thing but actually do another are much harder to get right. A disciplined and consistent use of blocks makes it easier to get it right.</p>
</blockquote>
<p>He's far less persuasive when he decides to forego examples. Proclamations such as the following come off like cant:</p>
<blockquote>
<p>
    The continue statement jumps to the top of the loop. I have never seen a piece of code that was not improved by refactoring it to remove the continue statement.
  </p>
</blockquote>
<p>Despite this occasional lack of substantiation, Crockford has succeeded in writing the definitive book on a language for which a definitive book has long been available. That's no small achievement. If you care about the quality of your JavaScript code, zip over to <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1217280892&sr=8-1">Amazon</a> or your <a href="http://search.safaribooksonline.com/9780596517748">Safari Bookshelf</a> ASAP.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/07/book-review-javascript-the-good-parts-by-crockford/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google Calendar: Finally, a search box that makes sense</title>
		<link>http://www.pathf.com/blogs/2008/07/google-calendar-finally-a-search-box-that-makes-sense/</link>
		<comments>http://www.pathf.com/blogs/2008/07/google-calendar-finally-a-search-box-that-makes-sense/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 21:31:11 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Google]]></category>

		<category><![CDATA[Google calendar]]></category>

		<category><![CDATA[Usability]]></category>

		<category><![CDATA[user experience design]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1057</guid>
		<description><![CDATA[I've been complaining for months about a usability problem with Google Calendar's default search behavior, so I figure I should document that it's finally been fixed. Ever since gCal introduced the concept of public calendars, hitting "enter" in the global search box has kicked off a trawl through the public-calendar database. Instead of searching MY [...]]]></description>
			<content:encoded><![CDATA[<p>I've been <a href="http://www.pathf.com/blogs/2008/02/ionut-alex-chit/">complaining for months</a> about a usability problem with Google Calendar's default search behavior, so I figure I should document that it's finally been fixed. Ever since gCal introduced the concept of public calendars, hitting "enter" in the global search box has kicked off a trawl through the public-calendar database. Instead of searching MY OWN calendar for, say, my Aunt Donna's birthday, gCal instead searches public calendars of, like, sports schedules and Kazakhstanian bank holidays. Smart.</p>
<p>Now, though, that behavior seems to have been flipped. "Search My Calendars" is now the default action, while "Search Public Calendars" has become the secondary action. Bravo!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/07/google-calendar-finally-a-search-box-that-makes-sense/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Five jQuery plugins that are a joy to use</title>
		<link>http://www.pathf.com/blogs/2008/07/five-jquery-plugins-that-are-a-joy-to-use/</link>
		<comments>http://www.pathf.com/blogs/2008/07/five-jquery-plugins-that-are-a-joy-to-use/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 20:15:58 +0000</pubDate>
		<dc:creator>Brian Dillard</dc:creator>
		
		<category><![CDATA[Agile Ajax]]></category>

		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1050</guid>
		<description><![CDATA[
Yesterday I discussed how to separate the jQuery plugin wheat from the chaff. Today, I offer a completely subjective and biased list of jQuery plugins to know and love.



Form
This powerful library collects several useful utilities for manipulating forms - with or without Ajax. It adds eight separate methods to the jQuery namespace, but in some [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pathf.com/blogs/wp-content/uploads/2008/06/ejohn-side-jquery.gif"><img class="alignnone size-full wp-image-941" title="ejohn-side-jquery" src="http://www.pathf.com/blogs/wp-content/uploads/2008/06/ejohn-side-jquery.gif" alt="" width="74" height="74" style="float:right;padding: 10px" /></a></p>
<p><a href="http://www.pathf.com/blogs/2008/07/jquery-plugins-five-tips-for-separating-the-good-from-the-bad-and-the-ugly/">Yesterday I discussed how to separate the jQuery plugin wheat from the chaff</a>. Today, I offer a completely subjective and biased list of jQuery plugins to know and love.</p>
<p><span id="more-1050"></span></p>
<ol>
<li>
<h3><a href="http://malsup.com/jquery/form/">Form</a></h3>
<p>This powerful library collects several useful utilities for manipulating forms - with or without Ajax. It adds eight separate methods to the jQuery namespace, but in some ways I prefer that to one overloaded method with complex invocation logic. The <code>ajaxForm</code> and <code>ajaxSubmit</code> methods offer, respectively, complex or simple asynchronous form manipulation. Both implicitly support progressive enhancement. Additional methods allow you to serialize forms or individual form fields, clear or reset forms and retrieve form values. These methods offer a more convenient interface and a higher level of abstraction than built-in jQuery methods.</li>
<li>
<h3><a href="http://malsup.com/jquery/cycle/">Cycle</a></h3>
<p>It sometimes seems like half the jQuery plugins out there offer some mix-and-match combination of tabs, lightboxes and image slideshows. The cycle plugin does, too, but it's lightweight and well-factored. The core library is only 6k compressed. If you want fancy transitions, you can get those for another 6k. Easing and meta-data can be layered on, too. The API, too, is modular. The options bundle for the library's single, overloaded <code>cycle</code> method is a bit of a mishmash, but it lets you create endless slideshows, start-and-stop ones and everything in-between.</li>
<li>
<h3><a href="http://brandonaaron.net/docs/livequery/">Live Query</a></h3>
<p>Live Query does one thing, and it does it well: It automatically binds and unbinds event handlers whether the associated content was in the native page, added via DHTML or loaded via Ajax. By offering a simple, intuitive wrapper to jQuery's own <code>bind</code> and <code>unbind</code> methods, Live Query rewires a core part of jQuery without jumbling the API or losing the feel of jQuery's syntax.</li>
<li>
<h3><a href="http://plugins.jquery.com/project/jquerytemplate">Templates</a></h3>
<p>A fork of Ext.js templates, this powerful plugin lets you build client-side templates that are as easy to work with as server-side ones. The default syntax leverages JSP-style variables, but you can rewire it with RegExes of your own. Either way, Templates lets you build on-the-fly DOM structures without concatenating strings by hand or building silly helper methods for tag construction. Build a template, throw a hash of data at it, and boom - instant DHTML.</li>
<li>
<h3><a href="http://tablesorter.com/docs/">TableSorter</a></h3>
<p>True Ajax data grids require careful handshaking between client- and server-side code. That makes pure JavaScript approaches to the problem a challenge. Oftentimes, though, you just want to add some progressively enhanced magic to client-side tables. Enter TableSorter, which adds simple or complex sorting to your tables without a lot of fuss. Several plugins offer solutions to this problem, but I haven't yet found one that does it as cleanly or elegantly as TableSorter.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2008/07/five-jquery-plugins-that-are-a-joy-to-use/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
