[Catalyst] sane AJAX strategy

Bill Moseley moseley at hank.org
Sat Jan 6 14:19:25 GMT 2007


On Fri, Jan 05, 2007 at 12:24:37PM +0100, Daniel McBrearty wrote:
> I just started using AJAX (or AHAH actually ... ) a little. I like the
> lightness it gives but I've been slow to pick up because I want to be
> sure that pages work without js, and I haven't figured out a generic
> method yet. I'm sure others are ahead of me on this ...
> 
> Typical scenario without AJAX :
> 
> form button submits to URL, which triggers a single Cat action, which
> is rendered by a single template, usually of the same name.
> 
> That's simple, just a one-to-one relationship.
> 
> When we use AJAX, things look very similar, EXCEPT that only a part of
> a page is loaded.
> 
> This implies that for the non-js user of the same page, multiple
> actions and templates have been combined so that the result is
> identical, even though the whole page loaded.

When you say above only part of a page is loaded are you talking about
the content part and not the headers, footers, and menus -- or talking
about part of the content such as just a new row in a table or
updating a single field in a form?

Not sure exactly what you are asking for, but I'll explain what I do
if that helps -- and besides I'm no fan of being warnocked.

I don't use that much AJAX, but I do use it for, say, displaying the
next page of a list or sorting a table by a column by clicking on a
column heading, or selecting a different "tab" to limit a table's
display to a category of some type.

My templates are already split up quite a bit.  So, I have templates
that know how to display tabs, table column headings, and how to build
the table.

When I update a table (e.g. "next page") the same controller code is
called for both AJAX and for non-ajax requests (it's the same request
url) and the same template is called (derived from the controller's
action name).

I use the typical TT wrapper method to build my entire page from
headers, footers, banners, menus, etc.  But, the TT wrapper code can
detect it's an AJAX request from the request headers and knows to only
build the content (i.e. the table with data I'm sorting), but not the
entire page.  Then my "end" action also knows it's an ajax request and
then returns using JSON.

Since I use common template code for generating tabs and table headers
and use the same urls for my ajax requests it's easy for javascript to
search the DOM and create the events for the ajax requests.  That way
my HTML markup doesn't have to do anything specific for the ajax
calls.  That's the commonly recommended method, of course, keeping the
behavior and html separate.

For AJAX requests that don't update the entire page content, like an
auto-complete search box, I still use the same controller as for the
non-ajax request but then the controller has a little extra code to
return just the search results not the entire new content -- it's just
one extra line of code in most cases.  Not always the most efficient
method (since I end up returning more columns than is really needed for
the ajax update), but so far has not been an problem.

Of course, for updating a single field in a form (e.g. type in a zip
code and city and state are automatically filled in) I use a separate
controller that just handles the ajax code.  In that case there's no
need for an extra template since it's just updating existing markup --
the controller just returns JSON.

So, I try to write as much as possible without coding specifics for
the ajax calls.  It's the standard recommendation to write the code
for non-ajax usage, then add that behavior on page load.  And, then I
divide my templates into small enough parts that can be used for ajax
and non-ajax calls based on how the request comes in.

-- 
Bill Moseley
moseley at hank.org




More information about the Catalyst mailing list