Archive for the 'jQuery' Category

Expanded Google Analytics Plugin

Despite numerous requests, I have either been too busy or too lazy, or both, to update my gaTracker plugin to support the new ga.js script from Google Analytics. Hence, I am very interested in trying out dvdsmpsn’s jGoogleAnalytics plugin, which not only converts my original plugin to work with ga.js, but also adds a slew of additional features for more fine-grained control over the tracking. It appears to be a pretty solid effort, and does pretty much everything I had planned to do with mine. I’ll report back once I’ve had a chance to put it through its paces.

jQuery File Tree

Cory S.N. LaViska over at A Beautiful Site has created a very nice jQuery plugin for displaying file trees called, naturally, jQuery File Tree. The great thing about it is its simplicity. It doesn’t have an overabundance of bells and whistles, but it’s super easy to integrate with a simple API (it even includes Lasso support), has plenty of hooks to add your own custom functionality, and generates nice clean markup. Check it out!

jQuery Combo Select Redux

As a followup to my previous post on creating comboselect boxes in jQuery, I have automated the process of transforming a normal multiselect input element into a comboselect with the (aptly named) comboselect plugin.

With the plugin, you start with a normal select input, and transform it using a few simple options. You can decide which sides get resorted after a change (none, left, right, or both), and also specify the labels for the buttons which control movement from left to right and vice versa. You can also move items from side to side by double clicking them. The default sort option is “both”, and the default button labels are “>” and “<”. The plugin passes the list of selected items back to the original form input, so the form submission works the same regardless of whether the plugin is used.

Sample usage is as simple as:

$('#somelist').comboselect();

Or, with options:

$('#somelist').comboselect({
	sort: 'right',
	addbtn: ' Add ',
	rembtn: ' Remove '
});

To see the plugin in action, check out this simple demo page:
http://devblog.jasonhuck.com/assets/comboselect_plugin/

You can download the comboselect plugin here:
http://plugins.jquery.com/project/comboselect

The download contains the source of the demo, including a sample CSS file and the Selso plugin, which is required for sorting.

Combo Select Boxes In jQuery

Although the standard <select> input for HTML forms supports a “multiple” attribute which allows users to select multiple options by control- or command- clicking, it’s easily one of the most confusing concepts for users to grasp. It’s also fairly clumsy, especially when the list of options is long. It’s difficult for users to see which options they have already selected, and if their previous selections scroll out of site, they get nervous that those choices will be lost when they make additional selections.

A more friendly and intuitive solution is to allow the user to create a new list of selected items by moving them from the original list into the new list. This keeps their (usually much smaller) list of selected items in constant view, and removes those items from the original list, making it shorter and easier to scan for any additional items they might wish to add.

I’ve been using these “combo select boxes” for many years, but a recent project provided me with the opportunity to recreate them with better markup, and using jQuery to control the behavior.

The Markup

I wanted to keep the markup as light and simple as possible, so I stuck with basic form elements. Classes are used as the “hooks” for the javascript so that you can manage multiple lists in a single page.

  • There are two <select> inputs, classed “left” and “right” — users will move items from the left (original) list to the right (new) list.
  • There are two <input> elements of type “button”, classed “add” and “remove”, to control the movement of items between the lists.
  • The buttons are wrapped in a <fieldset> so that they can be positioned as a group via CSS.
  • The grouped buttons and the two lists are wrapped in an additional <fieldset>, with an associated <label> element, so that the entire control can be treated as a single element when integrated with the rest of your form.
  • The one slightly unusual bit of markup here is the addition of an ID on each <option> element. This helps us keep the lists sorted as items are moved between them (explained below).
<label for="letters">Letters</label>
<fieldset id="letters">
	<select id="lettersleft" name="lettersleft" class="left" multiple="multiple">
		<option id="opt1" value="1">AAA</option>
		<option id="opt2" value="2">BBB</option>
		<option id="opt3" value="3">CCC</option>
		<option id="opt4" value="4">DDD</option>
		<option id="opt5" value="5">EEE</option>
		...etc...
		<option id="opt26" value="26">ZZZ</option>
	</select>
	<fieldset>
		<input type="button" class="add" value=" > " />
		<input type="button" class="remove" value=" < " />
	</fieldset>
	<select id="lettersright" name="lettersright" class="right" multiple="multiple">
	</select>
</fieldset>

Adding Behavior

jQuery’s built-in DOM manipulation methods made short work of the basic functionality. I used .parent() to traverse back up the tree to the master <fieldset>, and .find() to target the left and right lists respectively. Moving <option> elements between the two lists is a snap with .append():

$('input.add').click(function(){
	var left = $(this).parent().parent().find('select.left option:selected');
	var right = $(this).parent().parent().find('select.right');
	right.append(left);
	sortBoxes();
});

$('input.remove').click(function(){
	var left = $(this).parent().parent().find('select.left');
	var right = $(this).parent().parent().find('select.right option:selected');
	left.append(right);
	sortBoxes();
});

You’ll notice the call to a sortBoxes() function. The usability of this type of control is greatly enhanced if the lists are sorted as each change is made. For that, I used Guillaume Andrieu’s Selso plugin <http://plugins.jquery.com/project/selso>. A cool feature of this plugin is that it can simultaneously sort multiple lists with the given criteria, since it sorts individual elements within their respective parents. So, all I had to do is select all of the <option> elements from the left and right lists, and tell the plugin how I wanted them sorted. I also deselected any selected elements:

function sortBoxes(){
	$('select.left, select.right').find('option').selso({
		type: 'alpha',
		extract: function(o){ return $(o).text(); }
	});

	// clear all highlighted items
	$('select.left, select.right').find('option:selected').removeAttr('selected');
}

And that’s it! As usual with jQuery, not a lot of custom code required. I considered wrapping this up into a plugin, but I think I’ll wait until I’ve used it in a few more places to see what options would be the most useful. You can try out a demo here: <http://devblog.jasonhuck.com/assets/comboselect/>.

Google Analytics Integration with jQuery

Google Analytics is now an essential part of every site we produce. Unless you’ve been living under a rock, you should know that Google purchased Urchin, an industry-leading web analytics package, a few years back, and made a web-based version of it available for free. (Thanks, Google!)In contrast to traditional web log analyzers, Google Analytics collects data via a JavaScript (urchin.js) you add to each page you wish to track. On each page load, a function in the JavaScript (urchinTracker) requests a GIF file from Google and appends a query string full of data onto the request.

When you sign up for a Google Analytics account, you’re provided with a javascript code snippet which includes a unique account number, and you’re instructed to include this snippet on every page in your site that you wish to track. At a glance, this appears to be “all there is to it”, but of course you can do much more.

The Analytics site provides a few recommendations for tracking certain user activity that a single call to urchinTracker doesn’t catch on its own. It’s far from a comprehensive guide, but at this point the capabilities of the script have been pretty thoroughly reverse engineered by end users.

For instance, your web site may include resources that are not standard web pages. Things like PDF files, MP3’s, ZIP archives, etc. Since there is no way to embed the tracking script directly within these resources, we must instead track when users click on links to those resources from within other pages. Similarly, you may also wish to track links to external sites and/or mailto links. If you own an e-commerce site, or want to take advantage of the “campaigns” feature of Google Analytics, the customization can get even deeper.

Identifying and marking up these types of links is simple in concept, but difficult in practice in a modern site where multiple users may be contributing content through a CMS with no knowledge of HTML or JavaScript. Clearly, some form of automation is required. I decided to write a jQuery plugin to make embedding Google Analytics simpler for typical web sites. Currently the plugin does the following:

  • Determine whether to include the SSL or non-SSL version of the GA script.
  • Include the GA script from within try/catch to help suppress any issues GA may have from time to time.
  • Set the _uacct variable to your GA tracking code.
  • Call the urchinTracker() function once for the initial page load.
  • Examine all of the links on the page and attach onclick events to:
    • External links.
    • Mailto links.
    • Downloads.
  • Call urchinTracker() when these links are clicked, prefixing them appropriately.

In addition to the tracking code, the prefixes used for each of the link types above, as well as the extensions considered “downloadable files” are configurable by the user.

It requires jQuery 1.2 or higher for the cross-domain $.getScript() call. Usage is simply:

$.gaTracker('UA-XXXXX-XX');

Or you can specify options like so:

$.gaTracker(
    'UA-XXXXX-XX',
    {
        external:       '/external/',
        mailto:         '/mailto/',
        download:       '/downloads/',
        extensions:     [
            'pdf','doc','xls','csv','jpg','gif', 'mp3',
            'swf','txt','ppt','zip','gz','dmg','xml'
        ]
    }
);

Download the gaTracker plugin at jQuery.com.