Fighting AJAX’s Enemy: Legacy HTML Forms

August 08, 2005 @ 10:08 pm

1 Comment

Many designers have jumped on the AJAX/Javascript/Shiny bandwagon, developing interactive-this or on-the-fly-that, but nobody has stopped to address AJAX from a very common business standpoint. It's not always feasible to convert everything at once, nor is it always possible to work in a world of non tabular layouts. This is one designer's story

The Problem

Gaia Online just recently distributed its 400-million posts across several databases, and upgraded the posting engine from phpbb's post system to a Circuit MVC(72squared: post on the Circuit Model View Controller) Architecture developed by 72Squared. With the system using this new lightweight design, the next step was to add the [feature" part of the posting system: post types.

For those not overly familiar with Gaia, the avatars are presented with small speech bubbles "example(Gaia Online Thread Example) that make it seem like they are saying things on the page. This is a step beyond the conventional forum in many stylistic ways. When the posts were migrated from the old phpbb format to the new style, a field was reserved for assigning a type to the posts. This [type" field would allow for the user to change the style of their post, letting them change out the speech bubble for a think bubble, a shouting box, a whisper, or a document style post.

Not content with simple border decoration, however, additional "compound" types were added. These types allowed a user to roll dice, generate random numbers, display items from their inventory, and create "photos" of themselves and their friends avatars. It was in these compound post types (most notably friends and inventory) that created the problem. There was no reason to access a user's inventory or their friendslist if they were not going to use them- this data had to be called on demand. For that matter, that "subform" had to be called on demand to reduce page weight. Finally, it didn't make sense to reload the entire page just to swap out a piece of a form. I had heard about the XMLHTTPRequest Object in Javascript back when Google Maps and GMail were released. Enter the Google.

Where to Learn About AJAX

AJAX isn't called AJAX by everyone, I may as well be upfront about that. Depending on who you ask, it will be given a ton of terms. I actually made a choice to adopt the term AJAX not because it was trendy, but because when namespacing PHP files to handle requests, ajaxfilename looked much nicer than javascriptresponse_filename. There was honestly no other logic behind it. Knowing nothing about AJAX though, I went to Doug Bowman's site, because I distinctly remembered something about Javascript. That took me to "Adaptive Path's Article on AJAX(Adaptive Path)](http://www.adaptivepath.com/publications/essays/archives/000385.php.) Armed with at least a concept of what I could achieve, I went to Wikipedia's Article on AJAX(Wikipedia: AJAX)

And with that, I hit the ground running.

What Do You Do With the AJAX Response?

If you've followed any of the AJAX examples out on the internet, you'll find that you will have a response object. This response object is (hopefully) well-formed XML. In the case of the post types, I chose to use the posting MVC application to handle the AJAX request, and use a view to create the XHTML form components. I could have just as easily created Javascript Code to eval() or created a full XML response and had the client parse it, adding nodes to the tree as needed. This is where the legacy form system rears its ugly head.

It's worth saying right now that Gaia Online (at the time of this writing) does not validate. Come to think of it, many sites on the internet fail validation tests; though often times the code is the result of a rapid development cycle (working first) approach. Therefore, trying to access the DOM in an even semi-logical way for using appendChild() became a very tedious process. Processing the XML into form elements actually became worse on items such as inventory and friendslists, where the client was left to interpret XML data structures of more than 500 elements at a time. So, with direct DOM manipulation gone, and client side XML interpretation becoming a bad idea, I was forced to turn to innerHTML. A quick look at the W3C DOM Chart(quirksmode.org) put any fears aside. While not a w3 standard, every major browser has put in support for it because of it's usefulness. After using it, I'm not one to object either. So, that takes care of the really large forms being called on the fly. I hit the submit button, looked at $_POST and saw what would become the headache of legacy forms:

array(1) {"submit"=>"test this form"}

So where did the form elements go? They were there, getElementById() worked on them, and yet, nothing happened. Apparently, I'm not the only person in the world this has happened to though. It would seem that most forms which use AJAX also submit their data via AJAX (using POST). Converting poll options and preview settings over to AJAX would have added quite a bit of time to the development, and so a solution needed to be had.

Wedding AJAX to a Legacy Form

getElementsByTagName(string) is a method that returns all elements of a name specified by "string". This means you could get all input tags, all select tags, or any other form element you need. Because it is a method applied to an HTML element, you can use getElementById("id").getElementsByTagName("name"). Once you pull out the AJAX generated form elements, you can store that data in a textarea (in a non AJAX region) to be picked up by the script. For this, I used a function called processSubform() which stored the results as an XML string to submit. It works by capturing all elements with a "name" attribute assigned to them, and uses that name for the XML pairing.

On the server side, there is a bit of PHP magic required to map these values back to PHP key/value pairs.

This will leave you with $ajaxData, which is a multi-dimensional array of data. Multiple submissions with the same form name are stacked in the array, and as an added bonus, the ajax-speciffic submission is independant of $_POST, which should help prevent collisions with the legacy form. An additionally nice security measure is put in place as broken XML will simply cause rouge variables inside of $ajaxData, and you cannot overwrite $_POST. It is strongly reccomended to perform full validation on $ajaxData just like any other user-submitted form data.

Limitations

Hands down, the largest limitation to this method is the inefficiency of having to store the AJAX generated form data in a second location. This adds weight to the javascript, and adds a small amount of weight to the PHP side. This drawback is offset by a compatible method of capturing form data that will remain compatible with a legacy system. Because of the support for getElementById and getElementsByTagName, the form capturing process will remain the same.

Wrapping Up, Looking Forward

Building a dynamic element in a form can be tricky when the solution was not originally built with AJAX style development in mind. When submitting the form via Javascript fails, and $_POST seems empty with innerHTML, this might just be the solution you need. If anyone has found other ways of changing out the "middle" of a form, I'd love to hear them.

Note for Gaia users: There is still some artwork being developed. When the feature is announced, it will be in the announcement forum. =]

In response to "Fighting AJAX’s Enemy: Legacy HTML Forms":

  1. Chino
    August 11, 2005 at 10:08 pm

    The dice rolling still sounds as awesome as it did before. I’m gunna roll one all the time. XD Hmm… all the other stuff sounds too confusing for me. >_> Possibly I will learn someday. XD Sounds like you have a lot of work though so best of luck. :3

Leave a Reply:

Commenting is not available in this section entry.