Archive for the ‘AJAX’ Category

* Rich Mobile Applications

Posted on December 16th, 2008 by Dave Johnson. Filed under AJAX, phonegap.


Like the MiniDisc or the Atari Jaguar CD, web applications, rich internet applications to be specific, are a thing of the past. Yes a bold statement to be sure. Well maybe not a thing of the past but certainly in their current form.

I think that @PanMan summed it up best when he tweeted:

“Phonegap is definitely one of the most exiting developments for mobile developers these days…“

Yes the future is PhoneGap and the future is Rich Mobile Applications - RMAs for short. They can run on the phone native or as a web page but we of course think that being able to build applications using JavaScript and HTML rather than Objective-C and still having access to all the fun phone APIs like geolocation, mapping, calling / SMSing people, bluetooth etc is a very nice thing indeed.

Tags: , , .



* 13 Tips For A More Accessible Web

Posted on November 17th, 2008 by Dave Johnson. Filed under AJAX, Accessibility, JavaScript.


There are few web projects that I have worked on of late where accessibility has been a high priority. Of course having worked on the Complete UI Ajax framework that is generally used to build internal web applications we were always trying to make our components as accessible as possible, particularly through the use of the keyboard.

In general through there are a few simple things that you can do to make you web applications far more accessible to your users that may use screen readers like JAWS or have to divert from normal computer settings like just using larger than normal fonts or even using high contrast mode.

  1. Remember if something can get focus through the tab key, users with screen readers will find it and the screen reader will describe it to them.
  2. The first is something that I am sure you have heard a thousand times and may or may not have listened. Don’t use tables for layout. I think that I saw this great site about it through Dion. Amongst the many arguments against using tables for your layout is that they have semantic meaning for
    screen readers - that meaning is course that there is some tabular data to follow. So you can imagine it can be confusing when tables are found without any tabular data!

  3. When a screen reader finds a table, users generally assume that is has a header row with column headings - so use the <th> tag to specify the column headers and maybe even put that entire row in a <thead> element.
  4. Use the unordered (<ul>) and ordered lists (<ol>) when appropriate. Unordered lists should even be used for things like menus by setting the display to inline and the list-style-image to something to get rid of the normal bullet.
  5. Always set the alt attribute on <img> tags. When the image is inside of an anchor this attribute should describe the image as the anchor will bring focus to that HTML. If it is just an ornamental image then leave the value of the alt attribute empty rather than ignoring it (this was demanded by a client due to bugs in certain browsers / screen readers).
  6. Use CSS for all images. The previous issue with image tags that are purely ornamental should not happen since you should be using CSS to set background images on your HTML elements. Not to mention the fact that those images should be sprited using something like SmartSprite and so you have to use CSS.
  7. Form elements should always have an associated <label> element with the for attribute pointing to the element that the label is for.
  8. Try to put dynamic HTML (drop down menus etc) into the HTML tree where they appear
    visually such that tab index for focusable elements is maintained. If you generate a drop down but append it to the bottom of the HTML page and position so that it appears visually at the top of the page, you would have to set the tabIndex attribute on anchors in the menu to get the correct tabbing effect.

  9. Don’t use tabIndex.
  10. Any element that has an onclick event on it should be an <a> tag (or at least enclosed in one). This will ensure that it is focusable and the user can then use the enter key to activate the click event. This is also a good reason not to use onmousedown or onmouseup events since those will not be captured by the keyboard. Similarly, if you use onmouseover and onmouseout to do anything that is not visual then you may consider having onfocus and onblur to do the same thing.
  11. If you have headings then use the heading tags! Semantics, semantics, semantics.
  12. Use relative sizings like em for your fonts and other dimensions and check out how the site looks as you change the font size.
  13. Put in a hidden anchor (position absolute, x,y -5000px) near the top of the HTML that contains a message like “Skip navigation” with an href pointing to an another anchor that will skip down to the actual contents of the page such that screen reader users can skip any redundant links and header information.

If you follow that simple list you should make your web sites and applications much more accessible.

For Firefox users I recommend the Firefox Accessibility Extension, which makes testing your pages pretty easy.

Anything to add? Please leave a comment below!

Tags: , , , .



* Surfin’ Safari

Posted on October 9th, 2008 by Dave Johnson. Filed under AJAX, CSS, JavaScript, XML, completeui, quirks, safari.


For the past little while I have been busy fixing up Complete UI to work in Safari. The big problem for us in getting Complete UI working in the WebKit powered browser was that there was no client side XSLT JavaScript API until Safari 3.

So there were a few things I had to update to get things all working properly - and this more or less applies to Chrome now as well but I need to check on a few things.

XMLDocument::selectNodes

The first problem I came across was using the XMLDocument::selectNodes method. To get selectNodes working I had to implement my own NamespaceResolver which is usually handled for you by the browser.

I had to change the call to the XMLDocument:evaluate method a bit to look like this:

var oResult = this.evaluate(
  sExpr,
  (oContextNode?oContextNode:this),
  new MyNSResolver(),
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null);

Where the MyNSResolver class essentially implements the lookupNamespaceURI method through a switch statement returning the appropriate URI for the specified namespace prefix. Pretty easy but kinda annoying to figure out!


function MyNSResolver() {};
MyNSResolver.prototype.lookupNamespaceURI = function(prefix) {
  switch (prefix) {
    case "xsl":
      return "http://www.w3.org/1999/XSL/Transform";
      break;
    case "ntb":
      return "http://www.nitobi.com";
      break;
    default:
      return null;
  }
}

XSLT Transformations

Then there was the actual act of performing an XSLT transformation. Doing the transformations was fine but getting the output node or string from the transformations - depending on if the <xsl:output /> was text, html or xml - was rather different than both Firefox and Internet Explorer. Go figure.

For transforming to an XMLDocument here is what I found to be the output of an XML transformation for the various output methods.

Text:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
  </head>
  <body>
    <pre>innerText</pre>
  </body>
</html>

XML:

<output>innerText</output>

HTML:

<html>
  <body>
    <output>innerText</output>
  </body>
</html>

XSLT Parameters

There is also one difference in how the Safari XSLT processor deals with parameters. Rather than casting true / false to 1 / 0 the Safari XSLT processor does not recognize true or false values and requires the inputs to be 1 / 0. I have started setting all my XSLT params like this:


oXsltProc.addParameter("paramName", val+0, "");

Events and Focus

There were some other small issues that I came across regarding implementing rich keyboard navigation and events in general.

For example, in our Grid component I had to change the HTML element that we used to “focus” the Grid so that we could capture key presses from a <DIV> to an <INPUT>. Apparently you can’t call Element:focus on a <DIV> element from JavaScript but you can on an <INPUT> (even with a tabIndex set but I try to avoid those for accessibility reasons anyhow).

However, that was not my only problem with keyboard navigation. The other problem was that the focusable element (the newly created <INPUT> in this case) was still not getting focus due to a small code snippet like this:


oMyInput.focus();
cancelEvent(evt);

That second line where I cancel the event (wrapped nicely in a cross browser library call) somehow prevents the <INPUT> from getting the focus. Never figured out a workaround aside from a browser check before calling cancelEvent.

CSS

Finally, in some of our components we also generate CSS using XSTL and dynamically insert it into the page. For example, the developer defined column widths in a Grid produce dynamically generated CSS. However, WebKit does not seem to support the bulk creation of stylesheets neither using the document.createStylesheet method of Internet Explorer nor the hacky way of doing in Firefox by creating a <STYLE&gt element and setting the innerText. Instead Safari requires that you use the uber slow DOM API for adding rules to stylesheets :(

Miscellany

You will often see the “xml namespace prefix mapped to wrong URI” error when working with XSLT in Safari.

Be careful that you are using double quotes in your XSLT for attributes etc and only use single quotes in attribute values.

Of course you also have to be very careful about the nodes that you are transforming / selecting as you are also likely to get the “WRONG_DOCUMENT_ERR” fairly frequently.

Oh yah and depending on the application expect a lot of random “Stack overflow” errors!

Tags: , , , , , , , .



* Rails Timezones

Posted on October 5th, 2008 by Dave Johnson. Filed under AJAX, Components, Flex, Uncategorized, Web.


In my spare time I have been working on a geo-location application that runs on a BlackBerry mobile phone connecting to a Rails server where the geo data is stored.

If you happen to still be using Rails < 2.1 then this may be interesting, however, with the recent release of 2.1 timezones have been fixed up pretty well. Of course I wanted to get something that worked for my application in pre 2.1 days so I rolled together a few different libraries that seems to work pretty well. Having said that, the JavaScript will help you determine a users timezone no matter what version of Rails you are using.

The particular use case that I want to hit is that people can login to the web application from wherever they want and the application will automagically display the times in the timezone of the user viewing the site - not the timezone of the user that created the geo data and not the timezone of the server.

The general approach taken is to get the users timezone offset through JavaScript in the browser, then save that in the users profile, and then have a helper method to convert any times that are saved in the servers timezone to the users local zone.

Prerequisites

Gems: tzinfo (0.3.9, 0.3.8), tztime (0.1.0)

Plugins, tzinfo_timezone, tztime

Now for the code

So how do we figure out the users timezone? Through JavaScript of course! In application.js put the following script at the top - don’t put it on the onload event since it should set as soon as a user hits the page:


Cookie.set("tz", (new Date()).getTimezoneOffset());

This sets a cookie in the browsr to be the JavaScript timezone offset, which we will use later on the server. Note that this is using a simple cookie abstraction.

Now in application.rb we need some magic that will take that timezone offset from the cookie and update the users profile with their current timezone. This will be achieved with an around_filter (damn I love around filters) like so:


around_filter :set_timezone

def set_timezone
  if logged_in? && browser_timezone && (browser_timezone.name != current_user.time_zone || current_user.time_zone.nil?)
    current_user.update_attribute(:time_zone, browser_timezone.name)
  end
  TzTime.zone = logged_in? ? current_user.time_zone : browser_timezone
  yield
  TzTime.reset!
end

def browser_timezone
  return nil if cookies[:tz].blank?
  @browser_timezone ||= begin
    min = cookies[:tz].to_i
    TimeZone[-min/60]
  end
end

That takes care of getting the users current timezone. Now all we have left is to make it accessible to the application with a simple function in the application_helper.rb as follows:


def local_time(time_at)
  TimeZone[TzTime.zone].utc_to_local(time_at.utc)
end

Finally, we can just call local_time from anywhere passing in a time that is in the servers timezone from the database:


local_time(location.updated_at)

So if you are stuck on Rails < 2.1 that is a good approach to getting timezones working.

.



* Complete UI Q4

Posted on September 26th, 2008 by Dave Johnson. Filed under AJAX, JavaScript, Nitobi, completeui.


Some big changes are coming in the Q4 release of Complete UI. Big!

Of course there is a slew of JavaScript bug fixes for all the components with Grid receiving the most attention for IE 8, Safari 3, Firefox 3 and Chrome.

There are a bunch of changes to the Java side of Complete UI with more great JSP and JSF code to make it even easier to use Complete UI in your Java project.

Finally, we have also made huge changes to the ASP.NET Grid and Combo code - and are working on the rest of the components as I am writing this! I think that anyone using ASP.NET will be very happy with the new direction of the ASP.NET code :)
We are shooting for an on time Oct 1 release but there is so much we are trying to fit in it might be a bit late - but it will be well worth waiting for!

Tags: , , , , , , , .



* AIR Support

Posted on September 4th, 2008 by Dave Johnson. Filed under AJAX, air.


When Andre went on the final leg of the Adobe AIR tour back in the spring I needed to build a nice Ajax + AIR demo for him. Ultimately I had to drop the project and Andre went without. The main reason that I decided not to build the application was due to frustrations with building HTML / Ajax apps in AIR - though I had previously built several successful HTML / Ajax AIR apps in the beta versions of the AIR runtime.

This was the first real application that I had tried to build since the Beta 1 and of course there were some API changes - as can be expected between beta versions and a release - but more importantly the security restrictions in Ajax AIR applications make it almost unusable for certain use cases. At least for my HTML apps.

There are two main problems that I found exceedingly annoying and that ultimately led to the shelving of the project.

The first problem was that you cannot use innerHTML to insert HTML that contains event handler code such as <div onclick=”foo()”>Bar</div> when you are in the Application Sandbox. This is of course to prevent people from inserting malicious code on HTML events - which is equivalent to doing an eval if the user somehow triggers that event or the event is triggered manually through JavaScript.

That meant that I had to put most of my code in the Network Sandbox to get around the security restrictions. Fair enough I thought until Murphy reared his ugly head.

It just so happens that you cannot pass complex objects across the Sandbox bridge since they become of type “Object” on the other side. So for example I wanted to pass an XML document from the Network Sandbox where my application UI is residing into the Application Sandbox so that I can do some cross domain requests with it and / or save it to disk for use later when offline - essentially to do anything interesting it needs to be in the Application Sandbox. So to do this I had to write my own code to serialize and deserialize any custom objects that I wanted to pass around, essentially converting my XMLDocuments and so on to strings on one side and then loading them into XML documents again on the other. Pain. In. The. Arse.

A second, and maybe more important result of not being able to pass complex objects across the bridge is that it pretty much means that if you want your UI to be in the Network Sandbox you cannot do file drag and drop unless you have a special place that is in the Application Sandbox where the user can drop onto. This may not seem like such a big deal, however, it poses other problems with the UI layout since the best way to layout the UI in an HTML AIR app is to have the custom chrome in the Application sandbox using the CSS border-image (which is awesome) and then have the rest of the UI in a 100% width and 100% height IFrame with some margin to take into account the custom chrome edges. In that case there is not really any opportunity to have a special drop area in the Application Sandbox to accept dragged information from the desktop.

So to make a long story short, building AIR apps that use dynamic UI generation and some of the APIs that make AIR awesome, like drag and drop, means that HTML / Ajax AIR apps are simply not feasible due to the security restrictions.

Tags: , , , .



* Login Forms

Posted on August 15th, 2008 by Dave Johnson. Filed under AJAX.


Does it annoy anyone else that Web 2.0 apps like Basecamp no longer have login forms? I understand that you need to login at a specific URL http://nitobi.myapp.com but would it be so difficult to actually just have a login form that transfers you to your server rather than making people remember the server name?

Tags: .



* Enterprise Ajax Live Lessons

Posted on August 13th, 2008 by Dave Johnson. Filed under AJAX, Nitobi.


Get it while it’s hot! It looks like the Enterprise Ajax Live Lessons are now available on either Safari or Amazon.

if you want to learn about Ajax in a format that is bit more easily digestible than reading a boring book then be sure to pick up the Live Lessons where we step you through all the pitfalls of building an Enterprise Ajax application. Topics covered include a framework review, testing, security and usability.

Go get it!

Tags: , , .



* What is RIA?

Posted on August 12th, 2008 by Dave Johnson. Filed under AJAX, Conference, RIA, Web2.0.


Way back in May of this year (I have been thinking about this post for a while now!) Andre and I were down at JavaOne to give a presentation and also had the chance to take part in the always interesting (at least two years in a row now) RedMonk CommunityOne session. It was good to take part in the cloud computing, twitter and open source discussions - one great take away was “don’t drink and tweet”. I digress.

Of most interest to me was the round table discussion about “what is an RIA?“. There were various opinions on this that I will not repeat here and let you read over on RedMonk.

What didn’t come through on the RedMonk review was what I thought, arrived at through the great discussion, was really the defining characteristic of Rich Internet Applications. In the end it was not about flashy graphics or animations. The one defining characteristic of an RIA is that there is no page refresh.

That’s it. That is all there is to RIA. If you have an application running over the network that does not have a page refresh then that is an RIA - be it using Flash, Ajax or a Java Applet. The discussion went back and forth until Jeremiah Stone from SAP finally talked some sense (afterwards we had a very interesting discussion and I really need to follow up with him) saying that good design is dependent on the context of the problem being solved. Now this is a really important idea since if you are used to working with a keyboard accessible green screen application, a visual mouse driven GUI will probably be far less usable. It is all context dependent. I may take longer to learn the green screen application but it will likely pay dividends in productivity down the road.

At any rate, long story short, the one common theme that people presented was that an RIA is defined by an application that has no page refresh, whether it is made for a user of a terminal or a new web 2.0 application.

I had my epiphany at the very end of the session and was pretty much lost on deaf ears of people who were about ready for a cold one (aside from Duane who was thoroughly liquored already ;)) . However, I felt somewhat vindicated when I was reading James’ post about the session when I noticed that there was a comment from David Mendels of Adobe, who was possibly responsible for defining the term while at Macromedia in the early 2000’s. Indeed David suggested that the original definition of an RIA was an application with no page refresh.

Based on that I think that the case of the meaning of RIA can be considered closed.

RIA == No page refresh

QED

Tags: , , , , , .



* Complete UI Q3

Posted on June 18th, 2008 by Dave Johnson. Filed under AJAX.


We are almost ready to start building for our planned July 1 release of Complete UI Q3 - it is looking like we will be on schedule even! It is too bad we didn’t get everything in that we wanted but there are still a few nice new features.

The most notable updates aside from various bug fixes are Firefox 3 support, a new and improved Calendar and Datepicker component, and JSF versions of all the components!

I am really excited to see what sort of adoption we get for the JSF versions of our components and I think that people will be pretty happy with the new and Calendar functionality.

Time to get back to work as it will probably be a pretty tireless last week and a half.

.