Slider - DEPRECATED - use ScrollBar or PathSlider instead
shortdesc > Slider - DEPRECATED - use ScrollBar instead
path name="value" accepts="HMI_INT" > value
path name="range" accepts="HMI_INT" > range
path name="visible" accepts="HMI_INT" > visible
handle_click = undefined;
dispatch(value,oldval, index) {
let [min,max,start,totallength] = this.range;
//save current value inside widget
if (this.curr_value > max){
this.apply_hmi_value(0, this.curr_value);
else if (this.curr_value < min){
this.apply_hmi_value(0, this.curr_value);
this.value_elt.textContent = String(value);
this.scroll_range = value;
this.scroll_visible = value;
//don't update if draging and setpoint ghost doesn't exist
if(!this.drag || (this.setpoint_elt != undefined)){
this.update_DOM(this.curr_value, this.handle_elt);
//check if range is bigger than visible and set scroll size
if(this.scroll_range > this.scroll_visible){
this.scroll_size = this.scroll_range - this.scroll_visible;
this.range[1] = this.scroll_size;
let [min,max,start,totallength] = this.range;
// check if handle is resizeable
if (this.scroll_size != undefined){ //size changes
let length = Math.max(min,Math.min(max,(Number(value)-min)*max/(max-min)));
let tip = this.range_elt.getPointAtLength(length);
let handle_min = totallength*this.min_size;
//check if range is bigger than max displayed and recalculate step
if ((totallength/handle_min) < (max-min+1)){
step = (max-min+1)/(totallength/handle_min-1);
let kx,ky,offseY,offseX = undefined;
ky = handle_min/this.handle_orig.height;
ky = (totallength-handle_min*(max-min))/this.handle_orig.height;
//get 0 offset to stay inside range
offseY = start.y - (this.handle_orig.height + this.handle_orig.y) * ky;
//get distance from value
tip.y =this.range_elt.getPointAtLength(0).y - length/step *handle_min;
kx = handle_min/this.handle_orig.width;
kx = (totallength-handle_min*(max-min))/this.handle_orig.width;
//get 0 offset to stay inside range
offseX = start.x - (this.handle_orig.x * kx);
//get distance from value
tip.x =this.range_elt.getPointAtLength(0).x + length/step *handle_min;
elt.setAttribute('transform',"matrix("+(kx)+" 0 0 "+(ky)+" "+(tip.x-start.x+offseX)+" "+(tip.y-start.y+offseY)+")");
else{ //size stays the same
let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
let tip = this.range_elt.getPointAtLength(length);
elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")");
// show or hide ghost if exists
if(this.setpoint_elt != undefined){
if(this.last_drag!= this.drag){
this.setpoint_elt.setAttribute("style", this.setpoint_style);
this.setpoint_elt.setAttribute("style", "display:none");
this.last_drag = this.drag;
window.removeEventListener("touchmove", this.on_bound_drag, true);
window.removeEventListener("mousemove", this.on_bound_drag, true);
window.removeEventListener("mouseup", this.bound_on_release, true);
window.removeEventListener("touchend", this.bound_on_release, true);
window.removeEventListener("touchcancel", this.bound_on_release, true);
this.update_position(evt);
//ignore drag event for X amount of time and if not selected
if(this.enTimer && this.drag){
this.update_position(evt);
setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
let [min,max,start,totallength] = this.range;
//calculate size of widget in html
var range_borders = this.range_elt.getBoundingClientRect();
var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top];
var range_length = Math.sqrt( range_borders.height*range_borders.height + range_borders.width*range_borders.width );
//get range and mouse coordinates
if (evt.type.startsWith("touch")){
mouseX = Math.ceil(evt.touches[0].clientX);
mouseY = Math.ceil(evt.touches[0].clientY);
if (this.handle_click){ //if clicked on handle
let moveDist = 0, resizeAdd = 0;
//set paramters for resizeable handle
if (this.scroll_size != undefined){
// add one more object to stay inside range
//chack if range is bigger than display option and
// calculate percent of range with out handle
if(((max/(max*this.min_size)) < (max-min+1))){
range_percent = 1-this.min_size;
range_percent = 1-(max-max*this.min_size*(max-min))/max;
//calculate value difference on x or y axis
moveDist = ((max-min+resizeAdd)/(range_length*range_percent))*((this.handle_click[1]-mouseY)/Math.sin(this.fi));
moveDist = ((max-min+resizeAdd)/(range_length*range_percent))*((mouseX-this.handle_click[0])/Math.cos(this.fi));
this.curr_value = Math.ceil(this.handle_click[2] + moveDist);
else{ //if clicked on widget
//get handle distance from mouse position
if (minX > mouseX && minY < mouseY){
else if (maxX < mouseX && maxY > mouseY){
html_dist = range_length;
html_dist = (minY - mouseY)/Math.sin(this.fi);
html_dist = (mouseX - minX)/Math.cos(this.fi);
this.curr_value=Math.ceil((html_dist/range_length)*(this.range[1]-this.range[0])+this.range[0]);
//check if in range and apply
if (this.curr_value > max){
else if (this.curr_value < min){
this.apply_hmi_value(0, this.curr_value);
// redraw handle on screen refresh
// check if setpoint(ghost) handle exsist otherwise update main handle
if(this.setpoint_elt != undefined){
this.update_DOM(this.curr_value, this.setpoint_elt);
this.update_DOM(this.curr_value, this.handle_elt);
//enable drag flag and timer
window.addEventListener("touchmove", this.on_bound_drag, true);
window.addEventListener("mousemove", this.on_bound_drag, true);
window.addEventListener("mouseup", this.bound_on_release, true);
window.addEventListener("touchend", this.bound_on_release, true);
window.addEventListener("touchcancel", this.bound_on_release, true);
// check if handle was pressed
if (evt.currentTarget == this.handle_elt){
//get mouse position on the handle
if (evt.type.startsWith("touch")){
mouseX = Math.ceil(evt.touches[0].clientX);
mouseY = Math.ceil(evt.touches[0].clientY);
//save coordinates and orig value
this.handle_click = [mouseX,mouseY,this.curr_value];
// get new handle position and reset if handle was not pressed
this.handle_click = undefined;
this.update_position(evt);
//set min max value if not defined
Number(this.min_elt.textContent) :
this.args.length >= 1 ? this.args[0] : 0;
Number(this.max_elt.textContent) :
this.args.length >= 2 ? this.args[1] : 100;
// save initial parameters
this.range_elt.style.strokeMiterlimit="0";
this.range = [min, max, this.range_elt.getPointAtLength(0),this.range_elt.getTotalLength()];
let start = this.range_elt.getPointAtLength(0);
let end = this.range_elt.getPointAtLength(this.range_elt.getTotalLength());
this.fi = Math.atan2(start.y-end.y, end.x-start.x);
this.handle_orig = this.handle_elt.getBBox();
this.bound_on_select = this.on_select.bind(this);
this.bound_on_release = this.on_release.bind(this);
this.on_bound_drag = this.on_drag.bind(this);
this.handle_elt.addEventListener("mousedown", this.bound_on_select);
this.element.addEventListener("mousedown", this.bound_on_select);
this.element.addEventListener("touchstart", this.bound_on_select);
//touch recognised as page drag without next command
document.body.addEventListener("touchstart", function(e){}, false);
if(this.setpoint_elt != undefined){
this.setpoint_style = this.setpoint_elt.getAttribute("style");
this.setpoint_elt.setAttribute("style", "display:none");
optional_labels("value min max setpoint");