18 December 2008

A Simple Javascript Slider

HTML5 might well have a native slider element (as part of Webforms 2.0); jQuery and MooTools have slider components, and the StackOverflow slider page points to these and other implementations.

In the spirit of NIH, I wrote my own. Rolling your own is one way to learn to appreciate a language; afterwards you get bored and start trusting the libraries. Here's a screenshot:

This slider invokes a callback function (onchange) when necessary, with the percentage value of the slider. It's up to you to translate that into dates, numbers, colours, or whatever it is you're sliding. Use like this:

<table>
  <tr>
    <th>
      Slider
    </th>

    <td id="foo_slider_min">
      <img src='/images/slider_min.png'>
    </td>
    
    <td valign="top" style="padding-top:5px;">
      <div id="foo_slider_bar" style="width:128px;background-image:url('/images/slider-bar.png');background-repeat:repeat-x;position:relative;">
         
        <div id="foo_slider_button" style="position:absolute;top:0;left:95%;">
          <img src="/images/slider-button.png" alt="editor pixel size controller"/>
        </div>
      </div>
    </td>

    <td id="foo_slider_max">
      <img src='/images/slider_max.png'>
    </td>

  </tr>
</table>

Initialise this with

var onFooChange = function(percent) {
    // update foo so it's at percent%
  }
  var sliderControl = new Slider("foo_slider", onFooChange);

If your slider's name (the 1st argument to new Slider()) is "foo_slider", it expects the following DOM elements to exist:

  • foo_slider_bar - the object whose width is considered a value of 100%
  • foo_slider_button - the object whose position relative to foo_slider_bar determines the value of the component
  • foo_slider_min - an object which sets the slider to 0% when clicked
  • foo_slider_max - an object which sets the slider to 100% when clicked

Here's the actual Slider code, use as you please -

function Slider(name, onchange) {
  var sliderBar = $(name + '_bar');
  var sliderButton = $(name + '_button');
  var sliderMin = $(name + '_min');
  var sliderMax = $(name + '_max');
  var min = 0;
  var self = this;

  var max = function() {
    return parseInt(sliderBar.style.width) - 2;
  };

  var setButtonPosition = function(px) {
    if (px > max()) {
      px = max();
    } else if (px < min) {
      px = min;
    }
    sliderButton.style.left = "" + (px - 8) + "px";
    onchange(px / max());
  };

  sliderBar.onmousedown = function(event) {
    document.onmousedown = returnFalse;

    offsets(event, sliderBar, function(y, x) {
      setButtonPosition(x);
    });

    document.onmousemove = function(event2) {
      offsets(event2, sliderBar, function(y, x) {
        setButtonPosition(x);
      });
    }

    document.onmouseup = cancelMouse;
  };

  sliderMin.onclick = function() {
    self.resetTo(0);
  };

  sliderMax.onclick = function() {
    self.resetTo(1);
  };

  this.resetTo = function(proportion) {
    setButtonPosition(proportion * max());
  }
}

3 comments:

  1. The script says "obejct not found" on the first (and following) row - var sliderBar = $(name + '_bar');

    There should be any problem with that.

    ReplyDelete
  2. Hello Anonymous,

    If you call "new Slider('foo', my_onchange);", make sure you have previously defined a HTML element with id "foo_bar", as well as "foo_button" and the other required controls. The call to Slider must happen after these HTML elements are in place.

    ReplyDelete
  3. Hi
    Im working on a facebook application and I have to use FBJS so I have to translate your code so it fits. What does this part of the code do?


    offsets(event, sliderBar, function(y, x) {
    setButtonPosition(x);
    });


    What is 'offsets' and what does it do?

    regards

    Paul

    ReplyDelete