All posts in Tutorials

The Future of Web Apps: A look at the File API

Remember the bad old days when uploading files to a website involved clicking the browse button on a file input, navigating to where the file is, clicking open and then doing it all over again for multiple files! Well, those days are numbered thanks to the File API.

What is it?

The File API is a powerful API that allows developers to handle files from a users file system and manipulate those files to be used within a web application all done locally without server processing.

What you can do with it?

There are many applications and scenarios where the File API can be very useful. The most obvious is to use it with the Drag and Drop API to access the files on the drop event allowing drag and drop uploading of files such as images. When the user drops the file(s) you can convert them to a data URL to give instant feedback and show thumbnails of the images being uploaded asynchronously, creating a seamless experience for the user.

A few examples in the wild:

For this article I put together an example showing off the File API, this demo works in both Firefox 3.6+ & Chrome 6 dev. Drag and drop any file from your desktop and see what happens…

* Disclosure: That’s my own web app.

How to use it

There are two ways you can access a file and manipulate with the File API. The first is through a file input and the files attribute.

document.getElementById("fileinput").files

The code above accesses the FileList object which contains an array like sequence of the files. Each file has several properties available to it such as name, size and type.

The other method of accessing a file is through the Drag and Drop API which also includes the FileList object on the dataTransfer object which is available on the drop event in the DnD API.

event.dataTransfer.files

Both methods return the same array like sequence. Dragging and dropping multiple files can be handled and if the file input has the multiple attribute it can also handle multiple files.

FileReader

In order to do something with the FileList object and manipulate the files to display back to the user without the need for a server we have the FileReader object. It does it’s processing asynchronously so as not to lock up the Browser UI as it is processing the file(s).

var reader = new FileReader();

reader.onload = function (evt) {
    // do something with the file once it's loaded
    var data = evt.target.result, // file is stored in the result attribute;
          img = document.createElement("img");

    img.src = data;
    document.getElementsByTagName("body").appendChild(img);
}
reader.readAsDataURL(file);

The above code we create a new FileReader object, we setup our onload function so we can manipulate the file once it has been loaded into memory and the last function tells the reader what we want to do with the file. In our case return it as a DataURL. There are two other methods available which are

readAsText()

and

readAsBinary()

.

Inside the onload event we’ll create a new image element, set its source to the result attribute and append it to the document body. This will display the image back to the user straight away.

Handling large files – File URL

In the previous examples I’ve shown you how to load in a file and manipulate it to show it back to the user. All these methods are essentially creating a copy of the file(s), using readAsDataURL/Binary/Text etc, and loading it into your available memory. This creates a problem when uses start to load many or very large files. Say a user tries to drag in a video that’s a couple hundred MB or they drag in a few videos! This will create an incredible amount of data that needs to be loaded into memory and will bring any machine to a grinding halt and most likely crash the browser. Thankfully the File API creators and contributors have thought of this and added a very useful attribute on the FileReader object called url.

URL you say?

The url is basically a randomly generated unique string that maps back to a physical file on your hard drive. The reason that this is useful is that this unique string can be used in placea where a generic url can be used in a html document (e.g. an image). Setting the image source to that of the unique string generated by the File API will allow you to display the image back to the user without having to load it into memory.

<img src="moz-filedata:8616e48b-2a2b-418d-9ad4-5669858cf038" />

The above example shows what the image source will look like using the url attribute in Firefox 4.

Consider this scenario. You have a image uploader on your photo website, a user drags in their photos, the dropped photos appear as a nice grid of scaled down versions but the user sees an issue and realises that one of the images needs retouching. They open the file in a photo editor, do the retouching, go back to the web app and click the upload button. The beauty of using the url is the changed file will still be uploaded without the user having to re-add it to the upload list as it’s a live link to the physical image on the file system.

Firefox 4, so far, is the only one to support the url attribute and even then it already has a bug where the unique string will only display the image if it’s loaded through a file input. Trying to display the image from a drop event won’t work. Though it should be fixed by the time Firefox 4 get’s a stable release.

Take a look at this demo in Firefox 4 which uses a file input to load files using the url attribute.

// Code showing url
var droppedFileURL = file.url;
...
img.src = droppedFileURL;

The code above is simple. Rather than attaching an event to load the image into memory and convert it to a data URL, we simply loop through the files and access the url attribute on the file object and set that to our image source. Less work for the developer, less strain on the user’s computer and an all round better approach.

Where it’s headed

Browser support as of the time of writing is limited to 2 browsers, Firefox 3.6 & Chrome 6, with varying degrees of support for the File API specification.

The File API is one of the first in a line of many API’s which are being worked on. Such as the FileWriter & Media Interface (web cam access) which will all work together to create some amazing potential. This is just the beginning of what is coming and is a step closer in making web apps first class citizens in the desktop world. The line is getting blurry.

An Introduction to CSS3 – Creating a Button

This tutorial is just going to be a little tip introducing you to all the great things that CSS3 introduces. However, these things are not yet supported cross browser – Safari, Chrome and Firefox support most of the new features, Opera a few. But funnily enough IE does not, and IE versions 6 to 8 do not support any of the new code we’re going to write today. The IE9 preview introduces support, however for now you’re going to have to accept that this code will not work in IE. There are ways around this – using images as a fallback, or using Javascript. This will be covered in a later tutorial, however today we’ll only be focusing on what these new features are, not fallbacks. So, I suggest you load up the most recent versions of Safari, Chrome or Firefox and we will get going!

Set up a Link

We’re going to set up a basic link for us to transform into a nice button. No images allowed!

<a href="something.html">A Button</a>

Initial CSS

Nice and easy. I’ve also set up some basic CSS properties:

display: block;
width: 200px; height: 50px;
font-family: "Lucida Sans Unicode", Verdana;
font-size: 20px;
text-decoration: none; color: white;
text-align: center;
line-height: 50px;

You will notice I’ve set the text colour to white but no background. Don’t fret, as we’re going to do that shortly. Another neat trick is setting the height of the link to 50px but also setting the line-height to the same 50px value. This means that the text will be perfectly aligned vertically so it sits in the middle of the button.

Background Gradient

The first thing we’re going to do is add a background gradient. These are currently only supported in Safari, Chrome and Firefox 3.6+. Whilst Safari and Chrome are webkit based browsers, Firefox is not, and as such Firefox’s syntax is very different to Safari and Chromes. Eventually, once the CSS3 spec is confirmed, they will all use the same syntax, but no one knows. A very handy tool to do this is this Linear Gradient generator. There’s loads of other handy tools there which we will be mentioning in the future.

Webkit Syntax

Is like so:

background: -webkit-gradient(gradient types, start horizontal %, start vertical 0%, end horizontal % end vertical%, from(colour), to(colour));

Notice how we have to add “-webkit” to the front of the gradient code. Once everything is finalised, you wont have to, but for now we have to put up with it.
CSS3 also allows for radial gradients, however we wont be covering those today, we will be using a linear gradient. The first two percentage values decide where the gradient should start. If you’re doing a gradient from top to bottom, these will usually both be 0. The next two % values are for where the gradient should stop. A normal vertical gradient will have the values 0% 100% – that’s 0 from the left, and 100% from the top. The next two values are easy – which colour to start at, and which to end at. You can also add colour stops, which are done by adding this code after the final part of the gradient declaration:

, color-stop(.6,#333))

The .6 is how far along you wish to add the stop, the the colour is, well, the colour you want the stop to be.

We’re not using colour stops today, we’re going to create a simple orange gradient for our button, using this code:

background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#D9AE38), to(#D65D00));

That code is for webkit, and now we need to same code for Firefox. Lets do it.

Firefox Syntax

Firefox sadly does it all its own way.

background: -moz-linear-gradient(horiz start % vertical start% angle in deg,end colour, start colour);

For a start, this time the code is -moz-linear-gradient, not just -gradient as it is with webkit. The first value defines the horizontal position, the second % value is the vertical one. It’s not as clear cut as the webkit code, in fact, it’s hard to explain. I highly suggest you head over to the linear gradient generator using Firefox and mess around yourself. Another important note is that the colours are the reverse of what you might imagine, especially doing a linear gradient. Webkit does it going “down” whereas Firefox orders the colours going “up”. The code for our button looks like this:

background: -moz-linear-gradient(0% 75% 90deg,#D65D00, #D9AE38);

Finally, one easy fallback that takes little effort is just adding a colour. So, our final code (for Webkit/Firefox) looks like below. Other browsers will just display the colour.

background: orange -webkit-gradient(linear, 0% 0%, 0% 100%, from(#D9AE38), to(#D65D00));
background: -moz-linear-gradient(0% 75% 90deg,#D65D00, #D9AE38);

And the results are like so:

Border Radius

The gradient code is not very easy, but border-radius (or “rounded-corners” to me and you) is much more simple. It’s like so:

-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;

The first two declarations are for Webkit and Firefox. The third is the generic one, which is supported by Opera. The higher the value, the more rounded the corners are. Once you’ve added those, your button should be taking shape nicely!

Box Shadow

This is supported in Safari, Chrome, Firefox and Opera but does use vendor specific declarations once more. Opera uses the default without any vendor extras.

box-shadow:horizontal offset px vertical offset px blur px #colour

Once more the same site that had the linear gradient generator has a superb resource for generating box shadows. Horizontal and vertical offsets point out how far down and across the shadow occurs on the box. The blue is simply how blurred the shadow will be, 0px gives you a very crisp shadow, whilst a higher level blurs it a lot more, almost like smudging it.

We’re trying to be slightly subtle here, so here’s the code we’re adding:

-webkit-box-shadow:2px 2px 2px #333333;
-moz-box-shadow:2px 2px 2px #333333;
box-shadow:2px 2px 2px #333333;

This is where you might see the downside of CSS3 and all these vendor declarations. There is a lot of repetition.

Now our button should look like this:

Text Shadow

Text-shadow actually existed in CSS2 but was removed in 2.1. It’s now back in CSS3 and is supported by all but IE. No vendor specific additions required and the code is really simple.

text-shadow:horiz offset px vert offset px blur px #colour;

It’s identical to the code for box-shadow. Again you can mess around with this on the same site as before, the idea here is to experiment until you get it right.

Our code looks something like this:

text-shadow:2px 1px 1px #000;

And our button is complete, and looks like so:

All Done

In future posts we’ll look at fallback solutions in browsers that do not support these new features, but for now I hope you enjoyed this little dive into CSS3. Any problems, get hold of me on twitter and feel free to ask anything.

jQuery: More Tips & Tricks

Load from Google CDN

Google’s CDN (Content Delivery Network) hosts jQuery for you to include on your site. The advantage of this is two-fold: firstly, if the user has visited other sites that loaded jQuery from the CDN (of which there are a lot) then they will already have a version of jQuery cached, which means it will not be needed to load again. Secondly, you can specify a certain version to load. For example, this code would load version 1.4.2:

<script type="text/javascript" src=http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

However, if I wanted to load the most recent version, I could just do this:

<script type="text/javascript" src=http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

That will include the most recent version, up to version 1.9.9. However this is not recommended, as an upgrade to jQuery may well break your scripts. It’s generally suggested that you stay within a version, for example:

<script type="text/javascript" src=http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

jQuery takes CSS Selectors

Remember, jQuery functions will take any valid CSS selector. But a selector can contain multiple selections. For example, you might do this:

$(elem).siblings("h2").hide();
$(elem).siblings("p").hide();

But why not just do this?

$(elem).siblings("h2,p").hide();

Chain over lines

Remember, white space means nothing in Javascript, so whilst you might have this:

$("elem").hide().addClass("something").show().attr("alt","something else").fadeOut("slow");

If you struggle to read that, you can do this as well:

$("elem")
	.hide()
	.addClass("something")
	.show()
	//etc etc etc

There’s no bonus in either performance wise, it’s just down to readability. A lot of people don’t realise they can split it over multiple lines.

More Context

I know I discussed context in my last article, but I wanted to add a bit more. Last time we discussed adding a context like so:

$("#someElem", "div");

I know that’s a poor example, but bear with me! When you do this, all jQuery does is call the find() function on the div and search for “#someElem”. So the above code gets translated into this:

$("div").find("#someElem")

Which way you use is totally up to you. Personally I find the 2nd method (using .find()) to be much easier to understand when quickly scanning a document, but it’s up to you.

Check if an Element Exists

This is more a quick code snippet, but if you wish to check if an element exists, it’s so easy!

if($("elem").length) {
//the element exists
}

If it does not exist, jQuery will just degrade gracefully, no errors, nothing bad happens.

Run onLoad

This is pretty common knowledge, but to make sure jQuery only runs once the DOM is ready to be manipulated, you need to call jQuery’s .ready() function:

$(document).ready(function() {
//code in here
}

What is perhaps not as well known is that you can shorten this:

$(function() {
//code here
}

Or alternatively, you can add all your javascript just before the closing tag and not need to bother with the onLoad code:

....all your normal code here
<!--then add your javascript here, firstly loading jQuery.js and then your code-->
</body>

Add a JS Class to the Body

An easy way to detect if Javascript is on is to add a class to the body, so the first line of your Javascript would be:

$(body).addClass("javascripton");

Whilst this might seem pointless from a Javascript view (if Javascript isn’t on you wont be able to check via an if statement), this is useful for CSS. You might have some elements that might change style, so any CSS styles that might change via Javascript, just add “.javascripton” in front of the styles in your css file.

Store information with jQuery’s data method

jQuery provides its own method for storing data to be used later on. To save some data is pretty easy:

$("elem").data("someVariable", 39);

And to return it:

$("elem").data("someVariable") //returns 39

I’ve seen people use all sorts of tags to store information to be used with their Javascript code, title tags, alt tags, rel tags, etc. Use this. Note: I believe HTML 5 may well include some form of data attribute, but for now, stick with this.

Surrender $

If you are using another library that uses the “$” symbol, jQuery allows you to pass that on to be used by the other library and still use jQuery:

jQuery.noConflict();
//now instead of $, use jQuery
jquery("elem").hide();

You can also make use of a closure. Whilst explaining this is slightly out of the scope of this tutorial, this is how you use it:

(function($) {
//in here, $ relates to jQuery
$("elem").hide()
})(jQuery)
//out here, $ does not relate to jQuery
$("elem").hide() //WILL NOT WORK
jQuery("elem").hide() //works

And that’s it.

I hope you’ve found these tips useful and helpful. I’m planning a lot more similar posts in the future. If you have any suggestions the best place to get in touch with me is Twitter – @Jack_Franklin.