Ajax Smackdown: Dojo versus YUI!

Note: I was going to blob about the FLEV widget today, but I thought I should mention the smackdown presentation first, since it’s on Tuesday. I’ll follow up on that with the slides and a written article. In the meantime, check out the FLEV test page!
Here’s a description of a presentation scheduled for Tuesday, April 10, here in Rochester NY:

Since Jesse James Garrett coined the term Ajax in February 2005, the development landscape has exploded with Ajax frameworks, toolkits, and libraries. Although there are literally hundreds of libraries available today, two of the top contenders are the Dojo JavaScript Toolkit and the Yahoo! User Interface (YUI) Library.

On a recent Ajax spike, my team created the same example application in both Dojo and YUI. Let’s compare the implementations, and see how the underlying Ajax products differ. Both Dojo and YUI are excellent products in their own way. But, which is the best fit for you, your application, and your organization?

Bio: Ted Husted is a software engineer and team mentor. His specialty is building agile web applications with open source products like Yahoo! User Interface Library, Struts, Spring, iBATIS, and MySQL, for either Java or Microsoft .NET, and helping others do the same.

Ted is a member of the Apache Software Foundation, an active member of the Apache Struts and Apache iBATIS projects, and co-founder of the Jakarta Commons. His books include JUnit in Action, Struts in Action, and Professional JSP Site Design. Ted has consulted with teams throughout the United States, including CitiGroup, Nationwide Insurance, and Pepsi Bottling Group. He is currently working with the Oklahoma State Department of Environmental Services to improve their permitting system.

  • Meetings start at 6:00 pm and end around 8:00 pm
    & Meetings are held on the Third floor of the Golisano building, at RIT, room 70-3000 - CS conference room.
  • Directions to RIT can be found at [url=http://www.rjug.org]www.rjug.org[/url]
  • Members of RJUG are now entitled to discounts on O’Reilly books. Details will be available at the meeting.

S2 Tip - Within a namespace, reuse names for common concepts

In practice, most applications are composed of a small number of workflows that repeat within the application. When configuration elements in different namespaces serve the same role, use the same identifier for each element. If each namespace includes a “Menu” or a “Help” action, use those same names with each namespace.

/receivables/Menu.jsp

/payables/Menu.jsp

Since the namespace feature avoids collisions between element names, we can increase cohesion within the application by using a consistent naming pattern.

Can you spell FLEV?

The most common workflow in any business application I’ve every written or used is Find / List / Edit / View – or “FLEV”.

At work, our last two point applications used this workflow over and over again, and the third will be no different. Often we start with Finding and Listing one entity, which is then used to Find and List related entities, which have related entities of their own to List and Edit. And, of course, we also need to Edit and View any of these entities along the way.

For example in a mail reader, the software starts by finding the new posts for us and presenting a list. We then view the thread, and maybe call an editor to post another article. When posting, we might want to find and list entries from our address book, and either select or likely suspect, or view his or her details, and maybe make some changes.

So on and so forth.

One would think that a FLEV widget would be standard fare in any widget library. But, strangely not. Looking about, I find several types of tables and grids, many with inline editing and filtering. But, in real life, inline editing and filtering via a grid isn’t enough. We do need to rotate the axis and present a single entry on a form, often including fields not expressed on the grid.

Recently, I’ve been working with spanking-new DataTable from the Yahoo! User Interface (YUI) Library. Under the hood, DataTable use a RecordSet to represent the raw set of entries, and a ColumnSet to describe the schema for an entry (data type, editor, formatter, short label, long label).

All that’s needed is a companion widget that can use the same Recordet and ColumnSet to present and edit one entry at a time.

Essentially, we’re talking about a widget can present the same data in four different ways. To get started, I created an issue ticket that described the widget in terms of these four views.

A FLEV widget would allow us to define a columnset and datasource once and use it to generate four presentations.

Finder - Columnset in vertical layout as a form with multifield dataentry and submit. Submit does not modify state. (Matching entries are presented through a Lister.) Some fields may be selectors with change events that update other selectors. Other fields may be calendars or sliders.

Lister - Columnset in horizontal layout as a grid with double-click single field editing. Command events to edit, view, delete, or add may be associated with selected row. Paging through rows is supported.

Editor - Columnset in vertical layout as a read-only panel. Command events may be available, such as save, save and add another, delete, or cancel.

Viewer - Columnset in vertical layout as a read-only panel. Command events may be available, such as edit, copy, delete, print, add, or cancel.
I got a good start on FLEV this week, and we are about ready to drop it into our application. Of course, the widget will be available as open source under the BSD license as the first installment of the Yazaar project. Tomorrow is Struts 2 tip day, but I’ll be blogging more about FLEV over the weekend, including how it uses the YUI LogReader as a development tool. Stay turned!

Google Code Successively Refines

Google Code doesn’t seem to have release per se, or even announce when new features are added. Day by day, it just gets better and better.

Not long ago, the ninjas added to the automatic alerts. Yesterday, I was reviewing some issues and noticed that we can now edit all the issue details. Not long ago, the details were immutable. Now I can fix the issues inadvertently named “Enter one line summary”.

Here’s a run down of some other changes that I’ve noticed. Some of these may be older than others.

  • We can now feature (or deprecate) wiki pages and downloads
  • We can mark an issue “notify me of issue changes”.
  • We can edit issue details.
  • There are now search filters for “My Issues”, “My Starred Issues”, and “Issues to Verify”, along with “All Issues” and “Open Issues”
  • Advanced issues search offers a “without the words” option, along with narrowing the search to labels, statuses, reporters, owners, and such.
  • The number of people who have starred an issue is tracked and reported (as an indication that they care).
    One search filter that is missing is “Fixed” issues. The workaround for that is to enter the word “Fixed” into an all issues search. Ditto for “WontFix”.

Of course, there is still miles to go. Right now, the four features that I miss most on Google Code are

But, even with these missing features, Google Code is still my favorite host, though admittedly because the tab interface makes everything so quick and easy to use.

Now, if we could just wrap Confluence, JIRA, Jive Forums, and (of course) Subversion in the same sort of interface, and get someone to set up a free open source hosting service – then we would really have Team Best of Breed!

Log Me, Log YUI

I’ve never been a logging enthusiast. Many of the frameworks I use put logging to good use, but it not something I’ve felt compelled to inject into my own applications.

Many coders use logging as a development aid. One of my earliest Turbo Pascal programs wrote a character to the menu bar as a “tell”. As the application moved through a workflow, the tell would change. If it hung up, I knew where to start looking. It started as a development aid, but I left it in the production code because, well, it looked cool!

For most developers, our desire to log takes seed with a quick write to standard out, and blossoms as world-class products like Log4J, Log4Net, Log4PHP, and the other flowers in the Apache Logging bouquet.

Rather use loggers as a development aid, these days I tend to set a lot of breakpoints as I develop. I like to follow brother Steve McConnell’s advice from Code Complete. Every time I write a new swatch of code, first, I set a breakpoint and watch it run.

Unsurprisingly, Joe Hewitt’s brilliant FireBug plugin is one of my new best friends these days. Running a close second is the Yahoo! User Interface (YUI) Library’s Logger.

Like other implementations, the YUI Logger works as a singleton, so it’s very easy to write a logging message from anywhere in the application.

// Assigns default category "info" and default source "global"
YAHOO.log("My log message"); `</pre>
As implied by the comment, we can add categories and source parameters to the method call, which are also standard fare for logging systems.

The trick with JavaScript logging is viewing the messages. Most of the Apache Logging bunch rely on logging to console or to a shared file for the application. Some browsers do support a JavaScript console window, but it's not a standard feature. For JavaScript, we need to shift the paradigm.

But it's not such a big shift. Since YUI is a widget library, it would make sense to express the Logger Control (or LogReader) as a widget. To view the messages as they are logged, just add the LogReader widget to an application, again with one whole line of code.
<pre>`var myLogReader = new YAHOO.widget.LogReader(); `</pre>
By default, the LogReader widget plants itself in the top right corner of the browser window. If that arrangement doesn't work for you, the widget can also be attached to a div or dragged around the screen. If the window box still feels cluttered, there a builtin "Collapse" button. To be even more unobtrusive, you can add your own button to show or hide the widget.

An especially good use of logging in a JavaScript application is to document when events fire. Widgets raise primitive events like "click". A well-designed application will handle those events and raise an "idiomatic" event of its own. We can rely on the widget to raise its event, the interesting bit is when we raise our own.

Case in point, we're working on a DataForm widget that can share a RecordSet and ColumnSet with a YUI DataTable. The form widget raises "update" and "insert" events for the benefit of a client controller application. In early testing of the widget, we can't see those events happen, because they haven't been wired to a client yet. But, we can use a logger to view the events as they are raised.
<pre>`oSelf.fireEvent("updateEvent",context);
oSelf.logRecordEvent("updateEvent", oRecord, oOldRecord); // debug

Where logRecordEvent is a helper method that expresses the oRecord and oOldRecord data in human-readable JSON.

We could also set breakpoints to check that the events fire, and the first time around, we still do. But, the logging statements are also a rudimentary unit test. In fact, the next step might be to create Selenium tests that look for logging statements on our example pages.

The YUI library distribution includes *-debug version of all the modules that include this kind of logging statement. The production version has the logging statement extracted. (Leaving a few strange lines of code behind, like empty else statements.)

Of course, there would be a few ways to filter production code for logging statements. I don’t know what YUI does, but for my own projects, I might try an Aptana action to do the dirty work.

Though, since the LogReader can be flipped on and off, it’s not hard to imagine leaving some statements embedded, for the sake of technical support. So, for now, we’re marking the logging lines “// debug” in case we decide to leave some in later.

I may never love logging quite as much as Ceki, but the YUI LogReader is at least a friend with benefits!