Latest articles

Flickr client 1.3.0 adds search

In a previous article we introduced our Flickr JSONP client. We’ve just released a new version which adds some methods wrapping the Flickr search API. Here’s a quick demo.

The two new methods on the Flickr.Client class are search and getSearch; as with the other parts of this API, the first returns the raw Flickr data feed while the second wraps the returned photos in a nicer interface as instances of the Flickr.Photo class.

Download Flickr JSONP Client 1.3.0

Here’s a simplified version of the demo above; it searches Flickr for photos matching the search term "orchids", and drops the resultant photos into the page.

Client = new Flickr.Client('myflickrapikey');

Client.getSearch("orchids", function(photos) {
    var outputArea = Ojay('#photo-feed');
    
    photos.forEach(function(photo) {
        var image = Ojay.HTML.img({
                alt: photo.getTitle(),
                src: photo.getThumbnail()
            }),
            
            link = Ojay.HTML.a({
                href: photo.getLink()
            }, image);
        
        outputArea.insert(link);
    });
});

The new methods are both documented in the project README file.

Ojay 0.5.0

Ojay 0.5.0 is the latest release of Ojay, the OTHER media’s JavaScript library. As well as the usual bug fixes, and bumping core dependency JS.Class to version 2.1.5, the release includes several new features. You can compare the new version to the previous release, 0.4.2, on GitHub.

FilmStrips

We’ve added the Ojay.FilmStrip class to the Paginator package. This is a Paginator variant which allows for a single row or column of elements which vary in width or height respectively. You can see it in action on Paul Smith World.

Both FilmStrip and the existing Paginator class share a common core: the new Paginatable module, which can be included in your classes to create new, paginator-like user interface elements.

Overlay close buttons

Fed up with implementing your own close buttons for Ojay.ContentOverlay? We were, so we’ve added a new addCloseButton method. It accepts the same parameters as the hide method, so you can set it up to close the overlay however you like.

Below is some example code showing how you can rig things up so an associated page mask is also hidden when the close button is clicked.

var overlay = new Ojay.ContentOverlay(),
    mask    = new Ojay.PageMask(),
    close   = overlay.addCloseButton('zoom');

close.on('click', function() {
    mask.hide('fade');
});

Bug fixes

This release includes several important bug fixes. Firstly, some cross-browser problems with the DomCollection#set method, which sets properties on Ojay’s collections of DOM elements, have been resolved.

A bug in the Ojay.History module where URIs were being decoded twice has been fixed.

Finally, a bug where the creation of input elements failed in Internet Explorer 9 has also been fixed. Thanks to Urban Etter for reporting both problem and solution.

Flickr JSONP client

The Flickr API is renowned for being one of the most extensive and useful out there, and the response formats they provide include a raw JSONP service. This brings the full power of Flickr’s API to pure client-side applications, that is, ones involving no intermediate servers whatsoever—just the end user’s web browser and the Flickr servers.

Here’s a little demo we rustled up with our new Flickr JSONP client, which we’re now releasing as open source code under the BSD license. Just enter a Flickr username into the form, and it will display their recent photos.

This only scratches the surface of what’s possible with this library. It can query groups, find photos of people, and much more.

Download Flickr JSONP Client 1.2.0

The project README includes a full set of API documentation. Because the Flickr API is so extensive, we don’t provide wrappers around every method, but it’s extraordinarily easy to extend, so do let us know what you’re using it for.

Location Picker

There are many situations under which one might want to save the latitude and longitude of a particular spot, and rarely will one know precisely what those coordinates are. Our newly open-sourced Location Picker library solves this problem by tying Google Maps’ API to HTML forms, so you can place a marker in exactly the right spot and then extract the location data.

This makes inputting location data simple and intuitive: simply search for the approximate location (for example, with a post code), then move the marker to the exact spot you want to determine the coordinates of. Here it is in action; just change the text in the search field and submit the form to change the position of the pin, then drag it to a more precise location.

 

The Location Picker library is released under the BSD license.

Download Location Picker 1.0.2

Once you’ve set up the necessary bits of HTML (this is spelled out in detail in the README), you just need to create a new instance of the LocationPicker class:

var locpick = new LocationPicker('after', '#dataForm', {
    width:      600,
    height:     400,
    latField:   '#lat',
    lngField:   '#lng'
});

Generally, this will be sufficient for most needs, but if you need to access the widget’s API directly, all the methods are documented in the README. For example, you might want to call the search method directly:

locpick.search("1 Newham's Row, SE1 3UZ");

As you might expect, if you’re using Helium it’s exceptionally easy to use: just set the Helium.GOOGLE_API_KEY constant to your Google API key, and use require to pull in the LocationPicker object (have a look at the source code of this page for a live example). Full details of the custom loader function you’ll need to add to your Helium installation are also available in the README.

Shortener, a bit.ly API wrapper

One of the OTHER media’s major clients is the England and Wales Cricket Board. The ECB are very keen on reaching out to cricket fans, including via social media services such as Facebook and Twitter.

They asked us to provide a way for visitors to the ECB website to tweet about their articles, such as this one on Andy Flower’s challenge to the England batsmen. If you scroll down to the end of article, you can see what we came up with: a link to Twitter which pre-populates the “What’s happening?” field with the title of the article and a link to it.

However, many of the links on the ECB website are quite long—too long for Twitter’s 140 character message limit. Because Twitter’s web interface doesn’t provide a URI-shortening service, we decided to shorten the links before they got there.

The obvious candidate for performing this URI shortening was bit.ly. In addition to being one of the best-known shortening services, they have a rich JSONP API which we could hook into.

In fact, the bit.ly API was a bit too rich: all we wanted was a simple way to shorten URIs, that we could include in multiple projects and which would be usable by any frontend developer, without needing them to have a deep knowledge of a complex API or even a huge amount of JavaScript expertise.

To solve this problem, we developed a simple wrapper library called Shortener, which we’re now releasing as open source software under the BSD license.

Download Shortener 1.0.1

The library essentially provides just one object and one method, which you use like this:

Shortener.shorten(link, function(result) {
    if (result.statusCode != "ERROR") {
        window.location.href = result.shortURL;
    }
});

Full details of how to use the library are available in the README, and a test case with some example code can be found in the test directory. Unlike some of our other libraries, apart from the bit.ly JavaScript code it has no external dependencies, and with the addition of a small custom loader function it also works transparently with Helium.

Filling the screen with pictures

When we were developing the new Paul Smith website, one of the requirements was for an immersive visual experience, able to act as a channel to convey Paul Smith’s unique style and the look of the latest season, as well as directing visitors to all parts of the site.

Our design team came up with a fairly radical approach: instead of embedding images within a web page, images would be the web page, with branding, navigation and promotional components layered over them.

Originally the intention was to build this in Flash, with a fallback to an HTML version to satisfy accessibility and searchability requirements, but during the specification process we realised that it might be possible to develop it purely with HTML, CSS and JavaScript. After spending a couple of days developing rough prototypes, it became clear that this was an achievable goal, and we began work on the library we’re now releasing as open source, Edgecase.

Download Edgecase 1.1.0

The key component of the library isn’t that it merely fills the viewport when a visitor first arrives on the page; it’s that if they resize their browser window, the image resizes to fill it. You can see this in action on the Paul Smith collections page: just open the site and resize your browser window.

Because the library is designed to resize images, we have to take care to preserve the original aspect ratio of each element. This is achieved by measuring the size of the viewport whenever it changes, and working out whether it’s wider (proportionally speaking) or taller than the image. This is easier to represent visually: in the diagram below, the red rectangle represents the browser window, while the blue rectangle represents the image being scaled.

As you can see, the resized images are (unless the aspect ratios happen to be equal) actually larger than the viewport, and are then positioned so that the centre point of the image is the same as the centre point of the viewport.

Documentation on how to actually use the library is available in the project’s README file. It’s a very straightforward piece of code, so if anything is unclear, a quick look at the source should clear it up. As with all our libraries, it plays nicely with Helium out of the box.

In addition to the underlying image resizing functionality, the Edgecase library also includes a higher-level component built on top of it, EdgeGallery. This is what powers the Paul Smith home page: it’s a simple rotating gallery, with each image fading over the previous one at given intervals. However, because it fills the entire browser window, the repaint required can degrade performance.

One way we’re improving this is by using CSS Transitions in browsers which support them, rather than traditional animation techniques. Currently it only works on recent versions of Safari, Chrome and Opera, but Firefox 4 will support them, and we hold out hope that Internet Explorer 9 will eventually add them too. Because the animation simply falls back to YUI’s animation library, it works perfectly well in older browsers too—just not quite as smoothly.

Edgecase is released under the BSD license; you can find the full text in the LICENSE file. If you run into any bugs, or have an improvement you’d like to suggest, do get in touch.

Open-sourcing our accessible YouTube controls

YouTube’s embedded player works well in many ways, but it does have some deficiencies. To begin with, you can’t customise its appearance to fit with the design of the website you’re adding it to. Worse, various key pieces of functionality are not available to the keyboard alone, and because the controls are all in Flash, in many browsers they’re not accessible at all.

Given these problems, it gives the OTHER media great pleasure to release a highly accessible, skinnable set of YouTube player controls. Here they are in action:

Using the YoutubePlayer class is very straightforward. First, create a container to insert the video into; normally this is just an empty div element. Then set the YoutubePlayer.API_KEY to your YouTube API key. Finally, create a new instance of the YoutubePlayer class, passing in the ID of the YouTube video you want to embed, the id attribute of your container, and (if you want to configure the player further) an options object.

<div id="videocontainer"></div>

<script type="text/javascript">
    (function() {
        YoutubePlayer.API_KEY = '_your_youtube_api_key_';
        
        var player = new YoutubePlayer('_video_id_', 'videocontainer', {
            height:      400,
            skipTime:    30,
            volumeSteps: 4
        });
    })();
</script>

A more detailed writeup is available in the project’s README file. The main dependencies are Ojay and version 2.0 of SWFObject. Of course, you can easily avoid dependency hell (as well as potentially improving the load times of your pages) by using Helium.

So, why HTML controls? Leaving aside for the moment the fact that not all functionality is available, even in a reduced form, in the embedded YouTube player, why should we implement our controls as HTML—and not, for example, as another embedded Flash object?

Essentially, HTML is inherently accessible in a way that Flash—even well-intentioned and well-written Flash—is not. The OSU Web Accessibility Center explain in more detail:

One problem with Flash, however, is that in many browsers it is not accessible to the keyboard alone. Another problem is that screen reader programs for the visually impaired cannot always accurately discern the function of controls implemented in Flash, and some screen readers cannot access Flash controls at all.

For example, all browsers running in MS Windows except Internet Explorer cannot get focus to a Flash movie using the keyboard alone—a user must hover over a movie with the mouse and click. Tabbing into the movie is not possible. Once in the Flash movie controls for the YouTube video, all browsers other than IE are “trapped”, tabbing through the player controls perpetually, unable to access any other parts of the web page.

The problem is similarly difficult for screen reader users. A portion of experienced users of screen readers will know that they must turn off their screen reader’s regular page browsing mode and go into a “pass-through” mode to be able to read the buttons in the YouTube player, but even then the only usable buttons in the Flash-based YouTube player are Play and Mute. And if you happen to be using VoiceOver, the screen reader in Mac OS X, Flash controls are inaccessible.

The key improvements made by our library are simple: all the controls are simple HTML elements, albeit generated by JavaScript. Importantly, the main controls are all button elements. This means that users can access them via the keyboard just by hitting the ‘Tab’ key, without any need for mode switching.

Furthermore, all the major pieces of functionality are available via keyboard control: play/pause, skipping forwards and backwards, and raising and lowering the volume. There’s a marginally more powerful interface for users with pointing devices, since they can click on any of the volume bars or anywhere in the playback bar to seek to that point, but both these ends can be achieved with the keyboard alone.

Modifying the default design or writing a whole new one should be easy for anyone with a basic knowledge of CSS. After all, it’s just HTML, and every element has a class indicating its purpose and allowing it to be styled. The default CSS file should be fairly self-explanatory.

If you’re going to use it on your own site, you may need to change the URLs for the default graphic so that they point to the correct location on your website.

Broad compatibility with commonly-used web browsers is important to us, as many of our clients’ sites have a lot of visitors still using older browsers such as Internet Explorer 6. We’ve tested the library in most commonly-used browsers, including Safari, Firefox, Chrome and Internet Explorers 6, 7 and 8.

We’re releasing our YouTube player library under the BSD license. You can find the full text of the license in the LICENSE file in the library source code. We hope you find it useful, and if you find any bugs or add any new features of your own, please let us know!

If you’re interested in how the library works under the hood, check out James Coglan’s blog post on dispatching YouTube API events, published when he wrote the initial implementation of this library.

Ojay 0.4.2

Ojay 0.4.2 is the latest release of Ojay, the OTHER media’s JavaScript library. It’s primarily a maintenance release, fixing a few long-standing issues with Ojay 0.4.1. You can see all the changes in Ojay 0.4.2 on GitHub.

We’re hoping to start writing more comprehensive release notes for each new version, expanding on the rather terse listings in the changelog, so Ojay users don’t have to go wading through changesets just to understand what’s changed between versions.

ClearType is now reinstated when setting an element’s opacity to 1

Internet Explorer versions 7 and greater disable ClearType when a DirectX filter CSS property is set on an element. One common use of filter is to change the opacity of an element—for example, when fading it in or out. When an element’s opacity is changed to 1 (fully opaque) Ojay now removes filter properties, so that ClearType rendering is re-enabled. Thanks to George MacKerron for reporting this issue.

JSONP cleanups and improvemnts

Several improvements were made to Ojay’s JSONP code, including the addition of a URI#removeParam method to remove a parameter from a URI, and fixing a callback generation/cleanup bug.

Ojay.changeAlias now works in Internet Explorer

As with jQuery, Ojay by default is aliased to $. The Ojay.changeAlias function lets users change this—for example, to _. However, the implementation used the delete operator which Internet Explorer doesn’t like using on global objects. This is now fixed, so Ojay.changeAlias works correctly in Internet Explorer. Thanks to Thom Nichols for reporting this issue.

Tabs no longer animate when created

When creating a new set of tabs with Ojay.Tabs, the first page used to fade in when the tab set was created. Given how much work is done by the browser when a page is first rendered, the overhead was undesirable. This behaviour has been changed and tabs no longer animate when first created. Test coverage for the tabs module has also been improved.

Ojay.Forms.Select now respects disabled attributes

Any option element within an HTML select element can be disabled, and this should be reflected within input replacements like the Ojay.Forms.Select class. Unfortunately, until now that wasn’t the case—disabled options could not be selected, but this was not visible to the user, so they might inadvertently select a disabled option and end up submitting an option they did not intend to. This has now been rectified.

Removing all elements from a Paginator no longer causes errors

Paginators come with push, pop, shift and unshift methods, just like arrays. Because of some missing guard clauses, it wasn’t possible to remove all the elements from a paginator and then start adding new ones. We’ve fixed this issue, making it easier to dynamically update paginator contents.

Accordions enforce their single-pane restriction better

Previously, it was possible to open several sections of an Accordion—in contravention of the intended design—by clicking on the toggles while the expansion/contraction animation was in progress. We mixed in the JS.State module and made a few other architectural tweaks to remove this behaviour.