vendor/assets/javascripts/_slider.js in active_frontend-12.2.0 vs vendor/assets/javascripts/_slider.js in active_frontend-12.3.0

- old
+ new

@@ -1,6 +1,6 @@ -(function(root, factory) { +(function(factory) { if(typeof define === "function" && define.amd) { define(["jquery"], factory); } else if(typeof module === "object" && module.exports) { var jQuery; @@ -10,14 +10,14 @@ catch (err) { jQuery = null; } module.exports = factory(jQuery); } - else { - root.Slider = factory(root.jQuery); + else if(window) { + window.Slider = factory(window.jQuery); } -}(this, function($) { +}(function($) { // Reference to Slider constructor var Slider; (function( $ ) { @@ -172,29 +172,30 @@ var SliderScale = { linear: { toValue: function(percentage) { var rawValue = percentage/100 * (this.options.max - this.options.min); + var shouldAdjustWithBase = true; if (this.options.ticks_positions.length > 0) { var minv, maxv, minp, maxp = 0; - for (var i = 0; i < this.options.ticks_positions.length; i++) { + for (var i = 1; i < this.options.ticks_positions.length; i++) { if (percentage <= this.options.ticks_positions[i]) { - minv = (i > 0) ? this.options.ticks[i-1] : 0; - minp = (i > 0) ? this.options.ticks_positions[i-1] : 0; + minv = this.options.ticks[i-1]; + minp = this.options.ticks_positions[i-1]; maxv = this.options.ticks[i]; maxp = this.options.ticks_positions[i]; break; } } - if (i > 0) { - var partialPercentage = (percentage - minp) / (maxp - minp); - rawValue = minv + partialPercentage * (maxv - minv); - } + var partialPercentage = (percentage - minp) / (maxp - minp); + rawValue = minv + partialPercentage * (maxv - minv); + shouldAdjustWithBase = false; } - var value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step; + var adjustment = shouldAdjustWithBase ? this.options.min : 0; + var value = adjustment + Math.round(rawValue / this.options.step) * this.options.step; if (value < this.options.min) { return this.options.min; } else if (value > this.options.max) { return this.options.max; } else { @@ -280,12 +281,12 @@ value: null, enabled: null, offset: null, size: null, percentage: null, - inDrag: null, - over: null + inDrag: false, + over: false }; if(typeof element === "string") { this.element = document.querySelector(element); @@ -381,18 +382,37 @@ sliderTrackHigh = document.createElement("div"); sliderTrackHigh.className = "slider-track-high"; sliderMinHandle = document.createElement("div"); sliderMinHandle.className = "slider-handle min-slider-handle"; + sliderMinHandle.setAttribute('role', 'slider'); + sliderMinHandle.setAttribute('aria-valuemin', this.options.min); + sliderMinHandle.setAttribute('aria-valuemax', this.options.max); sliderMaxHandle = document.createElement("div"); sliderMaxHandle.className = "slider-handle max-slider-handle"; + sliderMaxHandle.setAttribute('role', 'slider'); + sliderMaxHandle.setAttribute('aria-valuemin', this.options.min); + sliderMaxHandle.setAttribute('aria-valuemax', this.options.max); sliderTrack.appendChild(sliderTrackLow); sliderTrack.appendChild(sliderTrackSelection); sliderTrack.appendChild(sliderTrackHigh); + /* Add aria-labelledby to handle's */ + var isLabelledbyArray = Array.isArray(this.options.labelledby); + if (isLabelledbyArray && this.options.labelledby[0]) { + sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby[0]); + } + if (isLabelledbyArray && this.options.labelledby[1]) { + sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby[1]); + } + if (!isLabelledbyArray && this.options.labelledby) { + sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby); + sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby); + } + /* Create ticks */ this.ticks = []; if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) { for (i = 0; i < this.options.ticks.length; i++) { var tick = document.createElement('div'); @@ -413,12 +433,14 @@ this.tickLabelContainer = document.createElement('div'); this.tickLabelContainer.className = 'slider-tick-label-container'; for (i = 0; i < this.options.ticks_labels.length; i++) { var label = document.createElement('div'); + var noTickPositionsSpecified = this.options.ticks_positions.length === 0; + var tickLabelsIndex = (this.options.reversed && noTickPositionsSpecified) ? (this.options.ticks_labels.length - (i + 1)) : i; label.className = 'slider-tick-label'; - label.innerHTML = this.options.ticks_labels[i]; + label.innerHTML = this.options.ticks_labels[tickLabelsIndex]; this.tickLabels.push(label); this.tickLabelContainer.appendChild(label); } } @@ -437,18 +459,21 @@ }; /* Create tooltip elements */ var sliderTooltip = document.createElement("div"); sliderTooltip.className = "tooltip tooltip-main"; + sliderTooltip.setAttribute('role', 'presentation'); createAndAppendTooltipSubElements(sliderTooltip); var sliderTooltipMin = document.createElement("div"); sliderTooltipMin.className = "tooltip tooltip-min"; + sliderTooltipMin.setAttribute('role', 'presentation'); createAndAppendTooltipSubElements(sliderTooltipMin); var sliderTooltipMax = document.createElement("div"); sliderTooltipMax.className = "tooltip tooltip-max"; + sliderTooltipMax.setAttribute('role', 'presentation'); createAndAppendTooltipSubElements(sliderTooltipMax); /* Append components to sliderElem */ this.sliderElem.appendChild(sliderTrack); @@ -617,11 +642,15 @@ // Bind touch handlers this.sliderElem.addEventListener("touchstart", this.mousedown, false); } this.sliderElem.addEventListener("mousedown", this.mousedown, false); + // Bind window handlers + this.resize = this._resize.bind(this); + window.addEventListener("resize", this.resize, false); + // 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'); @@ -647,10 +676,11 @@ if(this.options.enabled) { this.enable(); } else { this.disable(); } + } /************************************************* @@ -693,11 +723,12 @@ ticks_positions: [], ticks_labels: [], ticks_snap_bounds: 0, scale: 'linear', focus: false, - tooltip_position: null + tooltip_position: null, + labelledby: null }, getElement: function() { return this.sliderElem; }, @@ -822,18 +853,18 @@ on: function(evt, callback) { this._bindNonQueryEventHandler(evt, callback); return this; }, - off: function(evt, callback) { - if($) { - this.$element.off(evt, callback); - this.$sliderElem.off(evt, callback); - } else { - this._unbindNonQueryEventHandler(evt, callback); - } - }, + off: function(evt, callback) { + if($) { + this.$element.off(evt, callback); + this.$sliderElem.off(evt, callback); + } else { + this._unbindNonQueryEventHandler(evt, callback); + } + }, getAttribute: function(attribute) { if(attribute) { return this.options[attribute]; } else { @@ -870,43 +901,53 @@ _fnName : function() {...} ********************************/ _removeSliderEventHandlers: function() { - // Remove event listeners from handle1 + // Remove keydown event listeners this.handle1.removeEventListener("keydown", this.handle1Keydown, false); - this.handle1.removeEventListener("focus", this.showTooltip, false); - this.handle1.removeEventListener("blur", this.hideTooltip, false); - - // Remove event listeners from handle2 this.handle2.removeEventListener("keydown", this.handle2Keydown, false); - this.handle2.removeEventListener("focus", this.handle2Keydown, false); - this.handle2.removeEventListener("blur", this.handle2Keydown, false); + if (this.showTooltip) { + this.handle1.removeEventListener("focus", this.showTooltip, false); + this.handle2.removeEventListener("focus", this.showTooltip, false); + } + if (this.hideTooltip) { + this.handle1.removeEventListener("blur", this.hideTooltip, false); + this.handle2.removeEventListener("blur", this.hideTooltip, false); + } + // Remove event listeners from sliderElem - this.sliderElem.removeEventListener("mouseenter", this.showTooltip, false); - this.sliderElem.removeEventListener("mouseleave", this.hideTooltip, false); + if (this.showTooltip) { + this.sliderElem.removeEventListener("mouseenter", this.showTooltip, false); + } + if (this.hideTooltip) { + this.sliderElem.removeEventListener("mouseleave", this.hideTooltip, false); + } this.sliderElem.removeEventListener("touchstart", this.mousedown, false); this.sliderElem.removeEventListener("mousedown", this.mousedown, false); + + // Remove window event listener + window.removeEventListener("resize", this.resize, false); }, _bindNonQueryEventHandler: function(evt, callback) { if(this.eventToCallbackMap[evt] === undefined) { this.eventToCallbackMap[evt] = []; } this.eventToCallbackMap[evt].push(callback); }, - _unbindNonQueryEventHandler: function(evt, callback) { - var callbacks = this.eventToCallbackMap[evt]; - if(callbacks !== undefined) { - for (var i = 0; i < callbacks.length; i++) { - if (callbacks[i] === callback) { - callbacks.splice(i, 1); - break; - } - } - } - }, + _unbindNonQueryEventHandler: function(evt, callback) { + var callbacks = this.eventToCallbackMap[evt]; + if(callbacks !== undefined) { + for (var i = 0; i < callbacks.length; i++) { + if (callbacks[i] === callback) { + callbacks.splice(i, 1); + break; + } + } + } + }, _cleanUpEventCallbacksMap: function() { var eventNames = Object.keys(this.eventToCallbackMap); for(var i = 0; i < eventNames.length; i++) { var eventName = eventNames[i]; this.eventToCallbackMap[eventName] = null; @@ -941,25 +982,29 @@ else { positionPercentages = [ this._state.percentage[0], this._state.percentage[1] ]; } this.handle1.style[this.stylePos] = positionPercentages[0]+'%'; + this.handle1.setAttribute('aria-valuenow', this._state.value[0]); + this.handle2.style[this.stylePos] = positionPercentages[1]+'%'; + this.handle2.setAttribute('aria-valuenow', this._state.value[1]); /* Position ticks and labels */ if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) { - 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._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'; + if (this.options.orientation !== 'vertical') { + this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px'; + } + extraMargin = this.tickLabelContainer.offsetHeight; } else { /* Chidren are position absolute, calculate height by finding the max offsetHeight of a child */ for (i = 0 ; i < this.tickLabelContainer.childNodes.length; i++) { if (this.tickLabelContainer.childNodes[i].offsetHeight > extraMargin) { @@ -971,13 +1016,16 @@ this.sliderElem.style.marginBottom = extraMargin + 'px'; } } for (var i = 0; i < this.options.ticks.length; i++) { - var percentage = this.options.ticks_positions[i] || - 100 * (this.options.ticks[i] - minTickValue) / (maxTickValue - minTickValue); + var percentage = this.options.ticks_positions[i] || this._toPercentage(this.options.ticks[i]); + if (this.options.reversed) { + percentage = 100 - percentage; + } + this.ticks[i].style[this.stylePos] = percentage + '%'; /* Set class labels to denote whether ticks are in the selection */ this._removeClass(this.ticks[i], 'in-selection'); if (!this.options.range) { @@ -991,53 +1039,22 @@ } if (this.tickLabels[i]) { this.tickLabels[i].style[styleSize] = labelSize + 'px'; - if (this.options.ticks_positions[i] !== undefined) { + if (this.options.orientation !== 'vertical' && this.options.ticks_positions[i] !== undefined) { this.tickLabels[i].style.position = 'absolute'; - this.tickLabels[i].style[this.stylePos] = this.options.ticks_positions[i] + '%'; + this.tickLabels[i].style[this.stylePos] = percentage + '%'; this.tickLabels[i].style[styleMargin] = -labelSize/2 + 'px'; + } else if (this.options.orientation === 'vertical') { + this.tickLabels[i].style['marginLeft'] = this.sliderElem.offsetWidth + 'px'; + this.tickLabelContainer.style['marginTop'] = this.sliderElem.offsetWidth / 2 * -1 + 'px'; } } } } - if (this.options.orientation === 'vertical') { - this.trackLow.style.top = '0'; - this.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; - - 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 { - 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]) +'%'; - - this.trackHigh.style.right = '0'; - this.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%'; - - var offset_min = this.tooltip_min.getBoundingClientRect(); - var offset_max = this.tooltip_max.getBoundingClientRect(); - - if (offset_min.right > offset_max.left) { - this._removeClass(this.tooltip_max, 'top'); - this._addClass(this.tooltip_max, 'bottom'); - this.tooltip_max.style.top = 18 + 'px'; - } else { - this._removeClass(this.tooltip_max, 'bottom'); - this._addClass(this.tooltip_max, 'top'); - this.tooltip_max.style.top = this.tooltip_min.style.top; - } - } - var formattedTooltipVal; if (this.options.range) { formattedTooltipVal = this.options.formatter(this._state.value); this._setText(this.tooltipInner, formattedTooltipVal); @@ -1085,9 +1102,63 @@ this._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px'); } else { this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px'); } } + + if (this.options.orientation === 'vertical') { + this.trackLow.style.top = '0'; + this.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; + + 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 { + 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]) +'%'; + + this.trackHigh.style.right = '0'; + this.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%'; + + var offset_min = this.tooltip_min.getBoundingClientRect(); + var offset_max = this.tooltip_max.getBoundingClientRect(); + + if (this.options.tooltip_position === 'bottom') { + if (offset_min.right > offset_max.left) { + this._removeClass(this.tooltip_max, 'bottom'); + this._addClass(this.tooltip_max, 'top'); + this.tooltip_max.style.top = ''; + this.tooltip_max.style.bottom = 22 + 'px'; + } else { + this._removeClass(this.tooltip_max, 'top'); + this._addClass(this.tooltip_max, 'bottom'); + this.tooltip_max.style.top = this.tooltip_min.style.top; + this.tooltip_max.style.bottom = ''; + } + } else { + if (offset_min.right > offset_max.left) { + this._removeClass(this.tooltip_max, 'top'); + this._addClass(this.tooltip_max, 'bottom'); + this.tooltip_max.style.top = 18 + 'px'; + } else { + this._removeClass(this.tooltip_max, 'bottom'); + this._addClass(this.tooltip_max, 'top'); + this.tooltip_max.style.top = this.tooltip_min.style.top; + } + } + } + }, + _resize: function (ev) { + /*jshint unused:false*/ + this._state.offset = this._offset(this.sliderElem); + this._state.size = this.sliderElem[this.sizePos]; + this._layout(); }, _removeProperty: function(element, prop) { if (element.style.removeProperty) { element.style.removeProperty(prop); } else { \ No newline at end of file