Christian Heilmann

Posts Tagged ‘javascript’

A quick idea: JavaScript version controlling for static HTML documents

Monday, January 14th, 2008

When you write tutorials and you want people to use them wherever they are it is a good idea to offer the HTML documents as a zip for downloading. The benefit to the end user is that they don’t need to be online to look something up (I for example have the HTML 4.01 documents on my machine as HTML documents). The drawback is that the documents could be outdated without the user knowing – even when they are online while watching them.

Now, I pondered a bit about this and wondered if something like this wouldn’t be a solution:

  • You add a version number to the title of each document.
  • You add a remotely hosted versions.js script at the end of each document.
  • This script has a JSON object with the version information of each document and compares the file name and version.
  • If the version is outdated, it generates an error message that gets shown to the user.

You can try it out by downloading the two demo documents un-zip them and open them on a computer that is connected to the internet. The second document linked from the first one should be outdated.

The source of versions.js


(checkversion = function(){
// change as fit
var versions = {
‘documentexample.html’:’1.0’,
‘documentexample2.html’:’2.0’
};
var errorID = ‘versionerror’;
var errorMessage = ‘This document is outdated, please go to the homepage to download the new version!’;

// checking code
var d = document;
// get the version number
var cv = d.title.match(/(version (.*))$/);
// get the file name
var cn = window.location.href.split(‘/’);
cn = cn[cn.length-1].split(‘#’)[0];
// check and create error message if there is a mismatch
if(cv[1] && versions[cn]){
if(versions[cn] !== cv[1]){
if(!d.getElementById(errorID)){
var m = d.createElement(‘div’);
m.id = errorID;
m.appendChild(d.createTextNode(errorMessage));
d.body.insertBefore(m,d.body.firstChild);
}

}
}

}());

You could create both the titles and the JSON object in versions.js on the backend automatically by scanning the titles or from a version control system. What do you think?

Generating charts from accessible data tables and vice versa using the Google Charts API

Tuesday, January 8th, 2008

Google have lately been praised for their chart API and my esteemed colleague Ed Eliot has a workaround for its restrictions in terms of caching and server hits.

I played around a bit with it and thought it very cool but it felt a bit clunky to add all these values to a URL when they could be in the document for those who cannot see pie charts. This is why I wrote a small script that converts data tables to charts using the API and a wee bit of JavaScript.

Using this script you can take a simple, valid and accessible data table like the following and it gets automatically converted to a pie chart.













Browsers
BrowserPercent
Firefox60
MSIE25
Opera10
Safari5

Simply add the script to the end of the body and it’ll convert all tables with a class called “tochart”. You can define the size (widthxheight) and the colour as a hexadecimal triplet as shown in this example. If you leave size and colour out, the script will use presets you can alter as variables in the script itself.

What about data tables from charts?

As Victor of the Yahoo! Accessibility group asked for the other way around, this is now also possible. When you use the verbose data mode for the charts and add the class “totable” to the image the script will generate a data table preceeding the image and null out the alternative text. For example:


Fruit Consumption of under 15 year olds, March 2007

The tables have a class called “generatedfromchart” which you can use to move them off-left if needed.

Check out the demo page and download the script with the demo page and CSS to have a go with it yourself. Of course, all is licensed creative commons, so go nuts.

Useful? Please comment if you want something extra or wonder how the script works.

YUI on the go – load YUI components on demand

Friday, December 7th, 2007

This is one of my talks at the Yahoo! Frontend Engineering summit in London and it deals with the options of cutting down the size of the YUI library components. There have been many articles and posts about this subject already but none really explained the idea of using YAHOO_config to load components on demand instead of using the YUI loader.

This is also the trick I used to create the unobtrusive flickr badge v2.

Planning JavaScript for Larger Teams – Draft & Handout version

Wednesday, November 28th, 2007

I just found my original draft of my @mediaAjax presentation. I discarded it cause it was way too long for an hour talk and I didn’t know what do ditch:

Hope it is of use somehow.

JavaScript shortcut notations that shouldn’t be black magic to the “average developer”

Tuesday, November 27th, 2007

When publishing articles about JavaScript development you run into many rules set by publishers and editors. This is a great thing as it keeps us authors on our toes and makes us understand more about how much work successful publishing really is. However, it can also be terribly annoying, especially when older idioms just stick. One of them is that “the average developer” does not quite understand JavaScript shortcut notations.

Now, if you are “the average developer”, please give me 5 minutes of your time to get through the following, you’ll understand a lot more code out there and also spend a lot less time writing your own scripts.

Array shortcut notation – It is hip to be square

The first bugbear I have are arrays. These are terribly useful and omnipresent in JavaScript and still I find people who write convoluted things like:

var links = new Array();
links[0] = 'http://cuteoverload.com';
links[1] = 'http://icanhascheezburger.com';
links[2] = 'http://pencilsatdawn.wordpress.com';
links[3] = 'http://apelad.blogspot.com';
// ... ad nauseam ...

This is convoluted (you have to repeat the array name for every item) and also tricky to maintain. When you change the order (granted the order is of importance) you need to change the number, too. It is not necessary, as the numbering is done automatically for you. All you need to do is use the square brackets:

var links = [
  'http://cuteoverload.com',
  'http://icanhascheezburger.com',
  'http://pencilsatdawn.wordpress.com',
  'http://apelad.blogspot.com' // <-- last one, NO COMMA!
];

This makes it more obvious from a visual point of view, too. The indentation makes it easy to spy where the array begins and where it ends. Much less line noise to take in.

Notice that you need to separate each item with a comma, but make sure you don’t have a trailing comma at the last item. You can even nest arrays that way:

var links = [
  'http://cuteoverload.com',
  'http://icanhascheezburger.com',
  [100,200,20,'foo'],
  'http://pencilsatdawn.wordpress.com',
  'http://apelad.blogspot.com' // <-- last one, NO COMMA!
];

On that note, here’s another trick: to add a new item to arrays, you can either use the push() method or use the length property:

links.push('http://dailypuppy.com');
links[links.length] = 'http://bigeyedeer.wordpress.com';

Associative Arrays – OMG! Ponies!

One myth that keeps sticking is that JavaScript has a magical thing called associative arrays. These allow you to not just number the items but give them names instead! You find examples like:

var links = new Array();
links['Cute Overload'] = 'http://cuteoverload.com';
links['I can has cheeseburger'] = 'http://icanhascheezburger.com';
links['Pencils at dawn'] = 'http://pencilsatdawn.wordpress.com';
links['Hobotopia'] = 'http://apelad.blogspot.com';

This is treachery to the highest degree. It is a confusing JavaScript trait, as what you created here is not really an array, but an object. Want proof? – Do an alert(typeof links) or try alert(links[1]).

Object shortcut (literal) notation – getting curly.

So called associative arrays are actually objects, which means you will also find other scripts that took the earlier example serious and use the following instead:

var links = new Object();
links['Cute Overload'] = 'http://cuteoverload.com';
links['I can has cheeseburger'] = 'http://icanhascheezburger.com';
links['Pencils at dawn'] = 'http://pencilsatdawn.wordpress.com';
links['Hobotopia'] = 'http://apelad.blogspot.com';

Again we have far too much repetition. For objects, you have the Object Literal Notation as a shortcut, which basically is using curly braces:

var links = {
  'Cute Overload' : 'http://cuteoverload.com',
  'I can has cheeseburger' : 'http://icanhascheezburger.com',
  'Pencils at dawn' : 'http://pencilsatdawn.wordpress.com',
  'Hobotopia' : 'http://apelad.blogspot.com' // <-- again, no comma!
}

The semicolons get replaced by commatacommas (Happy, Stuart?) (except for the last one which you need to omit) and the equal signs become colons. If the properties (the things to the left of the colon) don’t have any spaces in them, you can even get rid of the quotes:

var chris = {
  hair : 'red',
  age : 32,
  city : 'London'
}

You can access the properties with object.property when they don’t have any spaces or with object[property] when they have spaces. For example:

var links = {
  'Cute Overload' : 'http://cuteoverload.com',
  'I can has cheeseburger' : 'http://icanhascheezburger.com',
  'Pencils at dawn' : 'http://pencilsatdawn.wordpress.com',
  'Hobotopia' : 'http://apelad.blogspot.com' // <-- again, no comma!
};
alert(links['I can has cheeseburger']);
alert(links.Hobotopia);

Simple if-else statements – ask and define with the ternary notation

You can shorten simple if statements dramatically. With simple I mean an if statement that assigns one of two values like this:

  var YUIguy;
  if(city === 'London'){
    YUIguy = 'Chris';
  } else {
    YUIguy = 'Eric';
  };

Again, a lot of repetition there. The ternary notation works around that problem:

var YUIguy = city === 'London' ? 'Chris' : 'Eric';

A lot of equal signs there. Maybe some parenthesis will make it clearer:

var YUIguy = (city === 'London') ? 'Chris' : 'Eric';

What’s going on here? You define the variable YUIguy and assign it a value. Then you have a statement, in this case the comparison of the variable city and if it equals to the string London (=== tests for both the value and the type, much safer than ==).

Then you ask the question if that is true or not by using the question mark. The option on the left of the colon is the answer to the question when the condition was met and the option on the right of the colon is the answer when the condition was not met. Any condition that could be true or false can go inside the parenthesis.

var direction = (x < max) ? 'left' : 'right';

Offering a fallback option with the default operator

The last thing I wanted to quickly talk about is the double pipe (||) default operator. This one is terribly useful when you want to make sure that something is set with a default value. The following construct is something that should not show up any longer:

  var section = document.getElementById('special');
  if(!section){
    section = document.getElementById('main');
  }

Again, useless repetition, as the same can be written as:

  var section = document.getElementById('special') || document.getElementById('main');

If the first is not defined, the second gets assigned as a value to section.

Thanks for your time!

I hope this helped “the average developer” to understand how you can make your JS a lot shorter without really cutting down on readability. If you want more detailed information about all these goodies, check out Douglas Crockford’s articles on the matter: