2010-01-30

Building a jQuery color picker with CSS-3

One of the apps I work on has a new feature that requires a color picker applet. I went searching around on the internet for something useful, only to find that most of the solutions for color pickers are way overblown for our needs. A simple select box with a dozen or so colors would probably work just fine, but I wanted something a little flashier. The smallest one that would kind-of work that I found out in the wild was 6K. And then it didn't work with the jQuery version we run on the app. An hour or so of Javascript-golf later and I have a basic color-picker applet that fits neatly into a single packet (including the HTTP headers).

This is the un-minified version; see /packer/ for a simple online Javascript-packer.

(function($){
var colors = [
  '#f7b', '#fb3', '#fb7', '#fbb',
  '#f77', '#bf3', '#bf7', '#3f7',
  '#37f', '#7f3', '#7bf', '#b3f',
  '#b7f', '#9af', '#7fb', '#bfb'
];

$(function() {
  $('input.colorpicker').each(function() {
    var $input = $(this),
      $div = $('<div />'),
      $div3 = $('<div />')
        .addClass('colorpicker-bin')
        .hide(),
      $div2 = $('<div />')
        .addClass('colorpicker-button')
        .css({
          'background-color': this.value,
          'cursor': 'pointer'
        })
        .html('&nbsp;')
        .click(function() {
          $div3.toggle("fast");
        });

    $input.css({
      'background-color': this.value,
      'color': '#000'
    })
      .attr('disabled','disabled');

    $(colors).each(function() {
      var color=this;
      var $div4 = $('<div />')
        .addClass('colorpicker-color')
        .css({
          'background-color' : color,
          'cursor': 'pointer'
        })
        .html('&nbsp;')
        .click(function(){
          $div2.css('background-color',color);
          $input.css('background-color',color)
            .val(color);
          $('div.colorpicker-color')
            .removeClass('colorpicker-selected');

          $(this).addClass('colorpicker-selected');
        });

      if (color==$input.val()) {
        $div4.addClass('colorpicker-selected');
        $div3.append($div4);
      }
    });

    $input.wrap($div).after($div2.append($div3));
  });
});
})(jQuery);

On page load (DOM ready, actually), it adds a color-picker to all input elements with class colorpicker. It even works with hidden input boxes. The (function($) { ... })(jQuery); hack lets me use $ throughout the plugin, even with jQuery in no conflict mode (as we do use it in this particular app). Most of the rest of the code is just build up to the onClick() events that do the heavy-lifting. The value of the input box is replaced with the background-color of whichever swatch the user clicks on, so form submission works like normal.

I wired it up with some simple css-3 (shamelessly stolen from Zurb) and I'm in business. @webkit-keyframes paired with the colorpicker-selected class is very neat. Just make sure not to forget about Gecko-based browsers and Internet Explorer.

:wq

No comments:

Post a Comment