Javascript Slider Control
Description
One of the limitations of standard HTML form controls is that they do not provide the ability for the user to input an analogue value in the sense that they can either type in something using the keyboard or switch on or off check boxes or radio buttons. From time to time it would be beneficial to allow a variable value to be input. In this example it is shown how to implement such an input control using javascript.
Demonstration
How To Use
- Using your mouse drag the handle left and right along the slider
- Once you have it a position that suits, let go of your mouse
- Click the submit button to confirm your choice
Requirements
javascript enabled
How it Works
<input name="sliderValue" id="sliderValue4h" type="Text" size="3" onChange="A_SLIDERS[3].f_setValue(this.value)">
<input name="Submit" type="button" value="Submit" onClick="javascript:alert('You have selected '+document.getElementById('sliderValue4h').value);">
<script>
function slider (a_init, a_tpl)
{
this.f_setValue = f_sliderSetValue;
this.f_getPos = f_sliderGetPos;
// register in the global collection
if (!window.A_SLIDERS)
{
window.A_SLIDERS = [];
}
this.n_id = window.A_SLIDERS.length;
window.A_SLIDERS[this.n_id] = this;
// save config parameters in the slider object
var s_key;
if (a_tpl)
{
for (s_key in a_tpl)
{
this[s_key] = a_tpl[s_key];
}
}
for (s_key in a_init)
{
this[s_key] = a_init[s_key];
}
this.n_pix2value = this.n_pathLength / (this.n_maxValue - this.n_minValue);
if (this.n_value == null)
{
this.n_value = this.n_minValue;
}
// generate the control's HTML
document.write(
'<div style="width:' + this.n_controlWidth + 'px;height:' + this.n_controlHeight + 'px;border:0; background-image:url(' + this.s_imgControl + ')" id="sl' + this.n_id + 'base">' +
'<img src="' + this.s_imgSlider + '" width="' + this.n_sliderWidth + '" height="' + this.n_sliderHeight + '" border="0" style="position:relative;left:' + this.n_pathLeft + 'px;top:' + this.n_pathTop + 'px;z-index:' + this.n_zIndex + ';cursor:pointer;visibility:hidden;" name="sl' + this.n_id + 'slider" id="sl' + this.n_id + 'slider" onmousedown="return f_sliderMouseDown(' + this.n_id + ')"/></div>'
);
this.e_base = get_element('sl' + this.n_id + 'base');
this.e_slider = get_element('sl' + this.n_id + 'slider');
// safely hook document/window events
if (document.onmousemove != f_sliderMouseMove) {
window.f_savedMouseMove = document.onmousemove;
document.onmousemove = f_sliderMouseMove;
}
if (document.onmouseup != f_sliderMouseUp) {
window.f_savedMouseUp = document.onmouseup;
document.onmouseup = f_sliderMouseUp;
}
// preset to the value in the input box if available
var e_input = this.s_form == null
? get_element(this.s_name)
: document.forms[this.s_form]
? document.forms[this.s_form].elements[this.s_name]
: null;
this.f_setValue(e_input && e_input.value != '' ? e_input.value : null, 1);
this.e_slider.style.visibility = 'visible';
}
function f_sliderSetValue (n_value, b_noInputCheck) {
if (n_value == null)
n_value = this.n_value == null ? this.n_minValue : this.n_value;
if (isNaN(n_value))
return false;
// round to closest multiple if step is specified
if (this.n_step)
n_value = Math.round((n_value - this.n_minValue) / this.n_step) * this.n_step + this.n_minValue;
// smooth out the result
if (n_value % 1)
n_value = Math.round(n_value * 1e5) / 1e5;
if (n_value < this.n_minValue)
n_value = this.n_minValue;
if (n_value > this.n_maxValue)
n_value = this.n_maxValue;
this.n_value = n_value;
// move the slider
if (this.b_vertical)
this.e_slider.style.top = (this.n_pathTop + this.n_pathLength - Math.round((n_value - this.n_minValue) * this.n_pix2value)) + 'px';
else
this.e_slider.style.left = (this.n_pathLeft + Math.round((n_value - this.n_minValue) * this.n_pix2value)) + 'px';
// save new value
var e_input;
if (this.s_form == null) {
e_input = get_element(this.s_name);
if (!e_input)
return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with ID='" + this.s_name + "'.");
}
else {
var e_form = document.forms[this.s_form];
if (!e_form)
return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the form with NAME='" + this.s_form + "'.");
e_input = e_form.elements[this.s_name];
if (!e_input)
return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with NAME='" + this.s_name + "'.");
}
e_input.value = n_value;
}
// get absolute position of the element in the document
function f_sliderGetPos (b_vertical, b_base) {
var n_pos = 0,
s_coord = (b_vertical ? 'Top' : 'Left');
var o_elem = o_elem2 = b_base ? this.e_base : this.e_slider;
while (o_elem) {
n_pos += o_elem["offset" + s_coord];
o_elem = o_elem.offsetParent;
}
o_elem = o_elem2;
var n_offset;
while (o_elem.tagName != "BODY") {
n_offset = o_elem["scroll" + s_coord];
if (n_offset)
n_pos -= o_elem["scroll" + s_coord];
o_elem = o_elem.parentNode;
}
return n_pos;
}
function f_sliderMouseDown (n_id) {
window.n_activeSliderId = n_id;
return false;
}
function f_sliderMouseUp (e_event, b_watching) {
if (window.n_activeSliderId != null) {
var o_slider = window.A_SLIDERS[window.n_activeSliderId];
o_slider.f_setValue(o_slider.n_minValue + (o_slider.b_vertical
? (o_slider.n_pathLength - parseInt(o_slider.e_slider.style.top) + o_slider.n_pathTop)
: (parseInt(o_slider.e_slider.style.left) - o_slider.n_pathLeft)) / o_slider.n_pix2value);
if (b_watching) return;
window.n_activeSliderId = null;
}
if (window.f_savedMouseUp)
return window.f_savedMouseUp(e_event);
}
function f_sliderMouseMove (e_event) {
if (!e_event && window.event) e_event = window.event;
// save mouse coordinates
if (e_event) {
window.n_mouseX = e_event.clientX + f_scrollLeft();
window.n_mouseY = e_event.clientY + f_scrollTop();
}
// check if in drag mode
if (window.n_activeSliderId != null) {
var o_slider = window.A_SLIDERS[window.n_activeSliderId];
var n_pxOffset;
if (o_slider.b_vertical) {
var n_sliderTop = window.n_mouseY - o_slider.n_sliderHeight / 2 - o_slider.f_getPos(1, 1) - 3;
// limit the slider movement
if (n_sliderTop < o_slider.n_pathTop)
n_sliderTop = o_slider.n_pathTop;
var n_pxMax = o_slider.n_pathTop + o_slider.n_pathLength;
if (n_sliderTop > n_pxMax)
n_sliderTop = n_pxMax;
o_slider.e_slider.style.top = n_sliderTop + 'px';
n_pxOffset = o_slider.n_pathLength - n_sliderTop + o_slider.n_pathTop;
}
else {
var n_sliderLeft = window.n_mouseX - o_slider.n_sliderWidth / 2 - o_slider.f_getPos(0, 1) - 3;
// limit the slider movement
if (n_sliderLeft < o_slider.n_pathLeft)
n_sliderLeft = o_slider.n_pathLeft;
var n_pxMax = o_slider.n_pathLeft + o_slider.n_pathLength;
if (n_sliderLeft > n_pxMax)
n_sliderLeft = n_pxMax;
o_slider.e_slider.style.left = n_sliderLeft + 'px';
n_pxOffset = n_sliderLeft - o_slider.n_pathLeft;
}
if (o_slider.b_watch)
f_sliderMouseUp(e_event, 1);
return false;
}
if (window.f_savedMouseMove)
return window.f_savedMouseMove(e_event);
}
// get the scroller positions of the page
function f_scrollLeft() {
return f_filterResults (
window.pageXOffset ? window.pageXOffset : 0,
document.documentElement ? document.documentElement.scrollLeft : 0,
document.body ? document.body.scrollLeft : 0
);
}
function f_scrollTop() {
return f_filterResults (
window.pageYOffset ? window.pageYOffset : 0,
document.documentElement ? document.documentElement.scrollTop : 0,
document.body ? document.body.scrollTop : 0
);
}
function f_filterResults(n_win, n_docel, n_body) {
var n_result = n_win ? n_win : 0;
if (n_docel && (!n_result || (n_result > n_docel)))
n_result = n_docel;
return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}
function f_sliderError (n_id, s_message) {
alert("Slider #" + n_id + " Error:\n" + s_message);
window.n_activeSliderId = null;
}
get_element = document.all ?
function (s_id) { return document.all[s_id] } :
function (s_id) { return document.getElementById(s_id) };
</script>
<script language="JavaScript">
var A_TPL4h = {
'b_vertical' : false,
'b_watch': true,
'n_controlWidth': 100,
'n_controlHeight': 16,
'n_sliderWidth': 17,
'n_sliderHeight': 16,
'n_pathLeft' : 0,
'n_pathTop' : 0,
'n_pathLength' : 83,
's_imgControl': 'images/slider/background.gif',
's_imgSlider': 'images/slider/handle.gif',
'n_zIndex': 1
}
var A_INIT4h = {
's_form' : 0,
's_name': 'sliderValue4h',
'n_minValue' : 0,
'n_maxValue' : 100,
'n_value' : 85,
'n_step' : 1
}
new slider(A_INIT4h, A_TPL4h);
</script>
Further Uses and Ideas
- none
Version History
- Version 1 (03/04/2008) - Version 1
Comments For This Page
Hi Rob, to do this, change the value for n_step from 1 to 10.By Daft Logic on 3rd January 2012
solve a problem is " Can not find the Input width Name='sliderValue4h' ". Just change "'s_form' : 0," to order of form that text box (sliderValue4h) is stay as 's_form' : 1, in
var A_INIT4h = {
's_form' : 0,
's_name': 'sliderValue4h',
'n_minValue' : 0,
'n_maxValue' : 100,
'n_value' : 85,
'n_step' : 1 }
By Nop on 27th December 2011
it can not work when it has a form before the form which have a text box name is "sliderValue4h". How i solve about that.By Nop on 27th December 2011
What would I have to do to change the increments to be in 10's rather 1's?By Rob on 22nd December 2011
hey i've just managed to create a really cool jquery plugin slider which is the same as the google news slider control. interested to hear people's thoughts.
http://jsfiddle.net/LucP/BPdKR/2/By Luc on 5th December 2011
Nice! works really nice. Just want to add more functionality by adding extra buttons such as minus and plus buttions to increase and decrease value. Can anyone suggest modifications?
On 8th September 2011
Hey thanks for such an important tutorial to implement slider.I copied all but i get the error: Slider #0 error: Can not find the Input width Name='sliderValue4h' can you please help me on this? I need it very urgently.
Thanks in advance
On 18th July 2011
like wonga I want a total box that adds the number to another number using this slider. Can anyone help? I don't want to use ajax or jquery. I want something simple.By Tim on 14th July 2011
How do I add a calculator to it like on wonga?By Tim on 13th July 2011
Nice script...By Gaurav Sharma (gaurav.motivati on 25th June 2011
can we add multiple control on sliderBy shashi on 27th April 2011
Very nice example, but is there a way to have the slider move to a value that a user input into the textbox?By DB on 28th March 2011
great exampleOn 24th February 2011
Thanks a lot.By Ross on 25th November 2010
pity i can't usse it
using an ipad
still
i think it can be useful with an idea i call subjective enumeration
where i ask peeps for a subjective value from 1 to 10
this might be a useful means of inputing it...
interested?By happyseaurchin on 11th November 2010
oops... working link: http://www.updatemywebsite.com/revision30-developers-blog/curved-rounded-or-circular-sliders-javascript-jquery-uiBy dRock on 16th October 2010
Check out this rounded slider... they are using jQuery UI:
http://www.updatemywebsite.com/revision30-dev-blog/curved-rounded-or-circular-sliders-javascript-jquery-uiBy dRock on 14th October 2010
Please help... I am getting the error
Slider #0 error: Can not find the Input width Name='sliderValue4h'On 10th October 2010
hey,
can you help me another time? The First Slider works yet, but i tried to integrate a second one, but i get the same error again. Maybe you could help me another time? Domain is http://sack.bplaced.net/boni24/On 21st July 2010
Try this code (adds a form around the INPUT and renames the id value)
By Daft Logic on 20th July 2010
20 out of 37 comments shown. See all comments.
Add your own comment below and let others know what you think: