Christian Heilmann

You are currently browsing the archives for the usability category.

Archive for the ‘usability’ Category

AjaxWorld East – Cold weather, Arctic Snowcruisers and a shift in perception

Thursday, March 27th, 2008

I am just sitting at the airport in Montréal, waiting for the delayed flight to arrive and get me back to New York City to get back to London. I’ve spent the last few days first in New York to speak at the AjaxWorld East conference, then go to Montréal, Canada to speak at the Coder’s Saturday and give a two presentation workshop at Nurun. Suffice to say, I am pretty bombed out, but this is a good chance to jot down my experiences during this trip. Let’s start with AjaxWorld.

The audience

The AjaxWorld conference was a bit of a surprise to me. Judging by the price of a ticket and the web site explaining all the other presentations I had braced myself to stand in front of a large room full of suits that needed to go to the conference rather than wanting to go. Turns out I was wrong. The audience was a mixed crowd of company owners, project managers, designers and developers and everybody was very involved and interested. I’ve met a lot of companies selling developer tools like frameworks and IDEs, a few implementing companies (including the lovely people from the food network who took me out for dinner for a real Italian NYC style) and really surprising edge developers like someone who ran software that controls geostationary satellites! I got a lot of interesting questions and feedback and I am happy to have met everybody there.

The location

The conference took place in the Roosevelt Hotel, located a block away from New York’s Grand Central Station. The hotel is a 1920s affair full of charm and grandeur of a bigone aera. You entered the place and felt like you are in a Hercule Poirot episode. However, for a tech conference this size it was not a great choice. For starters there was no internet connection that was either affordable or stable. Even the $24/day room connection went up and down like a roller coaster. This meant that I was driven to the bagel place (Cosi) on the other side of the street a lot as they had free Wi-fi (I am sure they made a killing these few days).

As for presentation facilities there was the main presentation hall which was a ball-room with really high ceilings reserved for sponsor talks and the keynote. This one easily allowed for all attendees to fit in, but was excruciatingly cold. All the other presentations took place in smaller meeting rooms not quite big enough to hold all interested delegates. The projectors were put in between rows of chairs which made it tricky for you to reach the screen and from time to time attendees would bump against them.

The hotel itself is also grossly overpriced for the comfort the rooms offer. My hotel in Montréal was about a third of the price per room per night, ultra-modern and had free connectivity, a fax and a safe in each room and came with complimentary breakfast. OK, it is New York city and the Roosevelt was built in the 20s, but a fleecing is a fleecing, no matter how your dress it up.

The organization and coverage

Apart from that, the hotel had a cozy atmosphere in the bar and the organizers did their best to keep everything in check. They did a splendid job filming the whole event and live-streaming parts of it. When you needed help, they were immediately there to help you out, something that is quite an uncommon event in NYC. There were more than enough handouts of the current schedules, signs were put up everywhere that you needed and every delegate got a free book on Ajax with the massive badge telling others who that person is and what he or she does. I felt pretty well looked after and was easily convinced to deliver an extra presentation in place of another presenter who had missed his flight.

The only thing I didn’t like too much is the amount of parallel presentations. I missed a lot of things I wanted to see, but couldn’t because I can’t split myself in two. Clever companies made sure that they sent several people there to allow for full coverage.

My presentations

My first presentation was a gap-filler for a speaker that didn’t show up and I wrote it a day before. I talked about the opportunity we have right now to use Flash to deliver rich media content on web sites and control the experience with JavaScript provided that we get a proper API. I got really interested in that lately, working with great people like Aral Balkan, Niqui Merret and Steve Webster. As examples I showed how SWFObject allows you to progressively enhance HTML to contain Flash, how the YUI image uploader allows you to batch upload files using Flash and how the YouTube API allows you to control online video with JavasScript.

My main and planned presentation was about architecting JavaScript for large applications using Event Driven Design showing off Yahoo Maps and Eurosport as examples. The unexpected bit of the presentation was that I explained it using the Antarctic Snowcruiser as an analogy.

The Antarctic Snowcruiser was a massive vehicle built in 1937 to explore Antarctica. The task the cruiser had to fulfill was amazingly problematic – it was to host a crew of 5 and keep them safe from the terrible cold for a year to cross 5000 miles of hostile environment. The cruiser was an absolute marvel of technology and its inventors thought up amazingly clever solutions to the problems they anticipated, including the possibility to retract the wheels into the body of the cruiser to overcome crevasses and to re-use the engine heat to keep the crew from freezing to death. The only thing they forgot to plan for was traction and when the cruiser arrived in Antarctica its wheels spun uselessly and the engine overheated almost immediately. The cruiser got abandoned and was found 20 years later encased in ice. Now it is unknown where it went as the piece of ice it was last seen on broke off and got dragged out to sea.

This was my example how we build applications – we assume a lot and over-engineer on the server side without realizing that most of the application work will be done by a browser in an to us unknown environment. I wanted to inspire people to consider the usability and restrictions of web applications before making assumptions that everything will work and that we can predict the environment our apps run in.

Both presentations were packed and I got good feedback, I’d be interested in more from people that went there and I am looking forward to seeing the videos.

Other presentations

I didn’t see many other presentations, but here is what I got: Douglas Crockford’s Keynote was a stark reminder how broken the technologies we use to create web applications really are, showed security flaws and ideas as to how we can try to fix these. Caja was mentioned along with adSafe and Douglas explained his idea of vats to secure the web. There was more and more detail published on his blog the last few days, so make sure to check there.

In terms of security, there was a full-on attack vector talk by
Danny Allan of Watchfire which showed exactly how far an unrestricted scripting injection will get attackers. It is pretty easy to disregard XSS as a banal penetration of your site but this presentation showed how a fully patched new Firefox running on a windows machine with firewall and up-to-date virus software can be accessed with malicious JavaScript and get all kind of passwords and deeper access using a mix of phishing and social engineering.

The IBM people involved in the Dojo framework showed off the internationalization and accessibility options of Dojo in a joint presentation and I was very impressed as to how far the framework embraced ARIA and how much information was given on how to do both i18n and a10y with usability in mind. Great work!

I’ve spent a lot of time with the people who build qooxdoo, a widget framework exclusively written in JavaScript. Their presentation showed what the framework is and how it works cross-browser. They also showed the very impressive performance of the widgets and how they can be skinned. The really cool stuff of qooxdoo is still in the making though and I will make sure that we watch the guys more closely and reveal some of the clever tricks they use to boost performance and build application code cleverly using a Python build script.

The last presentation I’ve seen was introducing ways to build iPhone applications that have the native look and feel and it was more or less a re-hash of the developer guidelines given out by Apple mixed with an introduction to iUI. I was not at all inspired by the talk which is amazing as iPhone is a really nice platform and highly interesting at the moment.

Summary and learnings

All in all it was well worth it going to the conference. The mix of presentations and topics covered was well done and I myself realized that it is high time we stop advocating web standards as a technical solution. Web standards are there to ensure maintainability and predictability but in the enterprise world we are already one step further and technologies like Flex, Silverlight and Comet are what need our close attention to ensure that we have predictable and maintainable solutions in these as well. Douglas’ view as the browser model as being broken can be considered as too strong a message, but I realized that a lot of the things end users expect these days are just not possible with the HTML/CSS/JS trinity we keep preaching about. This does not mean standards are unimportant – they are best practice in terms of implementation. Technologically we have to brace ourself to be surprised of the changes in the next year.

An attempt for a more accessible edit-in-place solution

Friday, January 4th, 2008

Today I will try to find a more accessible way to provide an edit-in-place script. The solution described here is probably not ready for real life yet, please test it in different environments and provide fixes. It is licenced with creative commons share-alike, so go nuts!

I really like the idea of edit-in-place. Probably the most used example of edit-in-place is flickr which allows you to click any heading or description when you are logged in to directly edit it. The reason I like edit-in-place is that it makes it a lot easier for users to describe things, which hopefully results in more accessible and easier to find web sites (after all text is what gets indexed and what is available to everybody). The drawback of edit-in-place is that a lot of solutions are not very accessible. They add a click handler to elements that are not necessarily available to assistive technology and are not at all accessible with a keyboard.

A non-scripting solution attempt

Technically the easiest solution to create an accessible edit-in-place would be to use input fields with labels and use CSS to make them look like the other elements. The code could be the following:

<h1 class="editable">
  <label for="mainheading">Heading:</label>
  <input type="text" id="mainheading" 
         value="Otters in eastern Europe">
</h1>

And the CSS:

.editable label{
  position:absolute;
  top:0;
  left:-9999px;
}
.editable input{
  border:none;
  font-family:arial,sans-serif;
}

But alas! Is it more accessible? I am not sure, as the semantic goodness of a heading is disturbed. I am quite sure search engines will frown upon it and as screen readers work differently in forms mode than in reading mode it might even be more confusing. So let’s scratch that.

Making it work unobtrusively

The next step would be to use a normal heading and somehow connect it with a form field somewhere else in the document. The cool thing about this is that we have something like that in plain HTML: targeted links. For example:

<form id="editform" action="servermagic.php">
<h1 class="editable">
  <a href="#editheader">Edit me, wuss!</a>
</h1>
<p class="editable">
  <a href="#editdescription">Me as well, do it!</a>
</p>
<div id="editingsection">
  <p>
    <label for="editheader">Content of main heading:</label>
    <input type="text" id="editheader" name="editheader">
  </p>
  <p>
    <label for="editdescription">Content of description:</label>
    <input type="text" 
           id="editdescription" 
           name="editdescription">
  </p>
  <p><input type="submit" value="Save Changes"></p>
</div>
</form>

This works without JavaScript (but somehow my Firefox does not highlight the form field when you hit the link, does anyone know why? Please comment!). All it needs to turn it into a working version of edit-in-place is a JavaScript. What the script does is:

  • find the section with the ID “editsection” and hide it from view
  • find all elements with the class “editable” and add a click handler pointing to an edit function
  • override the submit event of the form to point to a store function

The edit function should do the following:

  • check if another element is already being edited and focus that if there is one
  • Get the ID of the form element from the href of the targeted link
  • set the value of the form element to the content of the element
  • set an “edited” style to the original element to hide it
  • show the form field where the original link was
  • focus the form field
  • tell the main script what element is currently being edited

The store function should:

  • check if there is an element edited (to avoid overriding normal form submission)
  • set the content of the targeted link to the value of the field
  • move the form field back to where it came from
  • set the focus back to the link
  • store the content asynchronously (not implemented here)
  • stop the normal form submission
  • reset the edit state of the script to none

Following is the script that does exactly that. I am using the YUI in this example as I like to concentrate on writing scripts rather than worrying about browser problems. That said, notice that you need to wrap form field focus in a timeout in Firefox, what’s with that?

YAHOO.namespace('ch');
YAHOO.ch.editinplace = function(){
 
  /* Names and IDs used */
  var namesandids = {
    editsection:'editingsection',
    edited:'edited',
    hidden:'hidden',
    editable:'editable',
    form:'editform'
  };
 
  var YE = YAHOO.util.Event,YD = YAHOO.util.Dom;
 
  var edit = {};
  var editingsection = YD.get(namesandids.editsection);
  if(editingsection){
    YD.addClass(editingsection,namesandids.hidden);
 
    function doedit(e){
      if(!edit.target){
        var t = YE.getTarget(e);
        if(t.href){
          var fieldid = t.getAttribute('href').split('#')[1];
          var field = YD.get(fieldid);
          this.appendChild(field);
          field.value = t.innerHTML;
          YD.addClass(t,namesandids.edited);
          setTimeout(function(){field.focus();},10)
          edit = {target:t,field:field,id:fieldid};
        };
      } else {
        setTimeout(function(){edit.field.focus();},10)
      }
      YE.preventDefault(e);
    };
 
    function store(e){
      if(edit.target){
        edit.target.innerHTML = edit.field.value;
        YD.removeClass(edit.target,namesandids.edited);
        editingsection.appendChild(edit.field);
        edit.target.focus();
        // Ajax Magic here, you can used edit.id as the id 
        YE.preventDefault(e);
        edit = {};
      };
    };
 
    var edits = YD.getElementsByClassName(namesandids.editable);
    YE.on(edits,'click',doedit);
    YE.on(YD.get(namesandids.form),'submit',store);
 
  }
}();

Try out the solution and Download the example page with the script as a zip and tell me what you think!

Tested in Firefox, IE7 and Opera 9 on PC, please get me some more feedback on other systems and browsers.