///////////////////////////////////////////////////////////////////////////////
// To use a slider, some elements with specific id's are required.
//
// Example:
//
//
//
//
//
//
//
// isValidText()
//
//
// SliderGroupSlider = new Slider("SliderGroup", LowValue, HighValue, CurrentValue, ValidatioFunction, Orientation, Enabled);
//
// The function image_preview_onChange() is called on change if it exists.
// If a slider change event callback is set (with the setSliderOnChange method)
// then it is called when the slider changes. If the callback does not exist
// but a function slider_onChange("SliderGroup") do, then is is called.
//
// ----------------------------------------------------------------------------
//
// Some usable functions
// ---------------------
// moveTo() - Sync slider with value in text field.
// moveX(X) - Horisontal slider, move slider X steps.
// moveY(Y) - Vertical slider, move slider Y steps.
// boundary(value) - Get value inside slider boundary.
// enable() - Enable the slider.
// disable() - Disable the slider.
// setActual(value) - Shows a marker on the slider indicating an "actual" value.
// removeActual() - Hides the marker on the slider indicating an "actual" value.
// update(min, max, value) - Updates limits and current value.
// refresh() - Refresh slider (moves handle to current value).
// setSliderOnChange(callback) - Set callback for slider change events.
//
///////////////////////////////////////////////////////////////////////////////
function Slider(cname, min, max, begin, validateFunction, orientation, enabled)
{
var isDragging = false;
/*
* Return number of pixels to top
*/
function getRealTop(imgElem) {
try {
yPos = eval(imgElem).offsetTop;
tempEl = eval(imgElem).offsetParent;
while (tempEl != null) {
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
} catch(e) {yPos = 1;}
return yPos;
}
/*
* Return number of pixels to left side
*/
function getRealLeft(imgElem) {
try {
xPos = eval(imgElem).offsetLeft;
tempEl = eval(imgElem).offsetParent;
while (tempEl != null) {
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
} catch(e) {xPos = 1;}
return xPos;
}
/*
* Returns if the scrollbar present for browser
*/
function getScrollBarState() {
var result = {vScrollbar: true, hScrollbar: true};
try {
var root = document.documentElement === null? document.body: document.documentElement;
result.vScrollbar = root.scrollHeight > root.clientHeight;
result.hScrollbar = root.scrollWidth > root.clientWidth;
} catch(e) {}
return(result);
}
this.startDrag = function(e) {
var coord;
var obj = this.obj;
if (!obj.isEnabled)
return false;
var h = obj.handle;
if (!h)
return false;
isDragging = true;
// Set coordinate event origioned from and prevent triggering the background.
if (typeof(event) == "undefined") {
coord = obj.isHorizontal ? e.clientX : e.clientY;
e.stopPropagation();
} else {
coord = obj.isHorizontal ? event.screenX : event.y;
event.cancelBubble=true
}
h.last_pos = coord - (obj.isHorizontal ? getRealLeft(h) : getRealTop(h));
// After dragging has started, the mouse pointer is not necessarily
// located over the handle. Therefor keep track in the entire document.
document.obj = obj;
document.onmousemove = obj.doDrag;
document.onmouseup = obj.endDrag;
return false;
}
this.doDrag = function(e) {
var coord;
var obj = this.obj;
if (!obj.isEnabled)
return false;
var h = obj.handle;
if (!h)
return false;
if (obj.isHorizontal) {
if (typeof(event) == "undefined")
coord = e.clientX;
else
coord = event.screenX;
obj.value = obj.getValue(coord - h.last_pos);
var newPos = obj.getPixelX(obj.value);
h.style.left = newPos + "px";
} else {
if (typeof(event) == "undefined")
coord = e.clientY;
else
coord = event.y;
obj.value = obj.getValue(coord - h.last_pos);
var newPos = obj.getPixelY(obj.value);
h.style.top = newPos + "px";
}
if (obj.text)
obj.text.value = obj.value;
return false;
}
this.endDrag = function() {
document.onmousemove = null;
document.onmouseup = null;
if (typeof(image_preview_onChange) == "function")
image_preview_onChange();
if (typeof(this.obj.onSliderChange) == "function")
this.obj.onSliderChange(this.obj.cname, this.obj.value);
else if (typeof(slider_onChange) == "function")
slider_onChange(this.obj.cname, this.obj.value);
isDragging = false;
}
/*
* Called when changing a value in the text field.
* To force a move even when disabled, set 'force' to true
*/
this.moveTo = function(force) {
var obj = this.obj;
if (!force && !obj.isEnabled)
return false;
var val = obj.boundary(obj.text.value);
if (val != null && !isNaN(val)) {
obj.value = val;
if (obj.text)
obj.text.value = val;
obj.refresh();
if (typeof(image_preview_onChange) == "function")
image_preview_onChange();
if (typeof(obj.onSliderChange) == "function")
obj.onSliderChange(obj.cname, obj.value);
else if (typeof(slider_onChange) == "function")
slider_onChange(obj.cname, obj.value);
}
return false;
}
/*
* Called when clicking left/right button or when clicking the background
*/
this.moveX = function(step) {
var coord;
var obj = this.obj;
if (!obj.isEnabled)
return false;
var h = obj.handle;
if (typeof(step) == "number") {
/* left or right button was clicked */
obj.value = parseInt(obj.value, 10);
obj.value = obj.boundary(obj.value + step);
coord = obj.getPixelX(obj.value);
} else {
var dh = ( h ? h.width/2 : 0);
/* background was clicked.*/
if (typeof(event) == "undefined" || event == null) {
coord = step.clientX;
} else {
var hScrollbar = getScrollBarState().hScrollbar;
coord = (!!hScrollbar && obj.barWidth > 1000)? event.offsetX +h.width+dh:event.x;
}
obj.value = obj.getValue(coord + document.body.scrollLeft - dh);
coord = obj.getPixelX(obj.value);
}
if (h)
h.style.left = coord + "px";
if (obj.text) {
obj.text.value = obj.value;
}
if (obj.moving) {
obj.timeout = setTimeout(obj.cname + "Slider.obj.moveX(" + step + ")",40);
} else {
if (typeof(image_preview_onChange) == "function")
image_preview_onChange();
if (typeof(obj.onSliderChange) == "function")
obj.onSliderChange(obj.cname, obj.value);
else if (typeof(slider_onChange) == "function")
slider_onChange(obj.cname, obj.value);
}
return false;
}
/*
* Called when clicking up/down button or when clicking the background
*/
this.moveY = function(step) {
var coord;
var obj = this.obj;
if (!obj.isEnabled)
return false;
var h = obj.handle;
if (typeof(step) == "number") {
/* up or down button was clicked */
obj.value = obj.boundary(obj.value + step);
coord = obj.getPixelY(obj.value);
} else {
/* background was clicked.*/
if (typeof(event) == "undefined" || event == null)
coord = step.clientY;
else
coord = event.y;
var dh = ( h ? h.width/2 : 0);
obj.value = obj.getValue(coord + document.body.scrollTop - dh);
coord = obj.getPixelY(obj.value);
}
if (h)
h.style.top = coord + "px";
if (obj.text) {
obj.text.value = obj.value;
}
if (obj.moving) {
obj.timeout = setTimeout(obj.cname + "Slider.obj.moveY(" + step + ")",40);
} else {
if (typeof(image_preview_onChange) == "function")
image_preview_onChange();
if (typeof(obj.onSliderChange) == "function")
obj.onSliderChange(obj.cname, obj.value);
else if (typeof(slider_onChange) == "function")
slider_onChange(obj.cname, obj.value);
}
return false;
}
this.stopMoving = function(pixels) {
var obj = this.obj;
if (obj.moving) {
obj.moving = false;
if (obj.timeout)
clearTimeout(obj.timeout);
if (typeof(image_preview_onChange) == "function")
image_preview_onChange();
if (typeof(obj.onSliderChange) == "function")
obj.onSliderChange(obj.cname, obj.value);
else if (typeof(slider_onChange) == "function")
slider_onChange(obj.cname, obj.value);
}
}
this.boundary = function(value) {
var obj = this.obj;
var v = parseInt(value, 10);
if (!isNaN(v))
return Math.min(Math.max(v, obj.min), obj.max);
else
return obj.value;
}
this.getValue = function(pixel) {
var obj = this.obj;
if (obj.isHorizontal)
return obj.boundary(Math.round((obj.max - obj.min)*(parseInt(pixel, 10) - getRealLeft(obj.bg))/obj.barWidth + obj.min));
else
return obj.boundary(Math.round(obj.max - (obj.max - obj.min)*(parseInt(pixel, 10) - getRealTop(obj.bg))/obj.barHeight));
}
this.getPixelX = function(value, padding) {
var obj = this.obj;
padding = ((typeof(padding) == "number") ? padding: 0);
var width = obj.barWidth - 2*padding;
if (obj.max == obj.min)
return getRealLeft(obj.bg);
else
return Math.min(Math.max(Math.round((parseFloat(value) - obj.min) / (obj.max - obj.min) * width), 0), width) + padding + getRealLeft(obj.bg);
}
this.getPixelY = function(value, valueHeight) {
var obj = this.obj;
valueHeight = ((typeof(valueHeight) == "number") ? valueHeight : 3);
var padding = Math.floor(valueHeight/2);
var height = obj.barHeight - valueHeight - valueHeight%2 - 1;
if (obj.max == obj.min)
return getRealTop(obj.bg);
else
return Math.min(Math.max(Math.round((obj.max - parseFloat(value)) / (obj.max - obj.min) * height), 0), height) + padding + getRealTop(obj.bg);
}
this.enable = function() {
var obj = this.obj;
obj.isEnabled = true;
}
this.disable = function() {
var obj = this.obj;
obj.isEnabled = false;
}
this.realSetActual = function() {
var obj = this.obj;
var o = obj.actualObject;
var v = obj.actualValue;
if (o) {
try {
if (obj.isHorizontal) {
o.style.top = (getRealTop(obj.bg) + 1) + "px";
o.style.left = (obj.getPixelX(v, Math.floor(obj.actualWidth/2) + 1) - Math.ceil(obj.actualWidth/2)) + "px";
o.style.width = obj.actualWidth + "px";
o.style.height = (obj.bg.height - 2) + "px";
o.onmousedown = this.moveX;
} else {
o.style.top = obj.getPixelY(v, obj.actualWidth) + "px";
o.style.left = (getRealLeft(obj.bg) + 1) + "px";
o.style.width = (obj.bg.width - 2) + "px";
o.style.height = obj.actualWidth + "px";
o.onmousedown = this.moveY;
}
} catch(e) {}
if (o.style.top.length == 0 || o.style.left.length == 0 ||
o.style.width.length == 0 || o.style.height.length == 0) {
o.style.display = "none";
}
}
}
this.setActual = function(aValue) {
var obj = this.obj;
var o = obj.actualObject;
var v = obj.boundary(aValue);
if (isNaN(v))
return;
if (!o)
{
o = document.createElement("img");
o.className = "actualSliderPos";
o.id = "actualSliderPos-" + obj.cname;
o.src = "/pics/blank.gif";
o.actualValue = v;
o.obj = this;
obj.actualObject = o;
obj.zIndex = 10;
document.body.appendChild(o);
} else {
o.style.display = "";
}
obj.actualValue = v;
obj.realSetActual();
}
this.removeActual = function() {
var obj = this.obj;
var o = obj.actualObject;
if (o)
o.style.display = "none";
}
this.update = function(min, max, value) {
var obj = this.obj;
min = parseInt(min, 10);
max = parseInt(max, 10);
value = parseInt(value, 10);
if (isNaN(min) || isNaN(max) || isNaN(value))
return false;
if (!!isDragging) {
return false;
}
obj.min = min;
obj.max = max;
obj.value = obj.boundary(value);
if (obj.text)
obj.text.value = value;
obj.refresh();
}
this.refresh = function() {
var obj = this.obj;
var h = obj.handle;
if (!h)
return false;
if (obj.isHorizontal) {
h.style.left = obj.getPixelX(obj.value) + "px";
h.style.top = getRealTop(obj.bg) + "px";
} else {
h.style.top = obj.getPixelY(obj.value) + "px";
h.style.left = getRealLeft(obj.bg) + "px";
}
obj.realSetActual();
}
this.setSliderOnChange = function(method) {
this.obj.onSliderChange = method;
}
/*
* Save parameters
*/
this.cname = cname;
this.min = min;
this.max = max;
this.isEnabled = (enabled != false);
this.isHorizontal = (orientation != "vertical");
this.onSliderChange = null;
_handle = document.getElementById(cname + '-handle');
if (_handle)
{
_handle.style.position = "absolute";
_handle.style.zIndex = 20;
_handle.onmousedown = this.startDrag;
_handle.obj = this;
}
var _handle_width = ( _handle ? _handle.width : 0 );
this.handle = _handle;
try {
_bg = document.getElementById(cname + '-bg');
if (_bg.width <= 0)
this.barWidth = _bg.width - _handle_width; // NON IE
else
this.barWidth = _bg.clientWidth - _handle_width; // IE
if (_bg.height <= 0)
this.barHeight = _bg.height - _handle_width; // NON IE
else
this.barHeight = _bg.clientHeight - _handle_width; // IE
_bg.obj = this;
_bg.onmousedown = this.isHorizontal ? this.moveX : this.moveY;
this.bg = _bg;
} catch(e) {}
if (_handle)
{
this.handle.style.left = getRealLeft(this.bg) + "px";
this.handle.style.top = getRealTop(this.bg) + "px";
}
/*
* Left and right button and text field are optional
*/
if (_left = document.getElementById(cname + '-left')) {
_left.onmousedown = function () {
var obj = this.obj;
if (!obj.isEnabled)
return false;
obj.moving = true;
obj.moveX(-1);
}
_left.onmouseup = this.stopMoving;
_left.onmouseout = this.stopMoving;
_left.style.cursor = 'pointer';
_left.obj = this;
}
if (_right = document.getElementById(cname + '-right')) {
_right.onmousedown = function () {
var obj = this.obj;
if (!obj.isEnabled)
return false;
obj.moving = true;
obj.moveX(1);
}
_right.onmouseup = this.stopMoving;
_right.onmouseout = this.stopMoving;
_right.style.cursor = 'pointer';
_right.obj = this;
}
/*
* Up and down button and text field are optional
*/
if (_up = document.getElementById(cname + '-up')) {
_up.onmousedown = function () {
var obj = this.obj;
if (!obj.isEnabled)
return false;
obj.moving = true;
obj.moveY(-1);
}
_up.onmouseup = this.stopMoving;
_up.onmouseout = this.stopMoving;
_up.style.cursor = 'pointer';
_up.obj = this;
}
if (_down = document.getElementById(cname + '-down')) {
_down.onmousedown = function () {
var obj = this.obj;
if (!obj.isEnabled)
return false;
obj.moving = true;
obj.moveY(1);
}
_down.onmouseup = this.stopMoving;
_down.onmouseout = this.stopMoving;
_down.style.cursor = 'pointer';
_down.obj = this;
}
if (_text = document.getElementById(cname)) {
_text.moveTo = this.moveTo;
_text.value = begin;
_text.onchange = function() {
var obj = this.obj;
if (!obj.isEnabled)
return false;
if (typeof(validateFunction) != 'function')
var isValid = validateFunction();
else
var isValid = true;
if (isValid)
this.moveTo();
return isValid;
}
this.original_onkeypress = _text.onkeypress;
_text.onkeypress = function(e) {
var isValid = true;
var isValid2 = true;
if (typeof(this.original_onkeypress) == 'function') {
isValid = this.original_onkeypress(e);
}
var isEnterPressed = false;
if (typeof(event) == "undefined")
isEnterPressed = e.charCode == 13;
else
isEnterPressed = event.keyCode == 13;
if (isEnterPressed) {
if (typeof(validateFunction) == 'function') {
isValid2 = validateFunction();
}
this.moveTo();
}
return isValid && isValid2;
}
_text.obj = this;
this.text = _text;
}
this.moving = false;
this.value = begin;
this.obj = this;
this.timeout = false;
var o = document.getElementById("actualSliderPos-" + this.cname);
if (o) {
this.actualObject = o;
this.actualValue = o.actualValue;
} else {
this.actualObject = null;
this.actualValue = 0;
}
this.actualWidth = 5;
try {
if (this.isHorizontal) {
/*
* Adjust background if it's offsetted from the left button
*/
_bg.style.backgroundPosition = '0 ' + (_left?(_left.offsetTop - _bg.offsetTop):0) + 'px';
/*
* Initialize position
*/
if (_handle)
_handle.style.left = this.getPixelX(begin) + "px";
} else {
/*
* Adjust background if it's offsetted from the top button
*/
_bg.style.backgroundPosition = '0 ' + (_up?(_up.offsetTop - _bg.offsetTop):0) + 'px';
/*
* Initialize position
*/
if (_handle)
_handle.style.top = this.getPixelY(begin) + "px";
}
} catch(e) {}
return false;
}