var SlidePointInput = function(target, obj, returnCB){ var data = new Data(obj), template = '{{# separators }}{{/ separators }}{{# labels }}{{/ labels}}', element = getElementFromString(render(template, data)), fill = element.querySelector('fill'), separators = element.querySelectorAll('dot'), dragList = []; this.getValue = data.nub.getValue; this.setValue = data.nub.setValue; this.exit = exit; target.appendChild(element); setTimeout(init,0); function init(){ bindNub(); setFill(); setFilledDots(); } function Data(o){ this.separators = getSeparators(o.values.length); this.nub = new Nub('end'); this.values = o.values; this.startValue = o.startValue ? getStartValue(o.values, o.startValue) : null; this.labels = o.labels; } function Nub(key){ var nub = null, left = 0, slideWidth = 0, nubWidth = 0, currentIndex = 0, position = 0, drag = null; this.key = key; this.setNub = setNub; this.setValue = setValue; this.getLocation = getLocation; this.getWidth = getWidth; this.getData = getData; this.getCurrentIndex = getCurrentIndex; function getValueIndex(v){ var d = data.values, t = d.length, c = t; while(c){ var i = t-c--; if(d[i] === v) return i; } return 0; } function getIndexPosition(i){ return i / (data.values.length - 1); } function getCurrentIndex(){ return currentIndex; } function getWidth(){ return nubWidth; } function getLocation(){ return left; } function getPrependage(){ if(isDefined(data.prependValue)) return data.prependValue; else return '' } function getAppendage(){ if(isDefined(data.appendValue)) return data.appendValue; else return '' } function getLeftValue(v){ return (slideWidth - nubWidth) * getIndexPosition(getValueIndex(v)); } function getData(){ var a = data.values, t = a.length, c = t, d = t-1, mm = (1/t)/2, v = null; while(c){ var i = t - c--, amt = i/d - position; if((amt < mm && amt >= 0) || (amt < 0)) v = i; else if (c === 0 && v === null) v = 0; } return data.values[v]; } function setNub(e){ nub = e; setDrag(new DragController(e, dragStart, dragEnd, dragMove, { 'xOnly' : true, 'inBounds' : true, 'autoSet' : true })); } function setDrag(d){ drag = d; dragList.push(d); } function setWidth(){ setSlideWidth(); setNubWidth(); } function setSlideWidth(){ if(slideWidth != 0) return; c = element.getClientRects(); if(c.length > 0) slideWidth = c[0].width; } function setNubWidth(){ if(nubWidth != 0) return; c = nub.getClientRects(); if(c.length > 0) nubWidth = c[0].width; } function setValue(v){ setWidth(); left = getLeftValue(v); setNubPosition(); setPosition(); dragMove(null, left, null, true); drag.setOffsets(); } function setNubPosition(){ if(!nub) return; nub.style.position = 'absolute'; nub.style.left = left + 'px'; } function setPosition(){ setWidth(); position = left / (slideWidth - nubWidth); currentIndex = getValueIndex(getData()); } function dragStart(e){ nub.classList.add('active'); } function dragMove(e, l, t, force){ if(dragCheck(l, force)) dragMoveAction(l); else return false; } function dragEnd(e){ var d = getData(); setValue(d); if(!!nub) nub.classList.remove('active'); if(!!returnCB) returnCB(d); } function dragCheck(l, f){ return true; } function dragMoveAction(l){ if(isNaN(l)) return; left = l; setPosition(); setFill(); setFilledDots(); } } function Separator(v){ this.left = v + '%'; } function setFill(){ var e = data.nub; fill.style.width = e.getLocation() + (e.getWidth()/2) + 'px'; } function setFilledDots(){ var d = separators, t = d.length, c = t, ci = data.nub.getCurrentIndex(); while(c){ var i = t-c--; d[i].classList[i <= ci ? 'add' : 'remove']('filled'); } } function getStartValue(values, start){ var t = values.length, c = t; while(c){ if(start === values[t-c--]) return start; } return values[0]; } function getSeparators(c){ var v = 94 / (c - 1), a = []; for(var i=0; i