vendor/assets/javascripts/slider.js in active_frontend-9.1.1 vs vendor/assets/javascripts/slider.js in active_frontend-10.0.0

- old
+ new

@@ -269,10 +269,26 @@ return this; }; function createNewSlider(element, options) { + /* + The internal state object is used to store data about the current 'state' of slider. + + This includes values such as the `value`, `enabled`, etc... + */ + this._state = { + value: null, + enabled: null, + offset: null, + size: null, + percentage: null, + inDrag: null, + over: null + }; + + if(typeof element === "string") { this.element = document.querySelector(element); } else if(element instanceof HTMLElement) { this.element = element; } @@ -533,14 +549,19 @@ this.options.min = Math.min.apply(Math, this.options.ticks); } if (Array.isArray(this.options.value)) { this.options.range = true; - } else if (this.options.range) { + this._state.value = this.options.value; + } + else if (this.options.range) { // User wants a range, but value is not an array - this.options.value = [this.options.value, this.options.max]; + this._state.value = [this.options.value, this.options.max]; } + else { + this._state.value = this.options.value; + } this.trackLow = sliderTrackLow || this.trackLow; this.trackSelection = sliderTrackSelection || this.trackSelection; this.trackHigh = sliderTrackHigh || this.trackHigh; @@ -572,13 +593,13 @@ for (i = 0; i < this.ticks.length; i++) { this._addClass(this.ticks[i], this.options.handle); } } - this.offset = this._offset(this.sliderElem); - this.size = this.sliderElem[this.sizePos]; - this.setValue(this.options.value); + this._state.offset = this._offset(this.sliderElem); + this._state.size = this.sliderElem[this.sizePos]; + this.setValue(this._state.value); /****************************************** Bind Event Listeners @@ -602,14 +623,16 @@ // Bind tooltip-related handlers if(this.options.tooltip === 'hide') { this._addClass(this.tooltip, 'hide'); this._addClass(this.tooltip_min, 'hide'); this._addClass(this.tooltip_max, 'hide'); - } else if(this.options.tooltip === 'always') { + } + else if(this.options.tooltip === 'always') { this._showTooltip(); this._alwaysShowTooltip = true; - } else { + } + else { this.showTooltip = this._showTooltip.bind(this); this.hideTooltip = this._hideTooltip.bind(this); this.sliderElem.addEventListener("mouseenter", this.showTooltip, false); this.sliderElem.addEventListener("mouseleave", this.hideTooltip, false); @@ -673,62 +696,61 @@ scale: 'linear', focus: false, tooltip_position: null }, - over: false, - - inDrag: false, - getElement: function() { return this.sliderElem; }, getValue: function() { if (this.options.range) { - return this.options.value; + return this._state.value; } - return this.options.value[0]; + else { + return this._state.value[0]; + } }, setValue: function(val, triggerSlideEvent, triggerChangeEvent) { if (!val) { val = 0; } var oldValue = this.getValue(); - this.options.value = this._validateInputValue(val); + this._state.value = this._validateInputValue(val); var applyPrecision = this._applyPrecision.bind(this); if (this.options.range) { - this.options.value[0] = applyPrecision(this.options.value[0]); - this.options.value[1] = applyPrecision(this.options.value[1]); + this._state.value[0] = applyPrecision(this._state.value[0]); + this._state.value[1] = applyPrecision(this._state.value[1]); - this.options.value[0] = Math.max(this.options.min, Math.min(this.options.max, this.options.value[0])); - this.options.value[1] = Math.max(this.options.min, Math.min(this.options.max, this.options.value[1])); - } else { - this.options.value = applyPrecision(this.options.value); - this.options.value = [ Math.max(this.options.min, Math.min(this.options.max, this.options.value))]; + this._state.value[0] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[0])); + this._state.value[1] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[1])); + } + else { + this._state.value = applyPrecision(this._state.value); + this._state.value = [ Math.max(this.options.min, Math.min(this.options.max, this._state.value))]; this._addClass(this.handle2, 'hide'); if (this.options.selection === 'after') { - this.options.value[1] = this.options.max; + this._state.value[1] = this.options.max; } else { - this.options.value[1] = this.options.min; + this._state.value[1] = this.options.min; } } if (this.options.max > this.options.min) { - this.percentage = [ - this._toPercentage(this.options.value[0]), - this._toPercentage(this.options.value[1]), + this._state.percentage = [ + this._toPercentage(this._state.value[0]), + this._toPercentage(this._state.value[1]), this.options.step * 100 / (this.options.max - this.options.min) ]; } else { - this.percentage = [0, 0, 100]; + this._state.percentage = [0, 0, 100]; } this._layout(); - var newValue = this.options.range ? this.options.value : this.options.value[0]; + var newValue = this.options.range ? this._state.value : this._state.value[0]; if(triggerSlideEvent === true) { this._trigger('slide', newValue); } if( (oldValue !== newValue) && (triggerChangeEvent === true) ) { @@ -763,40 +785,40 @@ this.$element.removeData('slider'); } }, disable: function() { - this.options.enabled = false; + this._state.enabled = false; this.handle1.removeAttribute("tabindex"); this.handle2.removeAttribute("tabindex"); this._addClass(this.sliderElem, 'slider-disabled'); this._trigger('slideDisabled'); return this; }, enable: function() { - this.options.enabled = true; + this._state.enabled = true; this.handle1.setAttribute("tabindex", 0); this.handle2.setAttribute("tabindex", 0); this._removeClass(this.sliderElem, 'slider-disabled'); this._trigger('slideEnabled'); return this; }, toggle: function() { - if(this.options.enabled) { + if(this._state.enabled) { this.disable(); } else { this.enable(); } return this; }, isEnabled: function() { - return this.options.enabled; + return this._state.enabled; }, on: function(evt, callback) { this._bindNonQueryEventHandler(evt, callback); return this; @@ -890,36 +912,37 @@ this.eventToCallbackMap[eventName] = null; } }, _showTooltip: function() { if (this.options.tooltip_split === false ){ - this._addClass(this.tooltip, 'in'); - this.tooltip_min.style.display = 'none'; - this.tooltip_max.style.display = 'none'; - } else { - this._addClass(this.tooltip_min, 'in'); - this._addClass(this.tooltip_max, 'in'); - this.tooltip.style.display = 'none'; - } - this.over = true; + this._addClass(this.tooltip, 'in'); + this.tooltip_min.style.display = 'none'; + this.tooltip_max.style.display = 'none'; + } else { + this._addClass(this.tooltip_min, 'in'); + this._addClass(this.tooltip_max, 'in'); + this.tooltip.style.display = 'none'; + } + this._state.over = true; }, _hideTooltip: function() { - if (this.inDrag === false && this.alwaysShowTooltip !== true) { + if (this._state.inDrag === false && this.alwaysShowTooltip !== true) { this._removeClass(this.tooltip, 'in'); this._removeClass(this.tooltip_min, 'in'); this._removeClass(this.tooltip_max, 'in'); } - this.over = false; + this._state.over = false; }, _layout: function() { var positionPercentages; if(this.options.reversed) { - positionPercentages = [ 100 - this.percentage[0], this.options.range ? 100 - this.percentage[1] : this.percentage[1]]; - } else { - positionPercentages = [ this.percentage[0], this.percentage[1] ]; + positionPercentages = [ 100 - this._state.percentage[0], this.options.range ? 100 - this._state.percentage[1] : this._state.percentage[1]]; } + else { + positionPercentages = [ this._state.percentage[0], this._state.percentage[1] ]; + } this.handle1.style[this.stylePos] = positionPercentages[0]+'%'; this.handle2.style[this.stylePos] = positionPercentages[1]+'%'; /* Position ticks and labels */ @@ -927,11 +950,11 @@ var maxTickValue = Math.max.apply(Math, this.options.ticks); var minTickValue = Math.min.apply(Math, this.options.ticks); var styleSize = this.options.orientation === 'vertical' ? 'height' : 'width'; var styleMargin = this.options.orientation === 'vertical' ? 'marginTop' : 'marginLeft'; - var labelSize = this.size / (this.options.ticks.length - 1); + var labelSize = this._state.size / (this.options.ticks.length - 1); if (this.tickLabelContainer) { var extraMargin = 0; if (this.options.ticks_positions.length === 0) { this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px'; @@ -986,11 +1009,12 @@ this.trackSelection.style.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; this.trackSelection.style.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%'; this.trackHigh.style.bottom = '0'; this.trackHigh.style.height = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%'; - } else { + } + else { this.trackLow.style.left = '0'; this.trackLow.style.width = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; this.trackSelection.style.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; this.trackSelection.style.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%'; @@ -1013,11 +1037,11 @@ } var formattedTooltipVal; if (this.options.range) { - formattedTooltipVal = this.options.formatter(this.options.value); + formattedTooltipVal = this.options.formatter(this._state.value); this._setText(this.tooltipInner, formattedTooltipVal); this.tooltip.style[this.stylePos] = (positionPercentages[1] + positionPercentages[0])/2 + '%'; if (this.options.orientation === 'vertical') { this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px'); @@ -1029,14 +1053,14 @@ this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px'); } else { this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px'); } - var innerTooltipMinText = this.options.formatter(this.options.value[0]); + var innerTooltipMinText = this.options.formatter(this._state.value[0]); this._setText(this.tooltipInner_min, innerTooltipMinText); - var innerTooltipMaxText = this.options.formatter(this.options.value[1]); + var innerTooltipMaxText = this.options.formatter(this._state.value[1]); this._setText(this.tooltipInner_max, innerTooltipMaxText); this.tooltip_min.style[this.stylePos] = positionPercentages[0] + '%'; if (this.options.orientation === 'vertical') { @@ -1051,11 +1075,11 @@ this._css(this.tooltip_max, 'margin-top', -this.tooltip_max.offsetHeight / 2 + 'px'); } else { this._css(this.tooltip_max, 'margin-left', -this.tooltip_max.offsetWidth / 2 + 'px'); } } else { - formattedTooltipVal = this.options.formatter(this.options.value[0]); + formattedTooltipVal = this.options.formatter(this._state.value[0]); this._setText(this.tooltipInner, formattedTooltipVal); this.tooltip.style[this.stylePos] = positionPercentages[0] + '%'; if (this.options.orientation === 'vertical') { this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px'); @@ -1070,28 +1094,28 @@ } else { element.style.removeAttribute(prop); } }, _mousedown: function(ev) { - if(!this.options.enabled) { + if(!this._state.enabled) { return false; } - this.offset = this._offset(this.sliderElem); - this.size = this.sliderElem[this.sizePos]; + this._state.offset = this._offset(this.sliderElem); + this._state.size = this.sliderElem[this.sizePos]; var percentage = this._getPercentage(ev); if (this.options.range) { - var diff1 = Math.abs(this.percentage[0] - percentage); - var diff2 = Math.abs(this.percentage[1] - percentage); - this.dragged = (diff1 < diff2) ? 0 : 1; + var diff1 = Math.abs(this._state.percentage[0] - percentage); + var diff2 = Math.abs(this._state.percentage[1] - percentage); + this._state.dragged = (diff1 < diff2) ? 0 : 1; } else { - this.dragged = 0; + this._state.dragged = 0; } - this.percentage[this.dragged] = percentage; + this._state.percentage[this._state.dragged] = percentage; this._layout(); if (this.touchCapable) { document.removeEventListener("touchmove", this.mousemove, false); document.removeEventListener("touchend", this.mouseup, false); @@ -1114,22 +1138,22 @@ } // Bind mouse events: document.addEventListener("mousemove", this.mousemove, false); document.addEventListener("mouseup", this.mouseup, false); - this.inDrag = true; + this._state.inDrag = true; var newValue = this._calculateValue(); this._trigger('slideStart', newValue); this._setDataVal(newValue); this.setValue(newValue, false, true); this._pauseEvent(ev); if (this.options.focus) { - this._triggerFocusOnHandle(this.dragged); + this._triggerFocusOnHandle(this._state.dragged); } return true; }, _triggerFocusOnHandle: function(handleIdx) { @@ -1139,11 +1163,11 @@ if(handleIdx === 1) { this.handle2.focus(); } }, _keydown: function(handleIdx, ev) { - if(!this.options.enabled) { + if(!this._state.enabled) { return false; } var dir; switch (ev.keyCode) { @@ -1168,14 +1192,14 @@ if (ifVerticalAndNotReversed || ifHorizontalAndReversed) { dir = -dir; } } - var val = this.options.value[handleIdx] + dir * this.options.step; + var val = this._state.value[handleIdx] + dir * this.options.step; if (this.options.range) { - val = [ (!handleIdx) ? val : this.options.value[0], - ( handleIdx) ? val : this.options.value[1]]; + val = [ (!handleIdx) ? val : this._state.value[0], + ( handleIdx) ? val : this._state.value[1]]; } this._trigger('slideStart', val); this._setDataVal(val); this.setValue(val, true, true); @@ -1197,17 +1221,17 @@ } ev.cancelBubble=true; ev.returnValue=false; }, _mousemove: function(ev) { - if(!this.options.enabled) { + if(!this._state.enabled) { return false; } var percentage = this._getPercentage(ev); this._adjustPercentageForRangeSliders(percentage); - this.percentage[this.dragged] = percentage; + this._state.percentage[this._state.dragged] = percentage; this._layout(); var val = this._calculateValue(true); this.setValue(val, true, true); @@ -1216,21 +1240,21 @@ _adjustPercentageForRangeSliders: function(percentage) { if (this.options.range) { var precision = this._getNumDigitsAfterDecimalPlace(percentage); precision = precision ? precision - 1 : 0; var percentageWithAdjustedPrecision = this._applyToFixedAndParseFloat(percentage, precision); - if (this.dragged === 0 && this._applyToFixedAndParseFloat(this.percentage[1], precision) < percentageWithAdjustedPrecision) { - this.percentage[0] = this.percentage[1]; - this.dragged = 1; - } else if (this.dragged === 1 && this._applyToFixedAndParseFloat(this.percentage[0], precision) > percentageWithAdjustedPrecision) { - this.percentage[1] = this.percentage[0]; - this.dragged = 0; + if (this._state.dragged === 0 && this._applyToFixedAndParseFloat(this._state.percentage[1], precision) < percentageWithAdjustedPrecision) { + this._state.percentage[0] = this._state.percentage[1]; + this._state.dragged = 1; + } else if (this._state.dragged === 1 && this._applyToFixedAndParseFloat(this._state.percentage[0], precision) > percentageWithAdjustedPrecision) { + this._state.percentage[1] = this._state.percentage[0]; + this._state.dragged = 0; } } }, _mouseup: function() { - if(!this.options.enabled) { + if(!this._state.enabled) { return false; } if (this.touchCapable) { // Touch: Unbind touch event handlers: document.removeEventListener("touchmove", this.mousemove, false); @@ -1238,12 +1262,12 @@ } // Unbind mouse event handlers: document.removeEventListener("mousemove", this.mousemove, false); document.removeEventListener("mouseup", this.mouseup, false); - this.inDrag = false; - if (this.over === false) { + this._state.inDrag = false; + if (this._state.over === false) { this._hideTooltip(); } var val = this._calculateValue(true); this._layout(); @@ -1254,20 +1278,20 @@ }, _calculateValue: function(snapToClosestTick) { var val; if (this.options.range) { val = [this.options.min,this.options.max]; - if (this.percentage[0] !== 0){ - val[0] = this._toValue(this.percentage[0]); + if (this._state.percentage[0] !== 0){ + val[0] = this._toValue(this._state.percentage[0]); val[0] = this._applyPrecision(val[0]); } - if (this.percentage[1] !== 100){ - val[1] = this._toValue(this.percentage[1]); + if (this._state.percentage[1] !== 100){ + val[1] = this._toValue(this._state.percentage[1]); val[1] = this._applyPrecision(val[1]); } } else { - val = this._toValue(this.percentage[0]); + val = this._toValue(this._state.percentage[0]); val = parseFloat(val); val = this._applyPrecision(val); } if (snapToClosestTick) { @@ -1306,15 +1330,15 @@ if (this.touchCapable && (ev.type === 'touchstart' || ev.type === 'touchmove')) { ev = ev.touches[0]; } var eventPosition = ev[this.mousePos]; - var sliderOffset = this.offset[this.stylePos]; + var sliderOffset = this._state.offset[this.stylePos]; var distanceToSlide = eventPosition - sliderOffset; // Calculate what percent of the length the slider handle has slid - var percentage = (distanceToSlide / this.size) * 100; - percentage = Math.round(percentage / this.percentage[2]) * this.percentage[2]; + var percentage = (distanceToSlide / this._state.size) * 100; + percentage = Math.round(percentage / this._state.percentage[2]) * this._state.percentage[2]; if (this.options.reversed) { percentage = 100 - percentage; } // Make sure the percent is within the bounds of the slider. @@ -1337,14 +1361,13 @@ var input = val[i]; if (typeof input !== 'number') { throw new Error( ErrorMsgs.formatInvalidInputErrorMsg(input) ); } } }, _setDataVal: function(val) { - var value = "value: '" + val + "'"; - this.element.setAttribute('data', value); + this.element.setAttribute('data-value', val); this.element.setAttribute('value', val); - this.element.value = val; + this.element.value = val; }, _trigger: function(evt, val) { val = (val || val === 0) ? val : undefined; var callbackFnArray = this.eventToCallbackMap[evt]; @@ -1440,13 +1463,13 @@ return this.options.scale.toPercentage.apply(this, [value]); }, _setTooltipPosition: function(){ var tooltips = [this.tooltip, this.tooltip_min, this.tooltip_max]; if (this.options.orientation === 'vertical'){ - this.options.tooltip_position = this.options.tooltip_position || 'right'; - var oppositeSide = this.options.tooltip_position === 'left' ? 'right' : 'left'; + var tooltipPos = this.options.tooltip_position || 'right'; + var oppositeSide = (tooltipPos === 'left') ? 'right' : 'left'; tooltips.forEach(function(tooltip){ - this._addClass(tooltip, this.options.tooltip_position); + this._addClass(tooltip, tooltipPos); tooltip.style[oppositeSide] = '100%'; }.bind(this)); } else if(this.options.tooltip_position === 'bottom') { tooltips.forEach(function(tooltip){ this._addClass(tooltip, 'bottom'); \ No newline at end of file