Yesterday I was looking at the Scriptaculous library, in particular the slider bar. I had used it once before with some success, using a graphic for the track and gripper. But that’s was boring! What I wanted was to see the bar fill up with colour when it was slid. Something like this:

I hadn’t seen anything like this around (not saying it hasn’t been done, just that I hadn’t seen it!), so after a bit of playing I found out it was actually very easy to create. And this is how I did it…
All it really does is use a handy little trick with transparent PNG images and background-image positions. You can find details of what I mean in this handy article by Dave Stone, over at Bare Naked App.
So basically I have my slider gripper (or handle), which has a transparent background:
And the slider track, which has an opaque white background but is transparent where I want the colour to show through (thumbnail shown, but links through to full size image):
And then I have the background image, which is essentially double the size of the track and has one half in off-white and one in green (thumbnail shown, but links through to full size image):
The XHTML used for the slider looks like this:
<div id="slider">
<div id="slider-bar">
<div id="slider-handle"><p id="percent"></p></div>
</div>
</div>
The CSS looks like this:
#slider, #slider-bar, #slider-handle {
border: 0;
padding: 0;
margin: 0;
}
#slider {
width: 300px;
height:42px;
background: url(img/bg.gif) no-repeat -300px;
margin-left: 42px;
}
#slider-bar {
width:300px;
height:42px;
background: url(img/track.png) no-repeat;
}
#slider-handle {
width:42px;
height:42px;
cursor:move;
background: url(img/gripper.png) no-repeat;
}
#percent {
font-size: 75%;
font-family: arial;
font-weight: bold;
text-align: center;
padding-top: 1.1em;
}
And finally, the Javascript looks like this:
<script type="text/javascript">
// <![CDATA[
var hWidth, bWidth;
function setBgPos(v) {
var off = v * hWidth;
var pos = -bWidth + (v * bWidth);
$('slider').setStyle({backgroundPosition: Math.round(pos - off) + 'px'});
}
function setSlideOutput(v) {
$('percent').innerHTML = Math.round(v * 100) + '%';
}
Event.observe(window, 'load', function() {
hWidth = $('slider-handle').getWidth();
bWidth = $('slider-bar').getWidth();
var slide = new Control.Slider('slider-handle', 'slider-bar', {
sliderValue: 0.25,
onSlide:
function(v) {
setBgPos(v);
setSlideOutput(v);
},
onChange:
function(v) {
setBgPos(v);
setSlideOutput(v);
}
});
setBgPos(slide.value);
setSlideOutput(slide.value);
});
// ]]>
</script>
You may notice the offset value, off. I’m using this because in my experiment the slider handle doesn’t fully cover the bar (nor did I want it to), so I cannot have the background image colour go fully across the track. I had to incrementally offset it depending on the position and size of the handle.
And that’s it! Pretty darned easy, but looks really neat. You can see it in action at http://dev.amnuts.com/slider/.





I thought this was a little dodgy on Safari; the track image wouldn’t update and the percentage value wouldn’t display. In the end it turned out to be the version of Safari I was using not having Javascript 1.5, which the .toFixed() method requires. Changing that to use Math.round() fixes the issues in Safari (version < 2.0).
I’ve updated the code to reflect this change.
Hello, I tried to use this nifty slider in a school project for MYSQL and PHP, unfortunately when I tried to capture the percentage value to use it in a Form I didn’t succeed.I’m asking you for your help if possible since I’m really new to JavaScript and i just can’t find any solution to use the value effectively
Thanks in advance.
P.S.: Congrats for this Blog, it will surely one of my references.
dj_thekid; thanks for the kind words! One way to do this (and there are probably plenty of ways that you could), is to set a hidden form value on slide and change. So say you had a form element:
<input type=”hidden” id=”percentage” name=”percentage” value=”0″ />
Then you’d update the onSlide and onChange events to be something like:
onSlide: function(v) { setBgPos(v); setSlideOutput(v); $('percentage').value = Math.round(v * 100); }, onChange: function(v) { setBgPos(v); setSlideOutput(v); $('percentage').value = Math.round(v * 100); }Hope that helps.
Dear Andy,
Thank you for your precious help. Your suggestion worked perfectly as intended, now I can use the slider value inside the form.
Thanks Andy. Very good job on the visual. One problem I am having though is when going from horizontal to vertical I can not get 0% to be at the bottom and 100% to be at the top. Could you instruct me on how to achieve this?
Thanks
Hi, is there a way to get the whole package as a download?
Thanx!
Very, nice. But I can’t get it to work on any of my browsers (FF3, gChrome, etc.) I get a “Control is not defined — on Line 26 of index.html)” showing up on my FF Error Console. I simply copy and pasted everything from your web page and followed your directory structures. Any thoughts on what is causing this error?
I used this your code and it was really helpful. What I just need to do more on it is, make it stepped such that the slider stops on predefined intervals. How can i do this. I would appreciate your help
dk; It does work under FF 3.5 – did you also get prototype and scriptaculous? You need those two js libraries for the slider to work. Check out the demo here:
http://dev.amnuts.com/slider/