Archive for August, 2006

JSF and Ajax: ajax4jsf

Assuming that the component model of JSF is pretty well suited for Ajax applications, I found it surprisingly hard to find an Ajax framework that

  • has native support for JSF and the JSF lifecycle (unlike generic frameworks like AjaxAnywhere),
  • requires no custom Javascript coding for basic event/update mechanisms, and that
  • supports existing components unaware of Ajax.

There is a proof-of-concept implementation of a very JSF-centric approach proposed by Jacob Hokoom that fully utilizes the JSF component tree in the jsf-extensions project. Very promising, but it seems to be in a very early stage and requires JSF RI 1.2.

An existing alternative is Ajax4jsf, a rather mature and capable Ajax filter created and maintained by the Exadel people. Usage is fool-proof: using the a4j tag library, you either attach Ajax behavior to Javascript events (e.g. onchange) of existing input elements, or you add command buttons that emit Ajax calls when clicked, instead of reloading the whole page. When an Ajax event occurs, the form surrounding the element is submitted, making server-side handling identical to that of a common post-back. Ajax4jsf tags accept a list of component IDs to be re-rendered when the Ajax call was processed, automagically updating independent regions of the page. You don’t even have to identify those regions manually, for example, if a datatable should be updated – pass its ID to a4j and it will be updated when the server response arrives.

My only gripe so far is performance – by default, every request is routed through a Tidy filter, even for non-Ajax pages. This can be disabled by setting the forceparser init parameter to false (in the web.xml filter definition), which will only tidy up Ajax responses.

Oh, and if you’re using Facelets: read the docs ;). Remove the Facelets view handler from your faces-config.xml and set the org.ajax4jsf.VIEW_HANDLERS context parameter in the web.xml instead.

Besides possible performance concerns, I believe ajax4jsf’s interface is pretty much perfect for ajaxifying JSF applications without special needs – that is, wiring client-side events to JSF beans and rendering partial updates of a page. I’m all for simple, straight-forward solutions that just work – which is also the reason I was slightly disappointed of Pro JSF and Ajax with its clumsy (but surely more flexible) mabon. I guess I just don’t want to write more client-side Javascript than absolutely necessary for a pleasing user experience.

Advertisements

Comments (5)

New in JavaScript 1.7

Over the last two years or so, JavaScript got a lot of attention due to the surge of client-side scripting. It turned out that a few tweaks to a previously rather dull-looking, but dynamic language made JavaScript much more attractive, adding (or promoting) concepts like object orientation, function pointers and extension of built-in types.

The success of the Mozilla project probably made a difference, since it provides free and standards-compliant implementations of JavaScript and DOM, making dynamic webapps much less of a hassle than they used to be. Recent builds include support for JavaScript 1.7, and the Mozilla developer center lists some quite interesting additions to the language. Most of them seem pretty familiar to Python or Ruby programmers, but it’s nice to have these features available on web browsers as well. Some of the features are:

  • Generator support: anything generating a list of objects is much nicer to implement using generators if you don’t want to return the whole result at once.
    function x() {
      var i = 0;
      while (true) {
        yield i++;
      }
    }

    yields any number of consecutive numbers that can be consumed via .next():

    var gen = x();
    for (var i = 0; i < 100; i++) {
      document.write(gen.next() + " ");
    }

    produces 100 consecutive numbers – without resorting to arrays for intermediate storage or callbacks.

  • Iterators provide a cleaner solution of the “for…in” construct that breaks when a library like prototype.js adds custom properties to built-in types.
  • Array comprehensions, a favourite Python construct of mine, have been added. They come in handy for generating arrays or projecting objects to arrays. For example, you could write
    var evens = [i for (i in range(0, 21)) if (i % 2 == 0)];

    where range(x, y) is a generator function. I guess it would be easy to provide a generator iterating over an array of objects, allowing to write something like

    var ids = [obj.ids for (obj in iterate(objects))];
  • More functional-style programming using let. Probably the biggest improvement for fans of functional programming, though I’m not exactly sure how useful this turns out to be.
  • Multiple-value returns reduces boilerplate code when a tuple instead of a single value is returned from a function. So it’s possible to write
    function x() {
      return [1,2]
    }
    
    [a, b] = x();

Of course, the real question is when and if the other browser vendors adopt JS 1.7 (or even 1.5) – until then, it’s probably most interesting for Firefox plugin developers.

Leave a Comment