Creating Custom JQueryUI Buttons for a Toolbar

For the last several months I’ve been neck deep in Javascript, and JQuery has become an invaluable tool in my arsenal. JQuery coupled along with JQueryUI provides such an incredible amount of power and flexibility, I can’t even imaging trying to create web applications without them anymore. With all that power though, is surprising little documentation for some aspects of it. One such place I found myself recently was when I was tasked to create a toolbar for my application. Now, a toolbar seems such a “no-duh” thing, but I didn’t want to approach creating one the old fashioned way. I wanted to leverage JQueryUI to its fullest. So, here I write a tutorial that tries to explain more about creating toolbars with JQueryUI than what is provided by JQueryUI’s own documentation.

The Old Fashioned Way

So why bother with using JQuery and JQueryUI  at all? Well, let’s take a look at the good old fashioned way to do a toolbar. Toolbars are so taken for granted; they appear in everything we use. It’s not until you start to try and build one do you start to feel the magnitude of the undertaking. Think about that for a moment, if you look at an application like WordPad in Windows, you’ll see that it’s toolbar consists of over 20+ buttons.

So keeping in mind we may have lots of buttons, for our sake let’s just say we need 20 buttons. So we start drawing our buttons. Once we are done or close to it, we need to export them for our web application… But wait, we just can’t have one state for each button, we need at least 4; normal, hover, down and selected. Which means now we don’t have 20 elements, we have 80! But that’s ok right, we can use Photoshop and it’s layers, so we can create 4 layers to represent each state, and 20 layers for each button icon right? But wait, doesn’t the down and hover state show the icon in a different color? OK, so now we’re up to 40 layers to represent our buttons and 4 layers for each state. Now, the fun will be to export them all to web ready assets. When done, you’ll probaby end up with a folder that looks like this:

Lots of Images!

 

Now you go through the exercise of putting it all into an HTML and CSS page, wire it all up and it looks great. But wait! The color is wrong!, the site theme changed, and now your backgrounds colors are all wrong! So it’s back to Photoshop tweak and export again. Rinse and repeat this cycle of madness as necessary.

Isn’t there a better way than this insanity? Well, yes there is. 

JQueryUI provides a Button object that can be combined into a toolbar. The powerful component lets you specify standard form elements in HTML as a button. So, for example we can change a radio button, checkbox or even a standard input submit button into something more pleasing to the eye with just this line of code:

$( "input:submit, a, button", ".demo" ).button();

The snippet above turns anything that’s an input submit, URL Href, input button or anything with a css class of demo into a button. Pretty sweet. That concept can then be carried further into a toolbar. Let’s take a look at that a bit more.

JQueryUI’s Button Toolbar Documentation

Over at JQueryUI’s web site, http://jqueryui.com/demos/button/#toolbar, there is a sample of using JQueryUI buttons in a toolbar. The example seems simple enough, and clearly shows how you can add buttons to a toolbar. But the example doesn’t go into really explaining how to implement your own. So after much flailing about, I figured out how to do it.

JQueryUI’s approach is to implement CSS SpriteSheets. A Spritesheet, in case you don’t know, is a single image that can contain multiple image elements that can be broken up into chunks, so instead of 40 button images, we can have one, I’ll explain more a little further down.

If you dig a little into a JQueryUI Theme’s css file, you’ll see these CSS elements:

.ui-icon { 
     width: 16px; 
     height: 16px; 
     background-image: url(images/ui-icons_999999_256x240.png); 
}
.ui-icon-carat-1-n { background-position: 0 0; } 
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }

What these lines represent is a single image that is used to represent all the button images and are displayed through background position offsets. Which essentially means that button one’s icon is at 0px x 0px, and the next one is 16pixels next to it and so forth. If you load that image in question, it’ll be evident.

One of JQuery UI’s button sprite sheets

Taking Things to the Next Level

So how do we exploit this for ourselves? Well, one way would be to change the JQueryUI file or add your images to it, but that’s not really advisable, since you could potentially update the JQueryUI theme and lose all your additions. The best will be to create our own spritesheet.

Here’s my example:

My toolbar spritesheet

As you can see I have 30 button icons in that single file. It’s also important to note that the file is a png24 with a transparent background. I could have used a .gif file too, but the png is 24bit so there’s more colors available. It never ceases to amaze me how much detail can be crammed into a 16×16 pixel square.

So how do we then combine our stuff into JQueryUI’s? It’s a little CSS trickery and of course, our own CSS for our buttons. Observe:

First thing we MUST do is make JQueryUI use OUR image for the buttons and not their default. So in our own CSS file we override the .ui-state-default .ui-icon class with our own:

.ui-state-default .ui-icon { background-image: url(../images/mySpriteSheet.png); }

Having our own class of a similar name in our own CSS will override the JQuery one. The next will be to define all our buttons. 

.ui-button .custom-1 { background-position: 0px 0px; }
.ui-button .custom-2 { background-position: -16px 0px; }
.ui-button .custom-3 { background-position: -32px 0px; }
.ui-button .custom-4 { background-position: -48px 0px; }
.ui-button .custom-5 { background-position: -64px 0px; }

I didn’t do them all here, but hopefully you get the idea; what I’m doing on each line is making a CSS class for each of my buttons based off of the position of the image on the big one. They need to be of type .ui-button, which is why they all have that before the button name.

Then in your code you can now create button objects for your toolbar with the following code:

<script language="javascript">
$(function() {
// 1 button
$( "#tb_1" ).button({
text: false,
icons: {
primary: 'custom-1'
}
});
// 2 button
$( "#tb_2" ).button({
text: false,
icons: {
primary: 'custom-2'
}
});
});
</script>

In the HTML portion:

   <button id="tb_1">Custom Button 1</button> 
<button id="tb_2">Custom Button 2</button>

Rinse and repeat for your other buttons. With this setup you are free to place these elements within other DIV tags and format them as needed to create your toolbar. 

So, what makes this better then the old approach? Well, for starters you have ONE image. The next is because your images are just icons on a transparent background, there is no need to create the various states of the button, JQueryUI already has that taken care of with its theme, and can easily be changed out. If the background of the buttons starts out gray, but then it gets changed to light blue, that’s fine, just change out the CSS for the button background and your buttons are done. The only reason you may go back to the image file is to tweak the icons as necessary… Maybe the one you made looks bad on a light blue background instead of gray. That’s fine, you edit one file and save it out and viola, you’re done! You need more icons? Well, sure, just make the image bigger, add more at the end, then just tweak your CSS to make more entries for your new buttons! 

The savings will also add up in performance too, instead of your browser making 40+ trips back to your website to pull each toolbar button, you make one quick trip and you have them all! Everyone wins!

Hopefully this tutorial was helpful, but I only scratched the surface. There are other considerations, such as disabling and grouping buttons, which isn’t really covered in detail in JQuery’s documentation either. So stay tuned for additions to this series. Thanks for reading, and please leave comments.

You can download the source files for this tutorial here.