html

Cosying up to the client-side

July 23, 2004 22:48:04.081

I'm far from a Javascript wizard, and typically applications I build use as little of it as possible. But there's been a lot of buzz recently about the new breed of "rich" web UIs: the snappy navigation in GMail, Yahoo's subsequent purchase of Oddpost, IBM buying Alphablox (these guys built a spreadsheet in DHTML?), and so on. On a smaller scale, nice touches like autocompleting search fields are starting to pop up in blogs and online documentation everywhere. All of these rely in part on a particular Javascript trick: reacting to user input by making a background request to the webserver and selectively updating the current page from the data in the response, rather than doing a full redraw of the browser window. Traditionally, this has required nasty games with iframes, but recently browser support has gotten much better: the three browsers I care most about (Safari, Mozilla, and IE, in that order), all now support XMLHttpRequest, which makes doing an asynchronous HTTP GET from within a Javascript event handler pretty trivial.

So, much as I generally shun client-side scripts, I've been admittedly intrigued by how I might be able to leverage these techniques from within Seaside. What's the right generalization of all the various live update hacks out there? If I'm going to be doing Javascript, I want to do it once, do it right, and then build the right abstractions in Seaside to let me forget about it.

What I came up with does indeed work nicely for Seaside, but it might also be more universally useful. For the first and likely the last time, I'm posting some sample Javascript code for people to use. Do what you like with it; if you improve it in any way, feel free to email me your new version. It provides the function liveUpdater(), which takes as its only parameter a URI-generating function uriFunc. liveUpdater() returns a new function, suitable for attaching, for example, to the onclick handler of a link. This handler function does this:

  • Generate a new URI with the provided uriFunc
  • Make an HTTP GET request to that URI
  • Extract from the response the first element that has an id attribute
  • Replace the contents of the element with the corresponding id in the current document, with the contents of the element extracted from the new response
What this means, effectively, is that invoking this handler makes a request in the background, which the webserver can respond to by returning a new version of any part of the current page that it likes. That part of the page gets swapped out seamlessly for the new version. The thing I like about this is that it gives all the power to the server side: only after having processed the request does the decision have to be made about what parts of the page are affected and need to be redrawn, and those parts can be sent back to the client.

To round things off (and borrowing inspiration and approach from Jeff Minard), I also provide a higher level function called liveSearch(), which hooks a handler to a text input to trigger continuous liveUpdates as the user enters text. Both liveUpdater() and liveSearch() are supported with a nice clean API in the bleeding edge version of Seaside, available here. See the WALiveRequestTest class for example usage.

Comments

Bringing the server and clients sides closer together

[Harry Fuecks] July 24, 2004 8:07:17.706

Now XMLHttpRequest is supported in Mozilla, Safari and IE, Javascript is suddenly very interesting but think a big issue with Javascript is it's always been seen as something you develop seperately from what happens on the server side. From a more practical perspective, I'm nervous about writing something in Javascript that will be broken the moment things change on the server side.

Think if strategies can be worked out that make what you express on the server side is reflected on the client side (i.e. generate Javascript based on server side declarations), building rich clients can become alot easier.

Have been playing with something like that here: InputAutoCompleteTag (autocompletion is happening purely client side in that example). From the point of view of development, using this example requires zero Javascript coding. You specify a "magic tag" in the template here then attach information to it programmatically here

Support for multiple updates

[Ivan Toshkov] July 26, 2004 6:21:15.906

Perhaps it'll make sense (and it looks trivial enough to implement) to support updating multiple parts of the page with a singe XMLHttpRequest.

Maintaining Javascript

[Avi Bryant] July 27, 2004 22:59:20.593

Harry,

I completely agree - that's what I mean by "getting it right and forgetting about it". I have no desire to be writing custom pieces of Javascript all the time, but having a few generic facilities that I can reuse with a single function call (like liveUpdater) can really help.

Ivan, yes, updating more than one element at once would probably be pretty easy. I'll add that when I next have time to play with this stuff.

Borges implementation

[Leslie Hensley] July 28, 2004 0:43:51.108

I pounded out a quick Borges implementation by beating on Avi's code with a hammer until it ran under ruby. I've never had the stomach for lots of javascript programming, but this technique has to potential have all of web apps that I write packed with javascript (with minimal extra effort on my part). This has just scratched the surface of what can be done and I'm very excited to see what the future holds.

Dynamic auto-updating web pages with XMLHttpRequest

[Duane's Interminable Ramblings] August 4, 2004 6:30:24.910

Trackback from Duane's Interminable Ramblings

Dynamic auto-updating web pages with XMLHttpRequest

I've been doing a bit of web-based application coding recently, and a lot of fun it is too. One of the things I need to do is continually update simulation results on a page. Now in general this is not something that web-based applications are very good at, HTTP being mostly a client-pull technology. So, what are the options? The simplest way is just to add something like <meta http-equiv="refresh" content="3">, but that has a number of problems. First, it looks ugly. The reloads are very intrusive and the whole page is replaced in a distracting and cumbersome manner. The problem is especially acute if the page has scrollbars. This method also requires the entire page contents to be sent......

Very useful indeed

[Duane] August 4, 2004 6:39:47.694

Great stuff! I need to auto-update a page with new results as they came in, and by following your example and the links here I've got exactly what I want. I'm using setInterval to periodically update a page and have hacked up your script to meet my needs.

Google is the New Netscape

[phobia.com] September 24, 2004 21:58:01.486

Trackback from phobia.com

Google is the New Netscape

...