The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

emdeboas (7) [Avatar] Offline
#1
Back to chapters 3 and 4 again!

In chapters 3 and 4 two methods of web-application development are contrasted: a ontent-centric and a data-centric approach. In the content-centric approach, the server generates the HTML-fragments that are put into place by some JavaScript functions in response to an Ajax request. With the data-centric approach, only data is sent across, either using XML or using JSON as the transport data-structure.

The data-centric approach is not easy to use, because the server has to encode the data into XML or JSON, the client has to decode the data and then manipulate the DOM to make the data visible. This is counter-productive, because most server-side scripting languages are much better at rendering HTML than JavaScript is, while encoding and decoding the data to send it across from server to client seems rather redundant.

The one major disadvantage stated in the book for using the content-centric approach is the problem of updating multiple DOM nodes as the result of one Ajax request.

There are some aspects I would like to add here:
For both approaches there is a fair amount of very application specific JavaScript code that has to be written. Both the client and the server code have to contain knowledge about the structure and user-interaction of the application. This is a very undesirable situation, especially when larger development teams are involved. As before the Ajax era, I would like to use JavaScript only to trigger some actions, to show some effects, and maybe do some preliminary data validation.

Inspired by the data-centric approaches described in the book I was wondering whether it would be possible to have the best of both approaches: content-centric HTML generation, and the structure and flexibility of a data-centric approach.

Would I Be Not Nice ifÂ… I could send an Ajax response for the quick-gallery application along those lines:

<ajax-response>
<response-element target='title' place='replacechildren'>
<![CDATA[ ... the breadcrumbs go here ... ]]>
</response-element>
<response-element target='folders' place='replacechildren'>
<![CDATA[ ... folders go here ... ]]>
</response-element>
<response-element target='images' place='replacechildren'>
<![CDATA[ ... images go here ... ]]>
</response-element>
</ajax-response>

As you see, there are several segments, each targeting a specific DOM element and each specifying where the changes should be applied with respect to this DOM element. In the gallery application we only use "replacechildren". Other options could be "top", "bottom" etc. It is not only nice, but really easy to do also. The JavaScript follows shortly. I have named this the "process-centric" approach, for the time being.

A word of caution first: there are several frameworks which have a similar approach, for example Taconite, or Backbase. The drawback of both of these is that you have to send valid XHTML from the server. In my approach CDATA sections are used for the HTML fragments, which allows you to send any HTML, as long as the browser can render it. If you are trying to display data from a sloppy RSS feed that may be a genuine advantage.

Here is the code:

function ajaxLoad(path){
new Ajax.Request(
path,
{
method: "GET",
onSuccess: parseAjaxResponse,
evalScripts: true
} );
}

function parseAjaxResponse(transport){
var response=transport.responseXML;
var response_elements = response.getElementsByTagName('response-element');
var rels = $A(response_elements);
rels.each(function(node) {
var dest = node.attributes.getNamedItem("target").value;
var place = node.attributes.getNamedItem("place").value;
parseChildNodes(node, dest, place);
});
}

function parseChildNodes(node, dest, place){
var child = node.firstChild;
switch (place) {
case "replacechildren" :
if (child.data != '') {
// use update instead of innerHTML to allow scripts to be evaluaed
Element.update(dest, child.data);
// $(dest).innerHTML=child.data;
Element.show(dest);
}
else Element.hide($(dest));
break;
case "top" :
if (child.data != '') {
new Insertion.Top(dest, child.data);
Element.show(dest);
}
else Element.hide(dest);
break;
case "before" :
if (child.data != '') {
new Insertion.Before(dest, child.data);
Element.show(dest);
}
break;
case "bottom" :
if (child.data != '') {
new Insertion.Bottom(dest, child.data);
Element.show(dest);
}
else Element.hide(dest);
break;
default :
window.alert(place + " is not a supported placement value");
}
}


As you see, these 60 or so lines of JavaScript are as reusable as Prototype itself, and most of the specific JavaScript is gone. The server side is almost as easy to develop as the application without Ajax would have been. I recoded the quick-gallery application using this.

You can see it in action at:
http://www.bronstee.com/quickgallery/quickgallery-xml/images_xmlcentric.html

Since, I am using this to great advantage in a much larger project. Of course it would be
nice to expand the JavaScript a bit to handle POST data and to do some error checking. "Real" JavaScript programmers could probably write nicer and shorter code too.

Cheers, Ghica
davecrane (149) [Avatar] Offline
#2
Re: Process-centric Ajax
Hi Ghica,

This looks very interesting - at first, I thought 'aha - looks like Rico.AjaxEngine', but then I saw your comments about sloppy HTML, that's a nice touch.

I'm always humbled when somebody picks up the stuff that I've written and reworks it. Thank you for your interest in our stuff, and for taking the time to share it in the forums.

I've been up late fixing images for production for the book, sdo I won't say any more right now, as it probably won't make much sense, but I'll take the time to look over your demo code soon.

Best regards,

Dave
emdeboas (7) [Avatar] Offline
#3
Re: Process-centric Ajax
Hi Dave,
I had heard about Rico, but not about the Ajax Engine. How original are the names of the tags that I chose! smilie
As I understand, this is another one of those where you need to send XHTML and where you need XSLT or another bulky engine to interpret the Ajax response.

On the other hand, what I did is just a slight variation of your XML-data centric approach, where the data is actually the HTML content. It only needs the Prototype Insertion object (or just the Element object, depending on where you want to put the response) and Ajax.request of course. This results in a very lightweight Ajax Engine and because of the CDATA trick (something you cannot do so easily in JSON I believe) you have the flexibility of being able to handle external sources where you have no control over the generation of neat HTML, like in a portal.

It fixes also what is missing in your book in chapters 3 and 4: a way to let the server control the Ajax application and do what it is good at (PHP at least): generating HTML. That is why I appended this in the first place.

Thanks for reading my comments. Cheers, Ghica.
davecrane (149) [Avatar] Offline
#4
Re: Process-centric Ajax
Hi Ghica,

> I had heard about Rico, but not about the Ajax
> Engine. How original are the names of the tags that I
> chose! smilie

There's a lot of reinvention going on in Ajax - only so many ways to solve the problem, I guess.

> As I understand, this is another one of those where
> you need to send XHTML and where you need XSLT or
> another bulky engine to interpret the Ajax response.
>
Not necessarily. Rico allows mixed content-centric anddata-centric. If you specify an element type response, it just uses innerHTML to stitch the XHTML in for you. But with an object type response, then yes, you do need to parse the XML by hand using DOM or XPath. And in other ways, Rico.AjaxEngine is'heavy' IMHO - everything needs to be registered beforehand.

>
> On the other hand, what I did is just a slight
> variation of your XML-data centric approach, where
> the data is actually the HTML content.

I'd probably call this more of a content-centric approach, as the server is controlling the look of the page, and therefore the workflow. But it has data-centric elements to it too.

> It fixes also what is missing in your book in
> chapters 3 and 4: a way to let the server control the
> Ajax application and do what it is good at (PHP at
> least): generating HTML. That is why I appended this
> in the first place.

Much appreciated smilie I had thought about putting some reference to Rico's solution, but the chapterswere getting big enough as it was. Prototype hasn't (yet) come up with a solution that adopts this approach, and the main aim of the book is to cover Prototype and Scriptaculous (yeah, a bit of an artificial straightjacket, but I have to stop writing at some point!!). But these discussions sparked off by the book are immensely valuable.

Regards,

Dave