a stroke of luck

jQuery styleswitch – now with toggle!

About three years ago I posted my stylesheet switcher switcher here. It was the first bit of programming I ever did using jQuery. Surprisingly enough it is still one of the most popular posts on my blog and I still get quite frequent questions about it.

One of the most popular questions is “how can you make the styleswitcher toggle between available stylesheets?”. So I just put together a little example of how to do this. While doing it I noticed that the original code wasn’t really that extensible which is probably why people were always asking that question! So I ended up rewriting the code a bit as well as putting together the new example. You can find it all here.

Progressive enhancement with jQuery example

Update: shAIR is now called Sharify so I’ve updated the links below to point to the new website.

As I previously wrote, we just launched a new product called shAIRSharify. The website was a great chance to implement some progressive enhancement using my favourite javascript library, jQuery. So I thought I’d take the chance here to explain some of the things I did and how they continue to work without javascript enabled. None of this is rocket science by any stretch of the imagination but I thought is was worthy of a quick description.

Since much of the functionality discussed below is behind a login in the admin panel I put together a little example sandbox page which demonstrates the points below.

Styled submit buttons

The beautiful site design from hoppermagic called for submit buttons which don’t really look like buttons at all. Styling a normal submit button is fairly limited and hard to do cross browser so instead I decided to use javascript to swap out the submit button for a normal link which has an event listener which submits the form. If js is disabled the user gets a normal, accessible submit button. If js is available then we know that we will be able to use javascript to submit the form.

The code in question looks like this:

      var $this = $(this);
      var f = this.form;
      var link = $('<a href="#">' + $this.val() + '</a>')
               return false;
      $this.after(link).css({position:'absolute', top:'-2000px'});

Note that rather than hiding the real submit button with visibility:hidden or display:none we instead just move it way off the screen. This means that you can still submit the form by pressing return in one of the form fields (IE doesn’t allow this if there is no visible submit field in the form).

Form validation

Using the validation plugin made it very quick and easy to add clientside validation to my forms. This doesn’t replace serverside validation but it means that you can inform your users of their errors and give them meaningful feedback quickly. One thing that I would love to see added to the validation plugin is some sort of hooks for when the error message is shown and hidden. I wanted my errors to animate nicely into and out of existence. I managed to hack in a slideDown on the appear by abusing the errorPlacement callback but I wasn’t able to animate the disappearance of the element.

The code related to the validation plugin looks like this:

$forms = $('.validated-form');
if ($forms.length) {
         errorPlacement: function(error, element)

Note that I only try and call the validate method where I find forms with a class of validated-form. This is because I use the same javascript throughout my site but I only include the validate plugin (and add the validated-form class to forms) on pages where it is required. I would get errors complaining that the validate method couldn’t be found if I didn’t have the check.


Another easy one thanks to the jquery.simpletip plugin. None of the examples on that page seem to use the tooltip in a particularly gracefully degrading way though. In my case I decided to use the title element of the items I was creating a tooltip for to hold the text of the tooltip. This means that without javascript enabled people will still see (less pretty) tooltips. The code is very simple, it grabs the value of the title and passes it into the simpletip initialiser. We also need to remember to empty the title attribute so that the browser doesn’t display it’s tooltip as well as ours.

      var $tt = $(this);
            hook: {
               tooltip: 'topLeft',
               target: 'bottomLeft'
            offset: [20, -5],
            stem: {
               corner: 'topLeft',
               color: '#000',
               size: 15
      ).attr('title', '');

FAQs accordian

For the FAQs page I wanted to make it easy for people to scan the questions and then click on the one they wanted the answer for. And jquery made it really easy to add a bit of animation to this too. As an added extra I also add a CSS class to the relevant question heading which changes the direction of the arrow besides it. The answers are hidden by javascript on document ready so users without javascript will just see a normal list of questions followed by answers.

var $h2;
var $answer;
$('#faq h2').bind(
      if ($h2 && $h2[0] != this) {
      $h2 = $(this);
      $answer = $;

Message for IE6 users

I spent a little bit of time making sure that the site was at least usable in IE6. But I didn’t want to waste too much time making sure everything looked perfect. So I decided to add a little message to the top of every page which encourages IE6 users to upgrade their browser. This way they are at least aware why things don’t look quite right and they can’t complain. Luckily, IE6 is a (slowly) dying beast and will be used by a very small proportion of the site’s target audience (developers who are using Adobe AIR).


So that’s a quick description of some of the simple steps we took to make the website as beautiful and easy to use as possible for people on modern browsers while making sure it is still accessible and available to people using older browsers or who have javascript disabled (for whatever reason).

With the tools and information web developers have at their disposal these days it is so easy to build a site in this manner that there really is no excuse for sites which are completely broken with javascript disabled. Hopefully these simple examples illustrate the some of the concepts behind progressive enhancement.

Data scraping with YQL and jQuery

For a project that I’m currently working on I need a list of all the US National Parks in XML format. Google didn’t come up with anything so I decided that I would need to somehow grab the data from this list on Wikipedia. The problem is that the list is in messy HTML but I want some nice clean XML ready for parsing with E4X in Flash.

There are a number of ways I could parse the data. If I knew Ruby and had an environment set up I’d probably use hpricot. Or I could get my hands dirty again with PHP and DOMDocument. Or if the Wikipedia page was XML or could be converted into XML easily then I could use an XSL transform. Or I’m sure there are hundreds of other approaches… But in this case I just wanted to very quickly and easily write a script which would grab and translate the data so I could get on with the rest of the project.

That’s when I thought of using jQuery to parse the data – it is the perfect tool for navigating a HTML DOM and extracting information from it. So I wrote a script which would use AJAX to load the page from Wikipedia. And that’s where I hit the first hurdle: “Access to restricted URI denied” – you can’t make crossdomain AJAX calls because of security restrictions in the browser :(

At this point I had at least a couple of ways to proceed with my jQuery approach:
  • Copy the HTML file from Wikipedia to my server thus avoiding the cross domain issues.
  • Write a quick serverside redirect script to live on my server and grab the page from Wikipedia and echo it back out.
I didn’t like the idea of either of those options but luckily at this point I remembered reading about YQL:
The YQL platform provides a single endpoint service that enables developers to query, filter and combine data across Yahoo! and beyond.
After a quick flick through the documentation and some testing in the YQL Console I put together a script which would grab the relevant page from Wikipedia and convert it into a JSONP call which allows us to get around the cross-domain AJAX issues. As an added extra it’s really easy to add some XPath to your YQL so I’m grabbing only the relevant table from the Wikipedia document which cuts down on the complexity of my javascript. Here’s what I ended up with:
SELECT * FROM html WHERE url="" AND xpath="//table[@class='wikitable sortable']"

If you run this code in the console you’ll see that it grabs the relevant table from wikipedia and returns it as XML or JSON. From here it’s easy to make the AJAX call from jQuery and then loop over the JSON returned creating an XML document. If you are interested in the details of that you can check out the complete example.

I was really impressed with how easy it was to quickly figure out YQL and I think it’s a really useful service. Even if you just use it to convert a HTML page to a valid XML document then it is still invaluable for all sorts of screen scraping purposes (it’s always much easier to parse XML than HTML tag soup). One improvement I’d love to see the addition of a CSS style selection engine as well as the XPath one. And the documentation could maybe be clearer (I figured out the above script by checking examples on other blogs rather than by reading the docs). But overall I give Yahoo! a big thumbs up for YQL and look forward to using it again soon…

jScrollPane 1.2 released

I’ve just released a new version of jScrollPane – my jQuery plugin for cross-browser customisable scrollbars. It’s been a long time since the plugin has been updated and this release contains a number of significant improvements:
  • a jScrollPane now correctly scrolls when you tab to a focusable element within it [example]
  • a jScrollPane can now automatically re-initialise itself when images inside it load [example]
  • external (and internal) links to an anchor within a jScrollPane now correctly scroll the jScrollPane [example]
  • defaults settings are now user-settable [example]
In addition to these changes, jScrollPane now has a new home on googlecode. This makes it easier for people to keep up to date with the latest version and more importantly it makes it easier for me to track bug reports and issues with jScrollPane (something that was basically impossible on the jQuery plugins site). As you can see, there is already a number of issues raised (one of which has high priority) so there may well be a bug fix release soon. In the meantime, it would be good to get people testing the new release and seeing if I broke anything else while implementing these changes…


jScrollPane 1.2.1 was released very shortly after 1.2 to fix a fairly serious bug which prevented links within the scroll pane from working correctly. As always, the googlecode site has the latest version.

jScrollPane – Cross browser custom scrollbars

I’ve just released my latest plugin for jQuery – my favourite JavaScript library. It is a small (4KB) script which allows you to replace any vertical scrollbars on a div with overflow:auto with your own custom scroll bars. More info, demos and download here.

Switch stylesheets with jQuery

Update: I’ve released an updated version of this code which is more flexible. Please check it out.

I’ve just discovered jQuery which is an awesome JavaScript library. From the horse’s mouth:
jQuery is a Javascript library that takes this motto to heart: Writing Javascript code should be fun. jQuery acheives this goal by taking common, repetitive, tasks, stripping out all the unnecessary markup, and leaving them short, smart and understandable.
As an example of how succinct and easy code written with jQuery can be I put together a little example that allows you to add a stylesheet switcher to your site. Check out the example in action.

The stylesheet switcher allows your visitors to choose which stylesheet they would like to view your site with. It uses cookies so that when they return to the site or visit a different page they still get their chosen stylesheet.

The JavaScript code that powers the example looks like this:

* Styleswitch stylesheet switcher built on jQuery
* Under an Attribution, Share Alike License
* By Kelvin Luck ( )

   $(document).ready(function() {
         return false;
      var c = readCookie('style');
      if (c) switchStylestyle(c);

   function switchStylestyle(styleName)
         this.disabled = true;
         if (this.getAttribute('title') == styleName) this.disabled = false;
      createCookie('style', styleName, 365);

Then all you need to do is to add a class of “styleswitch” to any links that you want to activate the stylesheet switcher and a “rel” attribute which corresponds to the “title” attribute of the link tag embedding the stylesheet you want to switch to. Just view the source of the example and all should become clear…

I’d appreciate any feedback on the effectiveness of this technique. I think it should work fine on any browser that jQuery supports (I’ve tested on IE5.5, IE6 and FF1.5 on XP and Safari on OSX). It should degrade gracefully by going to the href of the link when jQuery isn’t supported or JavaScript is disabled. I have linked to a page which suggests possible ways to deal with this situation (disable JavaScript and try and switch stylesheets on the example to see the page).

If you would like to use this code then please feel free to download the zip