rob cherny.com

About

My name is Rob Cherny and I'm a professional Web Developer with 16 years of experience creating Web sites and Web-based applications. This site is where I write about my work, and random other things...

Learn More

Loading...

Close Tab

Web Development

Accessible Ajax, A Basic Hijax Example

After posting my article, "Ajax and Accessibility: You're Doing it Wrong (Hijax)", Jeremy Keith, the fellow who coined the term, actually posted asking about working examples. Well, I didn't have any that I could share off hand, but I posted a few things which were in the same spirit of working Accessible Ajax, or Hijax. Thinking about it more, I figured, well, it's pretty easy, I'll just slap together a sample. So away we go...

A Basic, Standard and Accessible Form

You'll need to start with a basic, traditional form process which will work without JavaScript enabled. So here we've got your average sample form with a post against a PHP script called "post.php".

  1. <form action="post.php" method="post">
  2. <p>
  3. <label for="username">Your Name:</label>
  4. <input type="text" id="username" name="username" />
  5. </p>
  6. <p>
  7. <label for="country">Country:</label>
  8. <input type="text" id="country" name="country" />
  9. </p>
  10. <p><input type="submit" /></p>
  11. </form>

And, the PHP script (for brevity I'm dropping DocTypes, etc., but you should always use them):

  1. <?php
  2. $results = $_POST['username'];
  3. $results .= " is from ";
  4. $results .= .$_POST['country'];
  5. ?>
  6. <html>
  7. <head>
  8.         <title>Accessible Ajax Form Test.</title>
  9. </head>
  10. <body>
  11. <p>Here is my post --
  12. <?php
  13. echo $results;
  14. ?>
  15. </p>
  16. </body>
  17. </html>

So right away you can see this is pretty basic, it simply echos out what was entered into the form field, but that's all you need to demo the technique. You can see we've started with something that might be a standard form.

Add Some Ajax and Hijack Your Script

You'll need to add some JavaScript. You'll need to decide if you want to use a Ajax library that might be out there, or if you're going to code your own.

Since this article isn't really intended to show how to append Ajax to a form, rather how unobtrusive scripting can applied to enhance a form using Ajax, I'm not going to go on at length about Ajax, rather just use my own Ajax Object script, as it works fairly well for this sort of thing.

I'm not going to get all fancy with event handlers either, just get the point out the door. The basic steps are:

  1. Modify the PHP script to process two ways, one with Ajax, one without
  2. Determine if the browser supports Ajax
  3. Override the form's onSubmit handler
  4. onSubmit, collect and format the form data into a query
  5. POST the data via your Ajax script
  6. Output the data received
  7. Return false so the form is not submitted normally

Modify Your Server-Side Script

Essentially, we're going to run the same script both ways, and only slightly differently if there's an additional parameter called "ajax" passed up to the PHP.

  1. <?php
  2. $results = $_POST['username'];
  3. $results .= " is from ";
  4. $results .= .$_POST['country'];
  5. if (!isset($_POST['ajax'])) {
  6. ?>
  7. <html
  8. <head>
  9.         <title>Accessible Ajax Form Test.</title>
  10. </head>
  11. <body>
  12. <?php
  13. }
  14. ?>
  15. <p>Here is my post --
  16. <?php
  17. echo $results;
  18. ?>
  19. </p>
  20. <?php
  21. if (!isset($_POST['ajax'])) {
  22. ?>
  23. </body>
  24. </html>
  25. <?php
  26. }
  27. ?>

You can see we've wrapped the HTML body portions of the page within two "if" statements, checking for the "not" existance of the "ajax" Post Variable, with the function ISSET(). First, for the page HEAD and opening BODY tags, then, second for the closing BODY and HTML tags.

Detect Support and Override Your Form

Back to the form. When the browser loads the form, onload you'll need to detect the support given for the XMLHttpRequest objects that power Ajax. With my Ajax Object (AO) script, that's as easy as creating a new AO object, and checking the AO.init property to be set to true.

  1. window.onload = function(){
  2.   var bSupport = new AO();
  3.   if (bSupport.init) { // test for support of Ajax
  4.   setQuery(); // override form
  5.   bSupport = null; // remove test object
  6.  }
  7.  else return false;
  8. }

There's several things to look at here. First, if there is browser support, you're going to run a function which is going to override the form submission. Here, we're also resetting the bSupport test object back to null, becuase it was created only for the sake of the browser support test. Finally, when support is determined to not exist, we're going to return false rather than take an action.

  1. var setQuery = function()
  2. {
  3.  var frm = document.getElementsByTagName("form")[0];
  4.  frm.onsubmit = function(){
  5.   var query = getQuery(); // grab form data
  6.   myHijax(query); // run ajax POST
  7.   return false; // do not process the form
  8.  }
  9. }

Now, there's even more going on here. First, we're going to access the form via the DOM FORM collection. Second, we're going to set it's onsubmit handler to an anonymous function which will fire onsubmit. Here, we're going to need to do a couple things.

First things, we're going to need to grab the form data and create a Query String style format. I've hacked it in my script by hard coding it in my getQuery() function, but you're probably going to want to spend the time to create a flexible library function which can properly format a query string. Then, you'll pass it to your Ajax handler. Finally, you'll want to "return false" so that the form does not get processed by the form in the traditional way.

When creating that query string however, we're going to grab the form data and also add a variable called "ajax" so that the PHP script can see that this is not the traditional form submission.

  1. // from getQuery() function
  2. return "ajax=true&username="
  3.   + encodeURI(user)
  4.   + "&country=" + encodeURI(place);

We need to execute our Ajax call. Using my Ajax Object script you create an object with a URL, optional Query String data, and then create an AO.onload handler. With that set up, you then POST your data.

  1. var myHijax = function(qs)
  2. {
  3.  var x = new AO("post.php",qs); // object, w/ data
  4.   x.onload = function()
  5.   {
  6.     if (x.init && x.status == "200")
  7.     x.putHere("output"); // output results
  8.   }
  9.   x.post(); // execute post
  10.  return false;
  11. }

The Ajax script that you've created needs to handle the returning string of content that the PHP form is going to include. In this case again, I've used a built-in method from the Ajax Object which sets the innerHTML of a given element (here, with the ID of "output') to the returning string. The better solution here, for the purposes of my Ajax Object script would be to check for other return codes with a failure and do something else, but this gets the point over.

Full Working Demo

You can see the full working demo here, and included is a download link for you to play with it if you'd like.

Oct 22, 07:02 PM in Web Development (filed under Ajax, Accessibility)

  1. Robert Brodrecht    Oct 23, 02:25 PM    #

    I think the title of this article is misleading. What you’ve presented is a good example unobtrusive JavaScript where the title suggests you have an idea on how to make Ajax accessible. As far as I can tell, replacing the form with a string still has all the traditional accessibility pitfalls.

    So, it seems, while you’ve made the form accessible for folks without Ajax or without JavaScript, there is no fallback for, say, screen readers that choke on page replacement stuff.

    I might be missing something, though. Feel free to illuminate me if I did.

    I’ve been using a similar technique on my blog. However, in the detection process, I also leave a message that Ajax can be disabled for the form (the turn-off-Ajax link sets a variable to turn off the Ajax and links the user to the form). While it isn’t the most elegant solution (come to think of it, my message might assume too much knowledge of web technologies), it gives the user a choice about how the form is submitted. It allows the user to un-”hijax” the form, as it were.

  2. rob    Oct 23, 03:32 PM    #

    Robert, those are excellent observations, and probably true from that perspective. It’s accessible from the standpoint that it’s not explicitly tied to or that it requires Ajax to work, failing gracefully with a good fallback where Ajax doesn’t work.

    After posting, I sort of figured that someone might comment on that, so yeah, I’ll give you that—but it might be too late to rename it. Apologies if I mislead anyone.

    As I noted in the prior article, the article was brought on by comments made by clients around not using Ajax because it wasn’t accessible. I guess the point is, with a “hijax” approach, you can at least make the apps work without Ajax.

    “Accessible forms where Ajax fails?”

    I dunno.

  3. mikesab    Oct 28, 02:21 PM    #

    Rob, nice little tutorial. One possible way to address accessibility for screen readers in this instance would be to also fire an alert() to display the data returned from the php script. Screen readers are able to process alert()’s just fine.

  4. Ryno    Oct 30, 03:34 AM    #

    I agree that the word ‘Accessible’ is slightly misleading for this post, but it is a step in the right direction that’s for sure and I appreciate the time taken to construct the example.

    I’d really like to see this example extended and Robert Brodrecht’s solution I reckon is on the right track and I also agree that the terminology used to provide a user with the option to disable the AJAX functionality needs to be worded carefully.

    Perhaps the following text could be dynamically slotted in before the form if the device is AJAX capable.

    E.g. Please note that this form uses technology which is not currently compatible with all screen readers and text only browsers and we recommend disabling it if you are using a screen reader or text only browser.

    @mikesab: Whilst the alert functionality would work, that’s not necessarily ideal for non screen reader users and how do you only target screen reader users?

    Also, an excellent compliment to this article by James Edwards can be found at SitePoint, which explores the perils of AJAX and screen readers in particular.

  5. RB    Oct 31, 04:50 PM    #

    @Ryno (and maybe @Mikesab)

    I wrote a bit regarding this article on my blog. I actually read the article Ryno suggested while I was writing my post (there is a link to it). Basically, the SitePoint article suggests that there is no reliable “cross-browser” method to make screenreaders aware of dynamic updates. So, the alert functionality is just as flawed as the rest.

    Though for non-screen reader use, I don’t buy that an alert is that big of a problem. It may get irritating, but another checkbox could be employed to “alert me when this is done.”

    I still feel like giving the user the option of not using Ajax is the best way to go.

  6. rob    Oct 31, 06:33 PM    #

    Thanks for commenting. I’ve also read the Sitepoint article and tend to agree, based on that and other things I’ve seen.

    For now, it does seem the best solution for full accessibility is to serve screen readers and so forth traditional pages w/ scripts disabled, which is the basis of the Hijax approach, really.

    The question is, how do you do that? Currently from what I gather detection of screen readers barely exists. Browser detection, much less reader detection is horrid. A visible user option, such as Robert was suggesting might be the best and most realistic option, but how do explain that in a way a typical user can understand?

    It seems, much like (some, Opera in particular being an exception) mobile devices, screen readers are about where browsers were in the 90’s with regard to realistic support for what people are trying to do with the Web. Sure, they support scripts, but the better question is, should they should support them half-way?

    Another good read is here.

  7. RB    Nov 2, 09:37 PM    #

    One of the problems is that most of the screenreaders run on top of existing web browsers. They don’t modify the user agents at all. A simple easy-to-get method to help screenreaders would be to use the positioned-off-page message. This is commonly used for things like front-loading lists that are obvious to those with site but aren’t obvious to those using screenreaders (e.g. navigation lists). One thing to do would be to put a note that says “If you are using a screen reader activate our more accessible form” Where the stuff between the asterisks (or the bolded part if it is treated as such) is a link. That link could take them to an alternate page or simply turn off Ajax.

  8. James Oppenheim    Nov 11, 02:04 AM    #

    Nice article Rob. I have been trying to get into AJAX off and on. I think I will use the techniques you have mentioned here as a starting point.

    Great job!

  9. decimus    Aug 7, 10:33 AM    #

    Hi, great post.
    I`d like to translate your article to Polish. Let me know if its ok?

  10. rob cherny    Aug 16, 10:11 PM    #

    Decimus, help yourself. Just keep the caveats on accessibility in these comments and my other posts in mind.

  11. Tomo    Oct 6, 10:20 PM    #

    Thank you Rob, im learning Ajax atm. The demo is saw could was great, it could be easy changed to an Comment system.

commenting closed for this article

In This Section