Easy Usability: Fitt’s Law

One of the easiest things that you could do to enhance the usability of your site is to properly use the <label> HTML Tag. Consider the following…

Example Forms

Select all that apply:

I love UX Design.
I understand Fitt’s Law.
I think that quick usability tips are awesome!

Now, compare that with this form:

Select all that apply:



Target Area Comparison

If you notice, the selections in the first form can only be ticked off by clicking on the actual checkbox, while in the second form the user can click anywhere (on the checkbox itself or on the textual label).

Fitts’ Law

A model that predicts that the time required to rapidly move to a target area is a function of the distance to the target and the size of the target.

 

What this means in our two form example is that because the target area is larger in the second form, it is thus easier to use and enhances the user experience because the user’s task is made easier (pointing to and clicking the item). This is a simplistic example but it corresponds very strongly to many aspects of UI design — the reason why call to action buttons are so large (amongst other properties) is precisely this law.

Code

Really all that’s required to make your forms more usable is to wrap inputs with their labels:

<label for="love">
  <input id="love" type="checkbox"> I love UX Design.</input>
</label>

How to Dynamically and Programmatically add Breakpoints in JavaScript

Debugger

Little known yet immensely useful fact is that you can use the keyword debugger; to stop JavaScript execution and bring up your browser’s debugger/web inspector (Firebug, WebKit Developer Tools, etc).

Programmatically

You can take this a step further by creating a global

window.DEBUG = true; // toggles programmatic debugging

flag with a global check debug function, like so:

window.CHECK_DEBUG = function() {
  if (window.DEBUG) { debugger; } 
}

And then insert the following in any function you’re concerned about debugging:

function foo() {
  CHECK_DEBUG();

 // foo's usual procedure ...
}

Dynamically

To take this a step further (and to take a page out of Firebug’s debug() and undebug() wrapper functions) you can decorate the native JavaScript Function object like so:

Function.prototype.debug = function(){   
   var fn = this;
   return function(){     
       if (window.DEBUG) { debugger; } 
       return fn.apply(this, arguments);     
   }; 
};

Then you can dynamically debug any function by calling:

foo = foo.debug();

Happy debugging!

Backbone Collection Update

Recently, while working on a Backbone-driven UI, I had the need to update a collection with two separate pieces of source data. That is, on initial load, I would get the basic properties of each Model in a Collection (color, title, etc) and later on during the lifetime of the app, I would get updates to the status of the Model along with other additional properties and potentially a completely new set of models. There was also the possibility that the basic properties would come in after the auxiliary properties due to latency and other factors.

There are likely many ways to solve this problem, but the first thing I looked for was an update() method on Backbone Collections. Surprisingly, Backbone Collections do not have an update() method out of the box and other solutions would require maintaing IDs, or reference hashes, etc. — things I preferred to avoid so as not to have to maintain. So, I set out to make my own update() method and attach it to the Backbone.Collection.prototype chain.

Here is what I started with:

Backbone.Collection.prototype.update = function(col_in){  
      var self = this;

      _(col_in).each(function(mod_in) {
        var new_model = self._prepareModel(mod_in);
        var mod = self.get(new_model.id);
        if (mod) { mod.set(mod_in); } else { self.add(mod_in); }
      });
    };

 

What this is basically doing is that for each model, mod_in, in the collection set coming in (col_in) we instantiate a new_model object (in order to attach the appropriate Backbone.Model properties). We then grab (via the Collection.get() method) any models that already exist in the collection, mod. If the model already existed, we simply update its data using the set() method. If it doesn’t exist, we add() it to the collection.

The issue with that loop is that it does not properly handle “stale” models. That is, it does not remove models that were not passed in as part of the collection to the update() method.

Easy to fix, we just need to create a new array of models and only add those that existed previously or are new to the collection (discarding those that were not passed in to the update() method). See below:

Backbone.Collection.prototype.update = function(col_in){  
  var self = this,
      new_models = [];

  _(col_in).each(function(mod_in) {
    var new_model = self._prepareModel(mod_in),
        mod = self.get(new_model.id);
    if (mod) { 
      new_models.push(mod.set(mod_in, {silent:true}));
    } else { 
      new_models.push(mod_in);
    }
  });

  this.reset(new_models);
};

 

Here’s a gist of this piece of code. Hopefully it will be included as part of the Backbone.js core eventually, as I think this is a method that may get a lot of utility in more complicated applications.

Equalize Multiple DIV Heights

While working on our web application, I had the need to equalize the heights of some DIVs so that side-by-side (diff-like) comparisons would be easier to do.

Quick Fix

The quick fix solution would be to set a min-height property in the CSS on the relevant DIVs, however, this isn’t ideal as the heights can vary widely and there’s no real “catch-all” height that can be used reliably.

jQuery Plugin

I did a quick search to see if anyone had solved this particular problem before and came across this helpful CSS-Tricks post. Building on this and turning it into a reusable jQuery plugin, I ended up with:

$.fn.equalize = function() {
    var maxHeight = 0;

    return this.each(function(){
        var $this = $(this);
        if ($this.height() > maxHeight) { maxHeight = $this.height(); }
    }).height(maxHeight);
};

This can then be used on the desired set of elements to equalize (after page-load or the appropriate AJAX-loads have completed, of course):

$('.a,.b,.c,.d').equalize();

Here’s a jsFiddle to illustrate how this works.

Extending Further

What would make this plugin even more useful would be if it could equalize other properties (such as width, color, etc.), however for the properties that cannot be compared arithmetically we would need the ability to pass in an equalizing function to determine the “max” value to use. I leave this as an exercise for the reader.

Jam

Jam is a JavaScript front-end package manager. Think of it as the “npm” for front-end frameworks such as jQuery, Backbone, Underscore, etc. This should prove incredibly useful for getting projects up and running quickly, while having the added benefit of utilizing AMD-style modules (Jam uses RequireJS by default, but a more lightweight solution can also be swapped in) so all resources are loaded asynchronously as needed.

Installing Jam is easy, if you’ve already installed node.js just run:

npm install -g jamjs

Then simply use jam to install modules as you would npm modules:

jam install backbone

Good stuff, I’m surprised this wasn’t created sooner! If you’ve already started building projects with Jam, be sure to comment and share your experience with it.