My IBM developerWorks series, part 2: Tooltips, lightboxes and more jQuery goodness

IBM developerWorks recently published my second "Ajax overhaul" tutorial. This series teaches intermediate-level developers how to layer Ajax features atop old-fashioned CRUD applications. My colleague Dietrich Kappe calls this the "Christmas tree" approach to Ajax development, and it's a valid choice for many companies. It's not the sexiest take on Ajax, but it often provides a lot of value for relatively little cost.

"Ajax overhaul" tackles a fictional shopping site for its use cases. Each installment examines a particular deficiency in the existing application's user experience and improves it using Ajax and progressive enhancement. Because I focus on the interface layer, the code examples feature only client-side code. I've completed four installments so far, each one employing some combination of jQuery, custom JavaScript and custom CSS.

I previously posted about the first installment. Here's the direct link to the second:

Ajax overhaul IBM developerWorks

Ext JS 2.1 Now GPL (was LGPL)

One thing I overlooked with the release of Ext JS 2.1 is that it is now GPL rather than LGPL. That means that if you build Ext JS 2.1 into your app, it would have to be GPL's if you planned to distribute it. (See this flame thread on the extjs forum).

Not a problem if you are providing a service, but if you are distributing the application, then you are GPL infected.

If we look at part of the GPL v2:

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Now IANAL, but if you distribute a stub application with at least 2 UI implementations that can be downloaded and installed separately, you might be OK. Another argument for designing your applications as service providers that can be accessed by multiple different clients. That way you can change UI frameworks as necessary, such as when your current framework changes open source licenses.

Continue reading "Ext JS 2.1 Now GPL (was LGPL)" »

Recent Ajax Framework Releases/Developments

Some noteworthy Ajax Framework releases have come out in the last few weeks, along with some other news of interest:

  • Ext JS 2.1 and Ext GWT 1.0 Beta - Better performance, new Slider, StatusBar components. REST support (support for other HTTP methods beyond POST and GET). The Ext GWT 1.0 Beta consummates the love affair between GWT (Google Web Toolkit) and Ext that was started by gwt-ext and MyGWT, but provides the comfort of knowing that it is supported by the Ext JS folks. Note: Ext GWT is pure GWT, not an Ext JS wrapper.
  • Dojo 1.1 - First off, API compatibility between 1.0 and 1.1. Unified timing loop (ala Scriptaculous) for animation effects, with increased performance. Syntactic improvements to dojo.query. Unification of XHR functionality into dojo.xhr() function.
  • Backbase Enterprise Ajax 4.2 - Backbase has been in the commercial framework game longer than almost anyone. Among the new features: hierarchical data bindings and improved performance. If you've wanted data binding for tree widgets, have a look.
  • Google Search, Feed and Translation API - I opined a while back that Google discontinued their SOAP search API because they didn't want people reordering or otherwise manipulating their search results. Looking at the terms of use of the new REST service, you can see that this continues to be a concern:  You agree that you will not, and you will not permit your users or other third parties to: (a) modify or replace the text, images, or other content of the Google Search Results, including by (i) changing the order in which the Google Search Results appear...
  • Google App Engine - it only runs Python apps right now, and it's a preview release available to a select few, but you can already see that this is Google's challenge to Amazon's EC2 compute cloud. In at most a year, unless you are security sensitive -- health care, financial services -- or running on Windows, you won't be building and maintaining data centers. The capital requirements for launching sophisticated and scalable online services is about to change.
  • Echo3 (beta) - it's getting close. Superior performance to Echo2. Easier development of new components. Automatic serialization of objects between client and server. All HTML rendering now done on client. Overall the JavaScript client code is now of a design quality on par with the server code.

Lots of exciting developments for Ajax developers and Web 2.0 entrepreneurs. I, for one, can't wait to see how the Google App Engine compares to EC2 for deploying and scaling Facebook applications.


Technorati Tags: , , , , , , ,

GWT 1.5: Get Ready to Fix All of Your JSNI that Uses long

I've been humming along with GWT 1.5, reading the release notes and compiling from trunk. Today I had a nasty little surprise. All of my JSNI code that used long as either a parameter or return value stopped working. So, something like the following...

public native long method(long param) /*-{
   // do something useful
}-*/;

...would throw a nice little exception in hosted mode:

Return value of type 'long' is an opaque, non-numeric value in JS code 
Parameter 'value': 'long' is an opaque, non-numeric value in JS code

Continue reading "GWT 1.5: Get Ready to Fix All of Your JSNI that Uses long" »

Breaking Prototype habits in a jQuery world

Jqueryinaction When you get used to doing things one way, it's hard to retrain yourself. It took me months to "get" the Prototype way of doing things after a decade of writing all of my own Plain Old JavaScript, sans framework. Now that I'm more likely to use jQuery, I've still got some residual Prototype habits to break.

In Prototype's Enumerable class, you call the each method to iterate over a collection. In jQuery, you can do the same - but you often don't have to. Many of the standard jQuery methods automatically iterate over the member nodes of a jQuery object. There's usually no need to do so manually using jQuery's version of each. My friend and former colleague Zack Frazier reminded me of this fact the other day, in response to this original post. His input helped me fine-tune my JavaScript on the new Pathfinder website.

Compare my original version of this code, which transforms target="_blank" windows into more finely controlled JavaScript popups:

Continue reading "Breaking Prototype habits in a jQuery world" »

QWT: Qooxdoo Web Toolkit

Qooxdoo Qooxdoo is an Ajax framework that I haven't spent much time with, but after meeting the guys of Qooxdoo at AjaxWorld East and finding out that it's pronounced "guckst du," as in the German slang "Was guckst du?" (Rough translation: "What are you looking at?"), my interest has been piqued.

One interesting recent addition to qooxdoo is QWT, the Qooxdoo Web Toolkit, a Java to JavaScript "compiler" that works with the qooxdoo framework. I put "compiler" in quotations because, after looking at the code, it looks more like a Java to JavaScript translator. Also, where GWT has a hosted mode where you can debug in Java, QWT doesn't appear to have that feature, so debugging wonky QWT code promises to be a bit of an adventure.

Still, an community effort of this kind indicates that qooxdoo is a vibrant framework. I intend to give qooxdoo a closer look over the next few months.

Technorati Tags: , , , ,

jQuery Form and jQuery UI Tabs: Two great tastes that taste great together

I spent last week holed up writing part 4 of Ajax Overhaul, my series of articles for IBM developerWorks. Aimed squarely at Ajax beginners, the series shows how to progressively enhance Web 1.0 sites with jQuery and Ajax. Each installment starts with the pre-Ajax version of an example e-commerce application and takes readers through the steps of retrofitting it to improve and modernize the user experience. The tagline for this installment is "Streamline multi-step processes with tabs and Ajax forms," a topic that allowed me to employ two of my favorite plug-ins for the jQuery open-source Ajax toolkit:

  • jQuery Form, which gives jQuery several methods for serializing form data and submitting the results via Ajax.
  • jQuery UI Tabs, which turns a series of divs and unordered lists into a tabbed interface.

I feel like I've run on and on about my enthusiasm for jQuery on this site, but I can't help it. One of the cool thing about its plugin ecosystem is the ease with which you can cross-pollinate a couple of plugins to create novel effects. In this case, I wanted to take a series of web forms - the checkout process for my example shopping site - and turn them into a single-page, tabbed interface in which each tab represented one step of the process. The biggest additional requirement was progressive enhancement; with JavaScript absent or disabled, the checkout process has to work like it did before I retrofitted it. All it took to accomplish these goals was a judicious mix of my two plugins.

Exampleshoppingapp

Continue reading "jQuery Form and jQuery UI Tabs: Two great tastes that taste great together" »

jCarousel Lite: DHTML image slideshows with 2kb of code

Jcarousellite

After posting last week about the strengths and limitations of jCarousel, the jQuery image-carousel plug-in, I did some digging and found jCarousel Lite, another option for your image-slideshow needs. Written and maintained by Ganeshji Marwaha, jCarousel Lite is optimized for size and simplicity rather than configurability. It weighs in at just 2kb, but you lose a lot of the more advanced options you get with jCarousel, such as Ajax slideshows and integration with Thickbox. Still, for plain-vanilla DHTML slideshows, jCarousel Lite offers a fast and lightweight solution that requires very little custom code.

Continue reading "jCarousel Lite: DHTML image slideshows with 2kb of code" »

GWT Rolodex now at Google Code

Chris Jones was kind enough to move his GWT Rolodex widget over to Google Code. Looks like you no longer have to resize your own images.

Grab your stack of images (you'll get the best results from images that are roughly the same medium size) and place them in the same package space as your RolodexCardBundle.
That's it. Just drop them in a directory. Check out the RolodexImageBundleBuilder.java for the code that does the magic at compile time.

One enhancement planned already is to do a real perspective transform to "get rid of the jaggies."



Technorati Tags: , ,

GWT: DOM and Opacity

Gwt One thing missing from the DOM class in GWT is the ability to set element opacity in a browser independent way. You do have DOM.setStyleAttribute, but in IE you set the opacity by squeezing a alpha(opacity=val) into the filter, where in most other browsers you set the opacity style attribute directly.

If you take a peek into the prototype library, you'll see all sorts of cruft around setting opacity, such as supporting Konquerer, etc., but in the world of GWT, we just have to support a few browsers (IE6+, Mozilla, Safari, Opera). I had a need for a kinder, gentler opacity when I started developing GWTaculous, my pure GWT port of the Scriptaculous effects library. I implemented my own DOMX class to support those extended DOM operations I needed.

Continue reading "GWT: DOM and Opacity" »

Release of GWT Ext 2.0

Yep, two of my favorite things just got better. The new GWT Ext 2.0 was released with support for Ext 2.0 (is that what the "2.0" means?). You can find the release notes here and a demo here. For those of you who have been stuck under a rock for the last year, GWT is the toolkit from Google that lets you write your Ajax apps as Java which is then compiled into JavaScript. And Ext JS is the super slick, good looking Ajax framework that is sweeping the nation.

Technorati Tags: , ,

A New ZK Tutorial

There are already quite a few tutorials and mini talks on the ZK site, but one more never hurt. Over at Dr. Dobb's, Andrzej Sekula guides you through "Hello, World!" with ZK, while explaining architecture, features and few other things. Worth a look.

Technorati Tags: , ,

Microsoft Eats Its Young: AjaxPro is no more

Ajaxnet Back when .NET didn't have an Ajax pot to piss in, I voraciously read Michael Schwarz's blog and followed his Ajax.NET framework. He eventually released a companion "Pro" version. Now, several Microsoft MVP awards later, he is packing it in. I, for one, will miss the competition in the .NET world. That leaves two major alternatives that I'm aware of:

  1. Anthem.NET
  2. Gaia Ajax Widgets

Since the concepts around how Ajax apps should be built are still in flux, it would be nice to have a few alternatives in the .NET world (especially ones that don't produce the XHR salad that ASP.NET Ajax does).


Technorati Tags: , , , ,

Echo3 Custom Components Coming into Focus

I had a read of some of the Echo3 developer docs this weekend. In particular, the docs on how to create a custom component were very interesting. If you've read the custom component docs for Echo2, you know how messy that was. This time around it looks a little cleaner. There are basically three different object hierarchies:


  1. The client-side JavaScript components, extended from EchoApp.Component.
  2. Their corresponding client-side JavaScript synchronization peers, extended from EchoRender.ComponentSync, which deal with manipulating the DOM hierarchy.
  3. The corresponding server-side Java synchronization peers, extended from the convenience  nextapp.echo.webcontainer.AbstractComponentSync, which handles synchronization between the client-side and server-side component.
  4. The server-side Java component.

The docs aren't quite done yet, but already it looks as if component writers can leverage the framework much more than in Echo2. It's good to see that event handler hygiene is encouraged in the docs.



Powered by ScribeFire.

New Year's Resolutions 2008

As I've posted before, I'm pretty leery of prognostication. My colleageus Noel and Dietrich have already made their predictions for 2008, anyway (here and here) so who am I to join the fray? Instead, let me dust off another hoary device and share my programming resolutions for 2008.

Continue reading "New Year's Resolutions 2008" »

Ajax Predictions for 2008

I'm a little early this year for my 2008 predictions. No matter. I seem to have been a bit early with my 2007 predictions as well, and as they say in the venture capital biz, "too early is the same thing as wrong." Some of my predictions did come true -- Ajax is no longer such a big buzzword; a number of framework specific books (GWT, jQuery) have been published at the end of 2007; Microsoft's Ajax stack continues to limp behind the rest. A few others did not, notably the ho-hum release of IE7 and the delay in FF3. So, let me try my hand at some more prognostication:
  1. Elegant, good looking frameworks like Ext and myGWT will gain traction. The more out-of-the-box good looks you can give them with CSS and bundle images and icons, the more acceptance they will gain.
  2. The JavaScript framework chaos will continue. The OpenAjax alliance will continue to be ineffectual in promoting things like widget interchangeability.
  3. Security will become a big headache, as less sophisticated developers start to venture into the wonderful world of Ajax, littering the web with state and control logic on the client side.
  4. Towards the end of 2008, FF4 and IE8 will start to change the landscape of Ajax and Web 2.0 with an update of JavaScript and new browser features.
  5. MS Volta will do nothing. It is just a FUD shot across the bow of GWT.
  6. Everyone except Craig's List will have some form of Ajax on their site.
  7. Desktop RIA's through Google Gears, Adobe AIR, etc., will start to make an impact in the second half of 2008. Look for desktop/web hybrids of the office productivity tools, such as word processors and Powerpoint clones, to see greater use in the corporate IT space.
  8. GWT's compiler will produce more efficient code than 98% of JavaScript developers can do by hand.
  9. With the new browsers, a cross platform Canvas/SVG will be a reality by the end of the year.
  10. IE8 will still leak memory like a sieve.
Have any of your own predictions? Feel free to add them in the comments.



Technorati Tags: ,

Eating crow on jQuery

When I was first getting acquainted with jQuery, I blogged about it quite a bit (here, here and here). There was a lot I liked, but I got easily frustrated. Having previous experience with Scriptaculous, I found the built-in effects features and even the Interface plugin a little under-featured. In particular, the lack of fine-grained queue control bothered me. I also struggled at first with jQuery's lack of built-in object and class factories. I engaged in back-and-forth with jQuery team members about my posts. Then I moved on to other projects.

Recently, however, I returned to jQuery for Ajax Overhaul, my upcoming series of tutorials for IBM developerWorks. Ajax Overhaul tackles how to improve the user experience of dusty pre-Ajax applications with unobtrusive JavaScript. My series shows how to install lightboxes, modal dialogues, form validation and other Ajax goodies with minimal changes to server-side infrastructure. It was therefore imperative that I use a toolkit engineered from the ground up for progressive enhancement. Naturally, I thought of jQuery.

In the process of writing the first couple of installments, I discovered the not-so-secret ingredient to jQuery's success: the plugin ecosystem. By officially sanctioning a broad range of plugins and providing hosting, support and PR for mature plugin libraries, the jQuery team has galvanized a really impressive developer community. So far in my writing for the IBM site, I've used Greybox, Thickbox, jTip and jQuery Forms - all really fantastic tools that empower even novice Ajax programmers to do really cool things with very little custom code and 100% adherence to progressive enhancement.

As long as plugin authors follow the rules, their libraries offer the same compatibility as the core jQuery distribution. (See this post, including comments, for details on how to write plugins that don't create namespace collisions.) My only gripe with the plugin landscape is that it's so scattered. Despite the availability of hosting on the jQuery servers, lots of plugin authors opt to host their own sites. There's no one-stop shop like the one for, say, Firefox.

I still haven't found a good plugin for managing classes, mix-ins and other inheritance schemes, but just by typing that I'm sure I'll get comments to the contrary. Regardless, it's easy to use jQuery alongside, say, MooTools.

As for my desire for fine-grained control of jQuery's effects queues, all it took was one enterprising plugin author. jQuery team member Rey Bango pinged me a few months ago about developments on this front, and now the code is live. I haven't yet worked with Luciano G. Panaro's Fx Queues plugin, but at first glance it looks like exactly what I need. As Really Simple History matures, I'm looking to get involved in other open-source projects. Contributing to the jQuery ecosystem is at the top of my list.

Technorati Tags

Blogging from the GWT Conference: GWT as a Replacement for Java Swing Apps

Just here a short while and I've already heard some interesting notions from some hardware vendors (SANS, Firewalls, etc.) about how GWT might be the key to solving their deployment problems. Right now, many of them use Java (write once, run anyware, etc.) to write the desktop administration applications that manage their hardware. But Java is not trivial to package up and deploy for different OS's. Many of these vendors seems to be considering GWT as an alternative, i.e. you get the RIA experience without having to deploy anything past a browser on the client. More evidence that the browser is being viewed as an application platform, i.e. an operating system.

Technorati Tags: ,

All guns blazing on Ext JS 2.0

The day has finally arrived: Ext JS 2.0 received its final public release today. Judging by the timeouts I've been getting all morning when trying to connect to the Ext site and blog, I'm not the only one who's been waiting anxiously. Originally tied to the YUI framework but now a standalone library, Ext provides the best example I've yet seen of a completely client-side framework for desktop-style RIAs.

As Ajax libraries multiply, they need to differentiate themselves to get my attention. Ext does just that, providing a top-to-tails solution for GUI components: tabs, trees, grids, you name it. Prototype, jQuery, Mootools and Dojo provide powerful general-purpose tools for Ajax development. Ext, on the other hand, uses a component model whose baseline configuration gets you 90% of the way there and whose extensibility gets you the rest of the way. It's a huge achievement that Ext does so while embracing Web standards and user experience design. You don't use Ext to sprinkle a little Ajax on your Web 1.0 application; you use it to build powerful, data-centric applications from the ground up without relying on GWT or .Net to write your JavaScript for you.

For the example application I'm building to show off Really Simple History, I'm constructing parallel versions with Prototype, jQuery and Ext. Frankly, it's the Ext version that I'm most excited to show off. I've been waiting patiently for a couple of months to find a hole in the schedule of busy Ext creator Jack Slocum. Now that Ext 2.0 is out there, I hope to publish an interview with him in this space soon.

With the Ext servers struggling to meet demand, you may have trouble trying to download the library, read the announcement or peruse the completely overhauled documentation. In the meantime, you can read this exhaustive Ajaxian post about all of the changes and new capabilities.

Technorati Tags

JRails: Scriptaculous on top of JQuery

Prototype and Scriptaculous had their origins in Ruby on Rails before spinning off. There they went head to head with the lighter, leaner JQuery. Now the circle is complete, with Scriptaculous functionality on top of JQuery making its way back into RoR in the form of JRails.

jRails is a drop-in jQuery replacement for Prototype/script.aculo.us on Rails. Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library.

This is certainly good news for folks who do a fair bit of mashing up. Combining two sites or services, one of which uses Prototype and the other JQuery, can be a bit painful.

Technorati Tags: , , , ,

Eating Some Crow on ThinWire

OK, so I was wrong in ThinWire. The issues around having to position and size components is obviated through the existence of two layout managers -- SplitLayout and TableLayout. These layout managers calculate size and positioning for you (and override any values you may have explicitly set). They certainly make developing in ThinWire much less tedious than I previously thought. For an excerpt of the ThinWire handbook that discusses the two layout managers, see here.

For more sophisticated or fine grained layouts, you'll likely want to develop your own layout managers. I'll officially remove ThinWire from my list of 2007 Ajax Turkeys.

Technorati Tags: ,

Really Simple History and the compulsion to tinker

I committed several weeks ago to roll Really Simple History 0.6 RC1 over into a final release on Dec. 1. That's still the plan, but I'm having trouble resisting the urge to tinker. I'm starting to see how a project like this could remain in indefinite limbo if I don't just draw a line in the sand and release a final "hard" version that people can rely on for production code. The current SVN trunk includes a number of backwards-compatible enhancements. I'm working hard to test them all as comprehensively as possible, but I'm going to avoid adding risk to 0.6. Instead, I'll save them for 0.7, which will come out in beta before Christmas.

The enhancements targeted for 0.7, some of them already complete, include the following:

  • Configurable location for the blank.html file: You'll be able to override the name and directory location of blank.html in case your server architecture demands that it be served from a different location.
  • Automatic handling of history points whose keys contain spaces or other special characters; encodeURIComponent is my friend.
  • Automatic title changes: You'll be able to pass a third argument to dhtmlHistory.add and update the document title with its value. You'll also be able to pass in a base document title through the options bundle so that each call to add just swaps out the subtitle.
  • One-line initialization: You'll be able to pass your listener into the dhtmlHistory.initialize without having to call addListener separately.
  • Private methods that are actually private: Methods that are currently marked "private" but are accessible to anyone will become inner functions with no public access.
  • Better global namespacing: I was hesitant to change the API for the 0.6 version, but I'd like to follow the YUI model and group all of RSH's objects into a single global variable. Instead of dhtmlHistory and historyStorage, we'll end up with RSH.history and RSH.storage.

The roadmap for 1.0 includes the following:

  • JSUnit and Selenium test suites.
  • Adapters for major frameworks using the MooTools model.
  • Customizable downloads.
  • Serious tutorials and documentation.

In the meantime, downloads for 0.6 RC1 have crept to just under 350 almost 700. Look for me to "flip the switch" on Saturday, promote 0.6 to the stable production version, and deprecate 0.4 once and for all.

Technorati Tags

JavaScript terror alert

Now that I'm getting immersed in the conference circuit, I've got a new game to play every time I attend a session on any technology meant to ease the pain of client-side development. Based on the session abstract, I lay odds as to how long it'll take me to hear the presenter say something like this:

Without [insert name of tool here], you'll have to write your own JavaScript. I don't know about you, but I sure don't wanna do that!

I wasn't surprised when I experienced this several times at Adobe MAX a few months ago, but it sure bummed me out to hear David Geary say it this weekend at No Fluff Just Stuff. I guess I shouldn't be surprised that this message would play well to the Java-centric crowd at NFJS. In fact, I should probably give Geary props for getting almost 75 minutes into his three-hour talk on Google Web Toolkit before delivering the blow.

My colleague Dietrich Kappe has obviously been a leading proponent of GWT, but until Geary's talk I hadn't really gotten past the high-level view. I have to say, despite the fact that GWT is designed to obviate the need for traditional client-side development, Geary's talk got me excited enough to give it a shot. At most every job I've ever had, I've wanted the chance to expand my skill set by stepping into a junior Java role on at least one project. It's never happened, though; once you're good at one thing, it's pretty hard to convince your boss to let you flail around trying to learn another on company time. Perhaps a GWT project or two will finally give me some real Java exposure in the client-side environment I know so well. It's pretty ironic, though, to write code in a language you don't understand just to have it compile "down" to a language you do.

JavaScript authors, have any of you given GWT a shot? I'd be interested to know what you learned, so leave me some comments.

Technorati Tags

DOMContentLoaded and the quick rise of de facto standards

There's never been a better time to be a JavaScript developer. JS hit the big time with the advent of Ajax, and overnight client-side programmers went from being the redheaded step-children of the web-development world to front-and-center participants in the RIA revolution. Even if you're working on a team of one, there's a thriving global community of JavaScript gurus constanly pushing the language forward, working out browser kinks, demonstrating how to import concepts from other languages and computing paradigms, and otherwise inspire you. It's a big change from 10 years ago, when you had Webmonkey and the David Flanagan book and a few cookbook-style compendiums of tips and tricks. This is seriously the golden age.

Working for the last couple of months on Really Simple History, though, I've become interested in the way specific techniques become the flavor of the month and quickly redefine how we conceptualize "good" JavaScript coding practices. Take, for instance, DOMContentLoaded. After the first version came onto the scene, within a matter of months we had many competing implementations of the basic concept that your scripts shouldn't have to wait for window.onload to fire before getting down to business. Now, DOMContentLoaded is the de facto start point for many, many JavaScript applications. Heck, it's even the basis of the entire jQuery event model. There's nothing wrong with that, but widespread use of Ajax toolkits can conceal the fact that DOMContentLoaded is just a collection of hacks. It works, as long as our toolkits keep iterating one step ahead of the browser vendors. But do we really need it?

At Orbitz Worldwide, my previous employer, we implemented a first-rate unobtrusive-JavaScript architecture. (See it in action at Ebookers UK.) Everything was progressively enhanced from dumb markup. That meant our application worked just about everywhere. But it also meant lots of DOM parsing and initialization that couldn't begin until window.onload. As our application grew, this caused enough of a UI flicker - form controls turning into widgets, links morphing into Ajax calls - that we needed to jump the gun on window.onload if we wanted a good experience for the majority of users ... the ones with modern, JS-capable browsers. DOMContentLoaded made sense, and architect Nik Krimm pounced on it.

But for a large subset of websites, there really isn't THAT much difference between window.onload and DOMContentLoaded. If you're merely adding an unobtrusive behavior layer to a traditional, content-driven website, chances are that good old window.onload will perform just fine. There's usually little reason NOT to use DOMContentLoaded. But unless you are developing a desktop-style webapp or implementing progressive enhancement on a foundational level, it's not really necessary. And in certain cases, it just flat-out won't work.

An enthusiastic beta-tester discovered such a case when trying to initialize RSH's dhtmlHistory object from DOMContentLoaded. It broke, and I immediately knew why: RSH relies on the ability of modern browsers to auto-save form data for the life of a session. RSH uses a hidden textarea to cache serialized Ajax application state and render the back button useful again. Internet Explorer doesn't repopulate the cached value of that textarea until an instant after window.onload. If you try to access that cache during DOMContentLoaded, it simply isn't there. This is true of both IE6 and IE7. Therefore, you need to wait for window.onload.

I'm not really sure there's any big conclusion to draw from this example. As I said, it's just interesting to me that in the space of a year or two, DOMContentLoaded has become a de facto standard. As we pile browser hacks on top of one another to push the web forward, sometimes they're going to conflict. Luckily, we can always peek past the curtains and figure out what's  going on behind the scenes.

Really Simple History 0.6 RC1 now live at Google Code

After much tinkering, I am happy to announce the release of Really Simple History 0.6 Release Candidate 1. This version offers a number of improvements and bug-fixes over the 0.6 beta released on Oct. 23. I encourage the 600+ people who have downloaded the beta to upgrade immediately to this release candidate. As for the 3,200+ people who have downloaded the stable 0.4 version in the last two months, it's your turn, too. Beta-testers helped me put RSH 0.6 through its paces in a wide range of browsers and platforms, alongside a wide range of Ajax frameworks, and the result is solid. I fully expect this version of the code to become the new, stable 0.6 release on December 1, barring any show-stopping bug reports.

What will change between now and the final release

We'll provide a minified version of the stable release for download. We'll also provide links to sample apps. That's it.

How to upgrade

Change log

  • Rock-solid support of Opera up to 9.5 beta for Mac and PC.
  • Rock-solid support of Safari/Mac from 2.03 through 3.03.
  • Tons of internal refactoring.
  • Two-line initialization of dhtmlHistory and historyStorage (as opposed to the previous two init calls in the library and two more in your code).
  • Support for an optional options bundle in the initialization call to trigger debug mode or override default JSON methods.
  • Compatibility with Prototype thanks to the aforementioned JSON override capability.
  • Additional choice in JSON parsers; we now ship with a default 2007 JSON parser that alters core object prototypes and an older 2005 version that doesn't.
  • Better user-agent sniffing that's more resistant to UA spoofing.
  • Removal of a bug introduced in 0.6 beta that threw an error when you hit a virgin (hashless) page state.
  • Graceful swallowing of errors in non-debug mode.
  • Replacement of equality operators with JSLint-friendly identity operators where appropriate.
  • Cleanup of a little cruft from the 0.4 and 0.6 beta versions.

Browser compatibility

Supported

  • IE6 (Windows)
  • IE7 (Windows)
  • Firefox 2.x (Mac, Windows, Linux)
  • Opera 9.22-9.5 (Mac and Windows)
  • Safari 2.03, 2.04 and 3.03 (Mac)

Unsupported

  • Safari 3.x (Windows): Falls prey to fundamental bugs in Apple's current beta release.
  • Non-Mozilla-based Linux browsers.
  • Any browser not listed above; test before you deploy.

Want to showcase your RSH-enabled application?

If you use Really Simple History 0.6 in your production code, I'd love to take a look and possibly highlight your app in a future post. Please email me, comment here, or send a note to our Google Group.

Technorati Tags

ZK 3.0 Released

It's been a bit over a month and a half since ZK 3.0 RC was released and the ZK team has sure been busy. The list of new features is long, but has a surprisingly large number of them are new from RC1 to final:

  • The performance of ZK is much improved - four ~ five times faster.
  • Server push (really polling) is enabled which allows you to update client’s information actively and the usage is simple and intuitive.
  • The ZK Layout component which simplifies the job of UI designer.
  • Customize layout of ZK components using CSS definitions.
  • Add forward and apply properties to realize MVC approach more easily.
  • SimpleListModelSharer - integrates server push and ListModel allows you to update data of clients based on the same data automatically.
  • New expression of annotation is ease of use, and easy-to-read.
  • TreeModel is introduced which simplifies the job of Tree rendering.
  • Flash components allow you to play audio and video files. (including youtube clip)
  • Native namespace is implemented to speed up the performance while integration with HTML.
  • To speed up the performance of ZK, EL evaluator is pluggable, and a new way to render ZK components is introduced.
  • More integration with other frameworks, ZK has integrated with JSF, JSP, and Ext-JS.

I find the addition of the layout component interesting. It seems that everyone from GWT, Tibco GI, Ext JS, etc., is moving toward the programmatic model of layout, i.e. DockPanel and so on. In fact, several of the Web 1.0 frameworks have been doing this for a while now, and of course the desktop GUI frameworks have been doing that since the stone age, so the wheel does seem to get reinvented again and again.

I do think that CSS, while giving you fine-grained control, can be a bit unwieldy for day-to-day use. Being able to stuff widgets into containers and have them handle layout is very tempting and convenient. But note the presence of fine-grained layout managers (GridBag anyone?). In my many years of developing applications, I've seen projects sink under the weight of getting everything within a pixel of perfect. Under those circumstances, fighting with CSS through the damp blanket of a layout manager is torture indeed.

P.S. ZK Mobile 0.8.7 was also released and is now compatible with ZK 3.0.


Technorati Tags: ,

Really Simple History 0.6 countdown: Bug fixes, SVN repo, mailing list, downloads, more

Lots more news on Really Simple History, the open-source Ajax bookmarking library I'm now spearheading:

  • SVN - RHS now has a Subversion repository. The version trail starts with the 0.6 beta. Since its release, I've been committing bug fixes and refinements as I get them tested. Feel free to check out a read-only copy if you're already bored with the beta.
  • Mailing list: I've also started a Google Group for the project. In the future, that will become the primary means of communication for RHS, and I'll get back to other subjects here on Agile Ajax.
  • Bug fix: for/in loops - It's universally acknowledged that they're considered harmful, but I unthinkingly added one to the codebase just before zipping up and publishing the 0.6 release. That's now remedied in SVN.
  • Bug fix: Safari - The initial 0.6 beta also had a major shortcoming in its Safari 2/Mac implementation. Bookmarking worked great as long as you didn't navigate away from your RSH-enabled app and then come back. If you did, goodbye, history. It turns out that the history.length hack fails in these circumstances because the browser resets the value each time the page loads. My solution was to add yet another hidden form field and store the initial history.length value there the first time the app loads during a session. Upon subsequent loads, I grab the value from this field instead of from history.length. Hacks upon hacks upon hacks, but it works.
  • Enhancement: test page - I've continued to refine the test page. It's now got a single logging console instead of three separate ones, plus easier-to-read log messages and more user-friendly controls.
  • Download archive - I've created a bunch of for-posterity-only downloads of Brad Neuberg's original versions 0.1 through 0.4. It seemed a little silly to create a retroactive SVN trail for them.

As of this writing, 225+ people have downloaded 0.6 beta. That's in addition to the 2150+ people who have downloaded the stable 0.4 release in just the six weeks that it's been hosted at Google Code. It's really hitting me how many people actually use this thing, which spurred me to spend my weekend on the tasks listed above. I'm working hard to address the following additional issues before putting out a non-beta release:

  • Bug fix: Safari infinite loading bug - I want to get rid of the stupid, eternally spinning disc on my RSH Safari tab. The fix is out there in the world; I just need to implement it.
  • Bug fix: Opera history dies when you navigate away and back - I licked this in Safari, so now on to Opera.
  • Bug fix: IE user-typed history entries - RSH 0.4 handled these properly, but I broke something in 0.6. It's a corner case, but I'd hate to undo Brad's hard work to handle it.
  • Enhancement: window.onunload - RSH has always clobbered previously defined onunload handlers. In this era of memory leaks and the onunload events that help plug them, I want to handle this more gracefully.
  • Enhancement: JSON bridging - The standard JSON library I'm shipping with RSH doesn't play well with Prototype. I need to provide a better mechanism than brute force for individual users to override these methods with their own JSON serializer and stringifier.
  • Enhancement: Graceful failure - I want to add better user-agent detection and set a global flag to just turn RSH off for those user-agents that aren't supported. Right now, for instance, the library thinks Safari works, period, when really only Safari 2/Mac works perfectly.

I'm pretty confident I can get most of this committed this week. If you're an RSH user, please let me know if there's anything I'm overlooking.

Technorati Tags

DOM methods, document.write and the art of library design

So I ended up doing some last-minute fiddling with the Really Simple History 0.6 beta before posting it for testing over at Google Code. Matt Snider pointed me to a potential SSL problem with using DOM methods rather than document.write to insert IE's hidden iframe. I've got four places where I need to insert stuff into the DOM, and I had already hemmed and hawed quite a bit about whether I should use DOM methods, document.write or a mixture. For now, based on Matt's comments and the verbosity of DOM methods, I've reverted back to using dirty-but-concise document.write. I'm going to continue testing this in as many browsers as possible before settling on a permanent solution.

While fiddling, I discovered something interesting that contradicted yesterday's (now-corrected) post. I originally wrote that if you've got script-generated DOM elements that need to be treated as native to the document (so, for instance, you can persist form values across an entire session regardless of whether you navigate off-site), you must use document.write to insert them into the DOM. Not true, as it turns out. It doesn't matter whether you call document.write or standard DOM methods from the head of your document. Either way, both methods seem to result in "native" HTML form fields that can properly persist values. Looking at Firebug or Opera's developer console, you can see that these elements end up being children of the body element even though they were, in fact, inserted into the head element. Modern browsers are so smart!

This whole issue of when to generate DOM nodes brings up an interesting facet of library development: Deciding how much stuff the end user (i.e the developer who is leveraging your library) has to do in the actual document. For most libraries, it's not an issue, because their objects and methods aren't going to do anything until called by application code. But it's different for something like Really Simple History, which relies on a variety of browser-specific hacks, many of which need to be set up before the DOM finishes loading. Sure, you could include inline script blocks in the body of your document to write the hidden, browser-specific DOM elements that enable your library to function. But developers really hate it when the use of a library forces them to fiddle with their page templates. Library authors have to get creative - for instance, by calling their initialization methods in the library file itself, even though that will result in DOM elements getting written to the document head.

As I said in yesterday's post, Ajax history management works only thanks to a variety of browser quirks and hacks. If you want clean code that doesn't break any standards, then you should cross history management off your list of requirements.

Things get even more interesting when your browser-specific DOM hacks work best when they're included as actual markup. My beta is out there, but I'm still scrambling to figure out the best strategy for Opera which, thanks to a bug introduced in 9.x, relies on a hack involving an image tag a crazy URL:

<img src="javascript:location.href='javascript:dhtmlHistory.checkLocation();';" style="visibility:hidden" />

This image throws errors in IE, so I couldn't tell developers to include it in their actual markup even if I wanted to release a library with such brittle implementation rules. If I want it to go in the actual HTML, I'd have to ask developers to do server-side browser sniffing and include it only for Opera users. YUCK. Yet all of the methods of writing it to the DOM via script have drawbacks. The way I'm doing it now, it works in Opera, but it throws an exception in the JavaScript console. Sure, only developers will see that exception, but still.... I guess I still have my work cut out for me.

Technorati Tags

Coming soon: Really Simple History 0.6 beta

Late tonight over at Google Code, I'll be posting a beta of Really Simple History 0.6 for testing. The goal is to elicit help from RSH users in chasing down any bugs I've failed to catch, then push out a stable release around Halloween.

I've tried to be as ambitious as possible with this release: full support of IE7/Win, Safari/Win, Safari/Mac, Opera/Win, Opera/Mac. I've didn't quite get there, but I got close.

Features in the new version include:

  • Full support for IE7/Windows (though my only Windows machines use IE7 Standalone, so I need help testing on "real" IE7 installs).
  • Full support for Safari 2/Mac (though I'm still trying to eliminate the "infinite loading" bug before I push out the beta).
  • Partial support for Safari 3/Windows (hampered by bugs in the current beta version of the browser).
  • Full support for cross-platform Opera 9.22 (though you may need to hard-code an image into your markup).
  • A totally revamped test page that allows you to play with the library in your browser of choice and see how it works behind the scenes.

As always, RSH works beautifully in Firefox 2 for Windows and the Mac. I hope to give it a good shakedown on Linux browsers in the next release.

So what is Really Simple History, and why am I updating it?

An Ajax bookmarking and history-management framework originally developed by Brad Neuberg, RSH became my responsibility a little over a month ago. I tinkered with it for a few weeks, then finally camped out with it for most of the past week to get a release out.

This is the first time I've ever contributed in this manner to an open-source project. It's been a lot of fun, but it's also been maddening, as anybody who's ever dug into the bowels of cross-browser history management can tell you. Here's a sampling of what I've learned from RSH:

Safari is crazy

Plenty of people who've worked on Ajax bookmarking projects have commented about this, but it only becomes clear once you've actually seen it in action. Getting this thing to work in Safari 2 for the Mac took a wildly disproportionate amount of time considering its market share. I wouldn't have been able to do it without Bertrand Le Roy over at Microsoft, whose blog entry on the development of the .Net history manager pointed the way for both Safari and Opera.

As Le Roy and others have noted, the Safari 3 Windows beta is so buggy that history management is hopeless. You can enable the back button for Ajax apps, but once you use it, the forward button becomes disabled. I noticed yet another wrinkle in this behavior (skip ahead if you're easily bored):

Navigate to a non-RSH site - Google, for instance. Then travel to an RSH site, create some history entries via RSH, and use your back button. The forward button stops working: a known bug. Now keep hitting back until you get back to Google again. Suddenly, your forward button works again. Hit forward and land back in your RSH app. Magically, the forward button continues to work.

If I hadn't spent so much of the last week lost in Safari-land, this interesting behavior might be worth further investigation. For now, I'm just hoping the Safari 3 team fixes this before the final Windows release.

Don't try to retire document.write just yet

A couple of different RSH users suggested getting rid of Brad's original calls to document.write in favor of standard DOM methods for adding elements to your page. That approach worked for some elements, but not for others.

In IE, RSH writes a hidden iframe into the document and uses the location and history of that iframe to help it track application state. Writing the iframe with document.createElement works just great.

But for all browsers, RSH uses a hidden textarea to store the entire history stack behind the scenes. This powers one of RSH's coolest features: its ability to retain history even if you navigate away to another site and then come back to your RSH application. This works because modern browsers retain form-field values throughout an entire browser session. But they do so only for form fields that exist in the DOM natively - that is, exist in the actual HTML markup or get inserted via document.write get inserted into the DOM before it's finished loading. 

If you create a form element after your DOM is already loaded, the browser has no way to persist values in that element after you leave the page. Each time the page loads, even from the cache, you essentially create a virgin new form field. I'm therefore using document.write for the hidden textarea - and for the hidden form field I've added to RSH for Safari support.

UPDATE: As it turns out, it's immaterial whether you use DOM methods or document.write. The important thing is to use either method before onload fires. I ended up using document.write in the 0.6 beta because of SSH concerns and the fact that it's so much more concise. For more on this topic, see this subsequent post. 

Because of the way RSH is structured, these elements actually get written to the head rather than the body of your document. Still, it works, and it should only offend the most anal-retentive of standards geeks. After all, if you're hacking the browser 10 different ways from Sunday just to enable Ajax bookmarking, then inserting a bit of non-validating markup via JavaScript is hardly the worst of your sins.

RSH won't be hitching its wagon to [insert name of your favorite framework here]

A few users suggested rewriting RSH in Prototype so it would be more compact. I appreciate the impulse, but I think that defeats one of RSH's chief virtues: the fact that it's written in Plain Old JavaScript and doesn't lock you into any specific Ajax framework. It plays well with any library you want it to: Prototype, jQuery, YUI, whatever. (If it doesn't, please file a bug so I can find out why.)

A little JSON never hurt anyone

The one library that RSH does require is a JSON parser; it ships with the latest open-source version. RSH 0.4 included an earlier version of the parser in the same file as its native code; I've broken it into a separate file under the logic that many users will already be serving a similar library. RSH's methods don't actually call toJSONString or parseJSON directly; instead, I've provided bridges so that you can hack in your own JSON methods without having to modify the guts of RSH itself.

Future roadmap

I've got quite a punch list for the next release:

  • Provide minified versions of RSH and JSON for download
  • Make use of Crockford's module pattern for better encapsulation
  • Add official support for Linux browsers, Safari 3/Mac and Safari 3/Win

That's the future. For now, I have to get 0.6 packaged up and ready for testing. Check Google Code late this evening or first thing tomorrow.

Technorati Tags

Echo3 Update: SVN, Wiki, Forms, Builds

Echo3 is showing a few more signs of life. Since my update last month on some early details of Echo3, the pace has picked up. No alpha release, but already there are two forums, one especially for folks looking to contribute to Echo3 development. Also, a few other things worth mentioning about Echo3:

  • The SVN repository can be found at svn://svn.nextapp.com/echo3/trunk (Echo3Extras are at svn://svn.nextapp.com/echo3extras/trunk).
  • If you just want the binaries (or binaries with source), the Echo3Go project is handy.
  • Initial performance numbers of Echo2 vs Echo3 show a more than 2x improvement in performance.

Further, a more detailed description of the new features, design principles and ideas behind Echo3 can be found on the wiki. Two items that are especially interesting for those looking to write their own components:

  • Automatic Serialization: Data objects sent between client and server can be automatically serialized between Java, XML, and JavaScript. The serialization architecture is extensible--serialization code for new object types may be added by the developer.
  • Simplified Client/Server Synchronization Peers: Serializing components and commands between client and server is performed automatically using the built-in serialization architecture. The component developer only need specify which properties should be sent (for components, all local style properties are automatically sent).

Serializing and deserializing data between client and server can be one of the more timeconsuming and error prone parts of developing Ajax apps. Packaging this into the framework with improve productivity at the very least. Technorati Tags: , ,

GWT Wrapper for Rialto

Supplementing GWT's basic set of widgets with wrappers around those of existing widget frameworks has become a bit of a cottage industry. There are wrappers for Scriptaculous, JsGraphics, TinyMCE (see the GWT Widget Library for these), Ext Js and many more. Now add Rialto to that list. (For a demo of the Rialto widgets, such as the interesting GridTreeView, see here.)



One shortcoming of Rialto's GWT wrapper, however, is that all of the widgets are subclasses of JavaScriptObject rather than Widget. A best practice that has emerged for wrapping other frameworks is to wrap a Widget adapter around a JavaScriptObject so that the wrapped framework's widgets can play nice and integrate with other existing GWT widgets. The Rialto wrapper doesn't do that and also implements a parallel set of event, clicklistener and other classes. This shortcoming needs to be resolved in order for this particular framework wrapping to be useful.

Technorati Tags: , ,

Tibco GI/Craigs List Bashup

Over at Ajaxian you can read about a pretty cool remix of Craig's List, somewhat similar to what I've been working on with GWT. I've termed this a "bashup," rather than a "mashup," because it kind of mashes things up against one or more of the participants wills. Now, whereas my solution will be injected into the site's page via a bookmarklet, this mashup proxies Craig's List through it's local server. I'm pretty sure that violates Craig's List's TOU (see article 12, ACCESS TO THE SERVICE).

Technorati Tags: , , ,

The painful art of prognostication

They say science fiction is rarely actually about the future; it's really an exploration of present-day fears and anxieties, interrogated through a metaphor of the future. William Gibson himself - the father of cyberpunk - has given up the future in favor of exploring our technological present in compelling novels such as Pattern Recognition and the brand-new Spook Country.

I couldn't help but think about science fiction when I read this "strategy letter" by Joel Spolsky of "Joel on Software" fame. Spolsky looks at a number of current trends in the Ajax world, draws parallels between them and the original emergence of desktop computing, and concludes that the future looks a lot like Windows. In Spolsky's vision, one or two powerful Ajax toolkits will become the de facto new platform/operating system for the next era of application development.

I cry bullshit not because Spolsky's discussion is illogical or ill-informed, but because it's presented with such certitude. If my time in the blog echo chamber has taught me anything, it's that the guy who seems most sure of himself is probably the one blowing the most hot air. Folks have an insatiable appetite for strong opinions, repeated loudly. Everybody wants to know what the future will bring. But the best most commentators can hope for is to surf the currents of the present and catch of peek at what's beyond the next wave. Extrapolating a bunch of disparate trends 5 or 10 years into the future is just an exercise in rhetorical prowess. Joel's a great storyteller, but like most storytellers he's primarily interested in spinning a great yarn. By all means give his theories a whirl, but don't expect capital-T Truth. Nobody can tell the future. To believe otherwise is science fiction.

1984 is a powerful book precisely because Orwell didn't have to make a lot of shit up. He had Nazi Germany and the Soviet Union under Stalin as models for what he was doing. He only had to dress it up a little bit, sort of pile it up in a certain way to say, "this is the future." But the reason it's powerful is that it resonates of history. It doesn't resonate back from the future, it resonates out of modern history. And the power with which it resonates is directly contingent on the sort of point-for-point mimesis, like sort of point-for-point realism, in terms of what we know happened.

--William Gibson, via Boing Boing

ZK 3.0 RC Released

One of the enduring criticisms of ZK, the server-side Ajax framework, has been against its perceived slow performance. Critics have observed, and supporters have conceded, that applications written with ZK seem a touch slow. So it's no surprise that a major focus of the latest major release has been improved performance. The ZK team found two major bottlenecks in performance testing:

After a series of stress test and reviewing the kernel code, we found out 2 bottlenecks on ZK 2.4.1 and fixed them in ZK 3.0 RC.

  1. The executing time is too expensive when rendering components. ZK uses templates to render components, and the EL is generally used in templates to simplify the variable access and templete maintenance. However, when the concurrent access rises to a large number, the overhead on rendering component with EL is too heavy.

  2. Threads spend too much time on waiting the synchronization when many threads access to the same cache under current cache mechanism.

ZK 3.0 RC solves these 2 bottlenecks by using the renderer class and new cache mechanism. The test result shows ZK 3.0 RC is four ~ five times faster than ZK 2.4.1.

I haven't validated these performance figures myself, but an initial comparison between some demo applications confirms a much more responsive user experience.

ZK 3.0 RC has also added a number of other new features:

  • Server push is enabled which allows you to update client’s information actively and the usage is simple and intuitive.
  • Add forward property of components to forward event without programming.
  • New expression of annotation is ease of use, and easy-to-read.
  • TreeModel is introduced which simplifies the job of Tree rendering.
  • Flash components allow you to play audio and video files. (including youtube clip)
  • Native namespace is implemented to speed up the performance while integration with HTML.
  • To speed up the performance of ZK, EL evaluator is pluggable, and a new way to render ZK components is introduced.
  • More integration with other frameworks, ZK has integrated with JSF, JSP, and Ext-JS.

Server push was already supported in ZK through use of the timer component, but the enhancements make it even easier (note: we're not talking comet, but rather client polling). Even more exciting for me is the dynamic loading of ZUML (the XML-based markup language for specifying ZK interfaces) pages dynamically from sources such as a database. That's very helpful if you want to allow non-developers to deploy interface changes without having to spit out ear or war files.

As usual, the ZK folks have done a good job documenting the changes and additions. It's too early to tell if 3.0 will solve all of ZK's previous shortcomings, but ZK is well on it's way to becoming my favorite server-side framework.

Technorati Tags: , ,

jQuery 1.2: A host of upgrades, but still no global effects queue

JQuery 1.2 is upon us and, as usual, there's already tons of carping discussion in the comments section of Ajaxian. I took a wander through the 1.2 release notes and the source code, and while I'm impressed with many of the new features, I'm a little disappointed with status quo of the Effects object. They've updated the queue and dequeue methods and made them public,  but effects queues continue to be maintained separately for each element. This was a real stumbling block for me when I took jQuery for a test drive on a demo project last month. Compared to Script.aculo.us's global effects queue, jQuery's element-by-element queues provide far less precise control for combinations of effects on disparate nodes. It's difficult to coordinate the timing of effects when you want, for instance, to pause the processing of all effects globally in response to an event, then restart some or all of them. The queue and dequeue upgrades are a step in the right direction, but I'd love to see a truly global effects queue that can be sliced and diced into named or el