wishthis/node_modules/fomantic-ui/dist/components/slider.js
2022-09-15 14:58:37 +02:00

1353 lines
48 KiB
JavaScript

/*!
* # Fomantic-UI 2.9.0-beta.315+0963809 - Slider
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ( $, window, document, undefined ) {
"use strict";
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.slider = function(parameters) {
var
$allModules = $(this),
$window = $(window),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
SINGLE_STEP = 1,
BIG_STEP = 2,
NO_STEP = 0,
SINGLE_BACKSTEP = -1,
BIG_BACKSTEP = -2,
// Used to manage document bound events.
// Use this so that we can distinguish between which document events are bound to which range.
currentRange = 0,
returnedValue
;
$allModules
.each(function() {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.slider.settings, parameters)
: $.extend({}, $.fn.slider.settings),
className = settings.className,
metadata = settings.metadata,
namespace = settings.namespace,
error = settings.error,
keys = settings.keys,
interpretLabel = settings.interpretLabel,
isHover = false,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$currThumb,
touchIdentifier,
$thumb,
$secondThumb,
$track,
$trackFill,
$labels,
element = this,
instance = $module.data(moduleNamespace),
documentEventID,
value,
position,
secondPos,
offset,
precision,
gapRatio = 1,
previousValue,
initialPosition,
initialLoad,
module
;
module = {
initialize: function() {
module.debug('Initializing slider', settings);
initialLoad = true;
currentRange += 1;
documentEventID = currentRange;
module.setup.layout();
module.setup.labels();
if(!module.is.disabled()) {
module.bind.events();
}
module.read.metadata();
module.read.settings();
initialLoad = false;
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of slider', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.verbose('Destroying previous slider for', $module);
clearInterval(instance.interval);
module.unbind.events();
module.unbind.slidingEvents();
$module.removeData(moduleNamespace);
instance = undefined;
},
setup: {
layout: function() {
if( $module.attr('tabindex') === undefined) {
$module.attr('tabindex', 0);
}
if($module.find('.inner').length == 0) {
$module.append("<div class='inner'>"
+ "<div class='track'></div>"
+ "<div class='track-fill'></div>"
+ "<div class='thumb'></div>"
+ "</div>");
}
precision = module.get.precision();
$thumb = $module.find('.thumb:not(.second)');
$currThumb = $thumb;
if(module.is.range()) {
if($module.find('.thumb.second').length == 0) {
$module.find('.inner').append("<div class='thumb second'></div>");
}
$secondThumb = $module.find('.thumb.second');
}
$track = $module.find('.track');
$trackFill = $module.find('.track-fill');
offset = $thumb.width() / 2;
},
labels: function() {
if(module.is.labeled()) {
$labels = $module.find('.labels:not(.auto)');
if($labels.length != 0) {
module.setup.customLabel();
} else {
module.setup.autoLabel();
}
if (settings.showLabelTicks) {
$module.addClass(className.ticked)
}
}
},
customLabel: function() {
var
$children = $labels.find('.label'),
numChildren = $children.length,
min = module.get.min(),
max = module.get.max(),
ratio
;
$children.each(function(index) {
var
$child = $(this),
attrValue = $child.attr('data-value')
;
if(attrValue) {
attrValue = attrValue > max ? max : attrValue < min ? min : attrValue;
ratio = (attrValue - min) / (max - min);
} else {
ratio = (index + 1) / (numChildren + 1);
}
module.update.labelPosition(ratio, $(this));
});
},
autoLabel: function() {
$labels = $module.find('.labels');
if($labels.length != 0) {
$labels.empty();
}
else {
$labels = $module.append('<ul class="auto labels"></ul>').find('.labels');
}
for(var i = 0, len = module.get.numLabels(); i <= len; i++) {
var
labelText = module.get.label(i),
$label = (labelText !== "")
? !(i % module.get.gapRatio())
? $('<li class="label">' + labelText + '</li>')
: $('<li class="halftick label"></li>')
: null,
ratio = i / len
;
if($label) {
module.update.labelPosition(ratio, $label);
$labels.append($label);
}
}
}
},
bind: {
events: function() {
module.bind.globalKeyboardEvents();
module.bind.keyboardEvents();
module.bind.mouseEvents();
if (settings.autoAdjustLabels) {
module.bind.windowEvents();
}
},
keyboardEvents: function() {
module.verbose('Binding keyboard events');
$module.on('keydown' + eventNamespace, module.event.keydown);
},
globalKeyboardEvents: function() {
$(document).on('keydown' + eventNamespace + documentEventID, module.event.activateFocus);
},
mouseEvents: function() {
module.verbose('Binding mouse and touch events');
$module.find('.track, .thumb, .inner').on('mousedown' + eventNamespace, function(event) {
event.stopImmediatePropagation();
event.preventDefault();
module.event.down(event);
});
$module.on('mousedown' + eventNamespace, module.event.down);
$module.on('mouseenter' + eventNamespace, function(event) {
isHover = true;
});
$module.on('mouseleave' + eventNamespace, function(event) {
isHover = false;
});
// All touch events are invoked on the element where the touch *started*. Thus, we can bind them all
// on the thumb(s) and don't need to worry about interference with other components, i.e. no dynamic binding
// and unbinding required.
$module.find('.thumb')
.on('touchstart' + eventNamespace, module.event.touchDown)
.on('touchmove' + eventNamespace, module.event.move)
.on('touchend' + eventNamespace, module.event.up)
.on('touchcancel' + eventNamespace, module.event.touchCancel);
},
slidingEvents: function() {
// these don't need the identifier because we only ever want one of them to be registered with document
module.verbose('Binding page wide events while handle is being draged');
$(document).on('mousemove' + eventNamespace, module.event.move);
$(document).on('mouseup' + eventNamespace, module.event.up);
},
windowEvents: function() {
$window.on('resize' + eventNamespace, module.event.resize);
}
},
unbind: {
events: function() {
$module.find('.track, .thumb, .inner').off('mousedown' + eventNamespace);
$module.off('mousedown' + eventNamespace);
$module.off('mouseenter' + eventNamespace);
$module.off('mouseleave' + eventNamespace);
$module.find('.thumb')
.off('touchstart' + eventNamespace)
.off('touchmove' + eventNamespace)
.off('touchend' + eventNamespace)
.off('touchcancel' + eventNamespace);
$module.off('keydown' + eventNamespace);
$module.off('focusout' + eventNamespace);
$(document).off('keydown' + eventNamespace + documentEventID, module.event.activateFocus);
$window.off('resize' + eventNamespace);
},
slidingEvents: function() {
$(document).off('mousemove' + eventNamespace);
$(document).off('mouseup' + eventNamespace);
},
},
event: {
down: function(event) {
event.preventDefault();
if(module.is.range()) {
var
eventPos = module.determine.eventPos(event),
newPos = module.determine.pos(eventPos)
;
// Special handling if range mode and both thumbs have the same value
if(settings.preventCrossover && module.is.range() && module.thumbVal === module.secondThumbVal) {
initialPosition = newPos;
$currThumb = undefined;
} else {
$currThumb = module.determine.closestThumb(newPos);
}
if (previousValue === undefined) {
previousValue = module.get.currentThumbValue();
}
} else if (previousValue === undefined) {
previousValue = module.get.value();
}
if(!module.is.disabled()) {
module.bind.slidingEvents();
}
},
touchDown: function(event) {
event.preventDefault(); // disable mouse emulation and touch-scrolling
event.stopImmediatePropagation();
if(touchIdentifier !== undefined) {
// ignore multiple touches on the same slider --
// we cannot handle changing both thumbs at once due to shared state
return;
}
$currThumb = $(event.target);
var touchEvent = event.touches ? event : event.originalEvent;
touchIdentifier = touchEvent.targetTouches[0].identifier;
if(previousValue === undefined) {
previousValue = module.get.currentThumbValue();
}
},
move: function(event) {
if(event.type == 'mousemove') {
event.preventDefault(); // prevent text selection etc.
}
if(module.is.disabled()) {
// touch events are always bound, so we need to prevent touch-sliding on disabled sliders here
return;
}
var value = module.determine.valueFromEvent(event);
if(event.type == 'mousemove' && $currThumb === undefined) {
var
eventPos = module.determine.eventPos(event),
newPos = module.determine.pos(eventPos)
;
$currThumb = initialPosition > newPos ? $thumb : $secondThumb;
}
if(module.get.step() == 0 || module.is.smooth()) {
var
thumbVal = module.thumbVal,
secondThumbVal = module.secondThumbVal,
thumbSmoothVal = module.determine.smoothValueFromEvent(event)
;
if(!$currThumb.hasClass('second')) {
if(settings.preventCrossover && module.is.range()) {
value = Math.min(secondThumbVal, value);
thumbSmoothVal = Math.min(secondThumbVal, thumbSmoothVal);
}
thumbVal = value;
} else {
if(settings.preventCrossover && module.is.range()) {
value = Math.max(thumbVal, value);
thumbSmoothVal = Math.max(thumbVal, thumbSmoothVal);
}
secondThumbVal = value;
}
value = Math.abs(thumbVal - (secondThumbVal || 0));
module.update.position(thumbSmoothVal);
settings.onMove.call(element, value, thumbVal, secondThumbVal);
} else {
module.update.value(value, function(value, thumbVal, secondThumbVal) {
settings.onMove.call(element, value, thumbVal, secondThumbVal);
});
}
},
up: function(event) {
event.preventDefault();
if(module.is.disabled()) {
// touch events are always bound, so we need to prevent touch-sliding on disabled sliders here
return;
}
var value = module.determine.valueFromEvent(event);
module.set.value(value);
module.unbind.slidingEvents();
touchIdentifier = undefined;
if (previousValue !== undefined) {
previousValue = undefined;
}
},
touchCancel: function(event) {
event.preventDefault();
touchIdentifier = undefined;
if (previousValue !== undefined) {
module.update.value(previousValue);
previousValue = undefined;
}
},
keydown: function(event, first) {
if(settings.preventCrossover && module.is.range() && module.thumbVal === module.secondThumbVal) {
$currThumb = undefined;
}
if(module.is.focused()) {
$(document).trigger(event);
}
if(first || module.is.focused()) {
var step = module.determine.keyMovement(event);
if(step != NO_STEP) {
event.preventDefault();
switch(step) {
case SINGLE_STEP:
module.takeStep();
break;
case BIG_STEP:
module.takeStep(module.get.multiplier());
break;
case SINGLE_BACKSTEP:
module.backStep();
break;
case BIG_BACKSTEP:
module.backStep(module.get.multiplier());
break;
}
}
}
},
activateFocus: function(event) {
if(!module.is.focused() && module.is.hover() && module.determine.keyMovement(event) != NO_STEP) {
event.preventDefault();
module.event.keydown(event, true);
$module.focus();
}
},
resize: function(_event) {
// To avoid a useless performance cost, we only call the label refresh when its necessary
if (gapRatio != module.get.gapRatio()) {
module.setup.labels();
gapRatio = module.get.gapRatio();
}
}
},
resync: function() {
module.verbose('Resyncing thumb position based on value');
if(module.is.range()) {
module.update.position(module.secondThumbVal, $secondThumb);
}
module.update.position(module.thumbVal, $thumb);
module.setup.labels();
},
takeStep: function(multiplier) {
multiplier = multiplier != undefined ? multiplier : 1;
var
step = module.get.step(),
currValue = module.get.currentThumbValue()
;
module.verbose('Taking a step');
if(step > 0) {
module.set.value(currValue + step * multiplier);
} else if (step == 0){
var
precision = module.get.precision(),
newValue = currValue + (multiplier/precision)
;
module.set.value(Math.round(newValue * precision) / precision);
}
},
backStep: function(multiplier) {
multiplier = multiplier != undefined ? multiplier : 1;
var
step = module.get.step(),
currValue = module.get.currentThumbValue()
;
module.verbose('Going back a step');
if(step > 0) {
module.set.value(currValue - step * multiplier);
} else if (step == 0) {
var
precision = module.get.precision(),
newValue = currValue - (multiplier/precision)
;
module.set.value(Math.round(newValue * precision) / precision);
}
},
is: {
range: function() {
return $module.hasClass(settings.className.range);
},
hover: function() {
return isHover;
},
focused: function() {
return $module.is(':focus');
},
disabled: function() {
return $module.hasClass(settings.className.disabled);
},
labeled: function() {
return $module.hasClass(settings.className.labeled);
},
reversed: function() {
return $module.hasClass(settings.className.reversed);
},
vertical: function() {
return $module.hasClass(settings.className.vertical);
},
smooth: function() {
return settings.smooth || $module.hasClass(settings.className.smooth);
}
},
get: {
trackOffset: function() {
if (module.is.vertical()) {
return $track.offset().top;
} else {
return $track.offset().left;
}
},
trackLength: function() {
if (module.is.vertical()) {
return $track.height();
} else {
return $track.width();
}
},
trackLeft: function() {
if (module.is.vertical()) {
return $track.position().top;
} else {
return $track.position().left;
}
},
trackStartPos: function() {
return module.is.reversed() ? module.get.trackLeft() + module.get.trackLength() : module.get.trackLeft();
},
trackEndPos: function() {
return module.is.reversed() ? module.get.trackLeft() : module.get.trackLeft() + module.get.trackLength();
},
trackStartMargin: function () {
var margin;
if (module.is.vertical()) {
margin = module.is.reversed() ? $module.css('padding-bottom') : $module.css('padding-top');
} else {
margin = module.is.reversed() ? $module.css('padding-right') : $module.css('padding-left');
}
return margin || '0px';
},
trackEndMargin: function () {
var margin;
if (module.is.vertical()) {
margin = module.is.reversed() ? $module.css('padding-top') : $module.css('padding-bottom');
} else {
margin = module.is.reversed() ? $module.css('padding-left') : $module.css('padding-right');
}
return margin || '0px';
},
precision: function() {
var
decimalPlaces,
step = module.get.step()
;
if(step != 0) {
var split = String(step).split('.');
if(split.length == 2) {
decimalPlaces = split[1].length;
} else {
decimalPlaces = 0;
}
} else {
decimalPlaces = settings.decimalPlaces;
}
var precision = Math.pow(10, decimalPlaces);
module.debug('Precision determined', precision);
return precision;
},
min: function() {
return settings.min;
},
max: function() {
var step = module.get.step(),
min = module.get.min(),
quotient = step === 0 ? 0 : Math.floor((settings.max - min) / step),
remainder = step === 0 ? 0 : (settings.max - min) % step;
return remainder === 0 ? settings.max : min + quotient * step;
},
step: function() {
return settings.step;
},
numLabels: function() {
var value = Math.round((module.get.max() - module.get.min()) / (module.get.step() === 0 ? 1 : module.get.step()));
module.debug('Determined that there should be ' + value + ' labels');
return value;
},
labelType: function() {
return settings.labelType;
},
label: function(value) {
if(interpretLabel) {
return interpretLabel(value);
}
switch (settings.labelType) {
case settings.labelTypes.number:
return Math.round(((value * (module.get.step() === 0 ? 1 : module.get.step())) + module.get.min()) * precision ) / precision;
case settings.labelTypes.letter:
return alphabet[(value) % 26];
default:
return value;
}
},
value: function() {
return value;
},
currentThumbValue: function() {
return $currThumb !== undefined && $currThumb.hasClass('second') ? module.secondThumbVal : module.thumbVal;
},
thumbValue: function(which) {
switch(which) {
case 'second':
if(module.is.range()) {
return module.secondThumbVal;
}
else {
module.error(error.notrange);
break;
}
case 'first':
default:
return module.thumbVal;
}
},
multiplier: function() {
return settings.pageMultiplier;
},
thumbPosition: function(which) {
switch(which) {
case 'second':
if(module.is.range()) {
return secondPos;
}
else {
module.error(error.notrange);
break;
}
case 'first':
default:
return position;
}
},
gapRatio: function() {
var gapRatio = 1;
if( settings.autoAdjustLabels ) {
var
numLabels = module.get.numLabels(),
trackLength = module.get.trackLength(),
gapCounter = 1
;
// While the distance between two labels is too short,
// we divide the number of labels at each iteration
// and apply only if the modulo of the operation is an odd number.
if(trackLength>0){
while ((trackLength / numLabels) * gapCounter < settings.labelDistance) {
if( !(numLabels % gapCounter) ) {
gapRatio = gapCounter;
}
gapCounter += 1;
}
}
}
return gapRatio;
}
},
determine: {
pos: function(pagePos) {
return module.is.reversed()
?
module.get.trackStartPos() - pagePos + module.get.trackOffset()
:
pagePos - module.get.trackOffset() - module.get.trackStartPos()
;
},
closestThumb: function(eventPos) {
var
thumbPos = parseFloat(module.determine.thumbPos($thumb)),
thumbDelta = Math.abs(eventPos - thumbPos),
secondThumbPos = parseFloat(module.determine.thumbPos($secondThumb)),
secondThumbDelta = Math.abs(eventPos - secondThumbPos)
;
if(thumbDelta === secondThumbDelta && module.get.thumbValue() === module.get.min()) {
return $secondThumb;
}
return thumbDelta <= secondThumbDelta ? $thumb : $secondThumb;
},
closestThumbPos: function(eventPos) {
var
thumbPos = parseFloat(module.determine.thumbPos($thumb)),
thumbDelta = Math.abs(eventPos - thumbPos),
secondThumbPos = parseFloat(module.determine.thumbPos($secondThumb)),
secondThumbDelta = Math.abs(eventPos - secondThumbPos)
;
return thumbDelta <= secondThumbDelta ? thumbPos : secondThumbPos;
},
thumbPos: function($element) {
var pos =
module.is.vertical()
?
module.is.reversed() ? $element.css('bottom') : $element.css('top')
:
module.is.reversed() ? $element.css('right') : $element.css('left')
;
return pos;
},
positionFromValue: function(val) {
var
min = module.get.min(),
max = module.get.max(),
value = val > max ? max : val < min ? min : val,
trackLength = module.get.trackLength(),
ratio = (value - min) / (max - min),
position = Math.round(ratio * trackLength)
;
module.verbose('Determined position: ' + position + ' from value: ' + value);
return position;
},
positionFromRatio: function(ratio) {
var
trackLength = module.get.trackLength(),
step = module.get.step(),
position = Math.round(ratio * trackLength),
adjustedPos = (step == 0) ? position : Math.round(position / step) * step
;
return adjustedPos;
},
valueFromEvent: function(event) {
var
eventPos = module.determine.eventPos(event),
newPos = module.determine.pos(eventPos),
value
;
if(eventPos < module.get.trackOffset()) {
value = module.is.reversed() ? module.get.max() : module.get.min();
} else if(eventPos > module.get.trackOffset() + module.get.trackLength()) {
value = module.is.reversed() ? module.get.min() : module.get.max();
} else {
value = module.determine.value(newPos);
}
return value;
},
smoothValueFromEvent: function(event) {
var
min = module.get.min(),
max = module.get.max(),
trackLength = module.get.trackLength(),
eventPos = module.determine.eventPos(event),
newPos = eventPos - module.get.trackOffset(),
ratio,
value
;
newPos = newPos < 0 ? 0 : newPos > trackLength ? trackLength : newPos;
ratio = newPos / trackLength;
if (module.is.reversed()) {
ratio = 1 - ratio;
}
value = ratio * (max - min) + min;
return value;
},
eventPos: function(event) {
if(event.type === "touchmove" || event.type === "touchend") {
var
touchEvent = event.touches ? event : event.originalEvent,
touch = touchEvent.changedTouches[0]; // fall back to first touch if correct touch not found
for(var i=0; i < touchEvent.touches.length; i++) {
if(touchEvent.touches[i].identifier === touchIdentifier) {
touch = touchEvent.touches[i];
break;
}
}
var
touchY = touch.pageY,
touchX = touch.pageX
;
return module.is.vertical() ? touchY : touchX;
}
var
clickY = event.pageY || event.originalEvent.pageY,
clickX = event.pageX || event.originalEvent.pageX
;
return module.is.vertical() ? clickY : clickX;
},
value: function(position) {
var
startPos = module.is.reversed() ? module.get.trackEndPos() : module.get.trackStartPos(),
endPos = module.is.reversed() ? module.get.trackStartPos() : module.get.trackEndPos(),
ratio = (position - startPos) / (endPos - startPos),
range = module.get.max() - module.get.min(),
step = module.get.step(),
value = (ratio * range),
difference = (step == 0) ? value : Math.round(value / step) * step
;
module.verbose('Determined value based upon position: ' + position + ' as: ' + value);
if(value != difference) {
module.verbose('Rounding value to closest step: ' + difference);
}
// Use precision to avoid ugly Javascript floating point rounding issues
// (like 35 * .01 = 0.35000000000000003)
module.verbose('Cutting off additional decimal places');
return Math.round((difference + module.get.min()) * precision) / precision;
},
keyMovement: function(event) {
var
key = event.which,
downArrow =
module.is.vertical()
?
module.is.reversed() ? keys.downArrow : keys.upArrow
:
keys.downArrow
,
upArrow =
module.is.vertical()
?
module.is.reversed() ? keys.upArrow : keys.downArrow
:
keys.upArrow
,
leftArrow =
!module.is.vertical()
?
module.is.reversed() ? keys.rightArrow : keys.leftArrow
:
keys.leftArrow
,
rightArrow =
!module.is.vertical()
?
module.is.reversed() ? keys.leftArrow : keys.rightArrow
:
keys.rightArrow
;
if(key == downArrow || key == leftArrow) {
return SINGLE_BACKSTEP;
} else if(key == upArrow || key == rightArrow) {
return SINGLE_STEP;
} else if (key == keys.pageDown) {
return BIG_BACKSTEP;
} else if (key == keys.pageUp) {
return BIG_STEP;
} else {
return NO_STEP;
}
}
},
handleNewValuePosition: function(val) {
var
min = module.get.min(),
max = module.get.max(),
newPos
;
if (val <= min) {
val = min;
} else if (val >= max) {
val = max;
}
newPos = module.determine.positionFromValue(val);
return newPos;
},
set: {
value: function(newValue, fireChange) {
fireChange = fireChange !== false;
var toReset = previousValue === undefined;
previousValue = previousValue === undefined ? module.get.value() : previousValue;
module.update.value(newValue, function(value, thumbVal, secondThumbVal) {
if ((!initialLoad || settings.fireOnInit) && fireChange){
if (newValue !== previousValue) {
settings.onChange.call(element, value, thumbVal, secondThumbVal);
}
settings.onMove.call(element, value, thumbVal, secondThumbVal);
}
if (toReset) {
previousValue = undefined;
}
});
},
rangeValue: function(first, second, fireChange) {
fireChange = fireChange !== false;
if(module.is.range()) {
var
min = module.get.min(),
max = module.get.max(),
toReset = previousValue === undefined
;
previousValue = previousValue === undefined ? module.get.value() : previousValue;
if (first <= min) {
first = min;
} else if(first >= max){
first = max;
}
if (second <= min) {
second = min;
} else if(second >= max){
second = max;
}
module.thumbVal = first;
module.secondThumbVal = second;
value = Math.abs(module.thumbVal - module.secondThumbVal);
module.update.position(module.thumbVal, $thumb);
module.update.position(module.secondThumbVal, $secondThumb);
if ((!initialLoad || settings.fireOnInit) && fireChange) {
if (value !== previousValue) {
settings.onChange.call(element, value, module.thumbVal, module.secondThumbVal);
}
settings.onMove.call(element, value, module.thumbVal, module.secondThumbVal);
}
if (toReset) {
previousValue = undefined;
}
} else {
module.error(error.notrange);
}
},
position: function(position, which) {
var thumbVal = module.determine.value(position);
if (which === 'second') {
module.secondThumbVal = thumbVal;
module.update.position(thumbVal, $secondThumb);
} else {
module.thumbVal = thumbVal;
module.update.position(thumbVal, $thumb);
}
value = Math.abs(module.thumbVal - (module.secondThumbVal || 0));
module.set.value(value);
}
},
update: {
value: function(newValue, callback) {
var
min = module.get.min(),
max = module.get.max()
;
if (newValue <= min) {
newValue = min;
} else if(newValue >= max){
newValue = max;
}
if(!module.is.range()) {
value = newValue;
module.thumbVal = value;
} else {
if($currThumb === undefined) {
$currThumb = newValue <= module.get.currentThumbValue() ? $thumb : $secondThumb;
}
if(!$currThumb.hasClass('second')) {
if(settings.preventCrossover && module.is.range()) {
newValue = Math.min(module.secondThumbVal, newValue);
}
module.thumbVal = newValue;
} else {
if(settings.preventCrossover && module.is.range()) {
newValue = Math.max(module.thumbVal, newValue);
}
module.secondThumbVal = newValue;
}
value = Math.abs(module.thumbVal - module.secondThumbVal);
}
module.update.position(newValue);
module.debug('Setting slider value to ' + value);
if(typeof callback === 'function') {
callback(value, module.thumbVal, module.secondThumbVal);
}
},
position: function(newValue, $element) {
var
newPos = module.handleNewValuePosition(newValue),
$targetThumb = $element != undefined ? $element : $currThumb,
thumbVal = module.thumbVal || module.get.min(),
secondThumbVal = module.secondThumbVal || module.get.min()
;
if(module.is.range()) {
if(!$targetThumb.hasClass('second')) {
position = newPos;
thumbVal = newValue;
} else {
secondPos = newPos;
secondThumbVal = newValue;
}
} else {
position = newPos;
thumbVal = newValue;
}
var
trackPosValue,
thumbPosValue,
min = module.get.min(),
max = module.get.max(),
thumbPosPercent = 100 * (newValue - min) / (max - min),
trackStartPosPercent = 100 * (Math.min(thumbVal, secondThumbVal) - min) / (max - min),
trackEndPosPercent = 100 * (1 - (Math.max(thumbVal, secondThumbVal) - min) / (max - min))
;
if (module.is.vertical()) {
if (module.is.reversed()) {
thumbPosValue = {bottom: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', top: 'auto'};
trackPosValue = {bottom: trackStartPosPercent + '%', top: trackEndPosPercent + '%'};
}
else {
thumbPosValue = {top: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', bottom: 'auto'};
trackPosValue = {top: trackStartPosPercent + '%', bottom: trackEndPosPercent + '%'};
}
} else {
if (module.is.reversed()) {
thumbPosValue = {right: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', left: 'auto'};
trackPosValue = {right: trackStartPosPercent + '%', left: trackEndPosPercent + '%'};
}
else {
thumbPosValue = {left: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', right: 'auto'};
trackPosValue = {left: trackStartPosPercent + '%', right: trackEndPosPercent + '%'};
}
}
$targetThumb.css(thumbPosValue);
$trackFill.css(trackPosValue);
module.debug('Setting slider position to ' + newPos);
},
labelPosition: function (ratio, $label) {
var
startMargin = module.get.trackStartMargin(),
endMargin = module.get.trackEndMargin(),
posDir =
module.is.vertical()
?
module.is.reversed() ? 'bottom' : 'top'
:
module.is.reversed() ? 'right' : 'left',
startMarginMod = module.is.reversed() && !module.is.vertical() ? ' - ' : ' + '
;
var position = '(100% - ' + startMargin + ' - ' + endMargin + ') * ' + ratio;
$label.css(posDir, 'calc(' + position + startMarginMod + startMargin + ')');
}
},
goto: {
max: function() {
module.set.value(module.get.max());
},
min: function() {
module.set.value(module.get.min());
},
},
read: {
metadata: function() {
var
data = {
thumbVal : $module.data(metadata.thumbVal),
secondThumbVal : $module.data(metadata.secondThumbVal)
}
;
if(data.thumbVal) {
if(module.is.range() && data.secondThumbVal) {
module.debug('Current value set from metadata', data.thumbVal, data.secondThumbVal);
module.set.rangeValue(data.thumbVal, data.secondThumbVal);
} else {
module.debug('Current value set from metadata', data.thumbVal);
module.set.value(data.thumbVal);
}
}
},
settings: function() {
if(settings.start !== false) {
if(module.is.range()) {
module.debug('Start position set from settings', settings.start, settings.end);
module.set.rangeValue(settings.start, settings.end);
} else {
module.debug('Start position set from settings', settings.start);
module.set.value(settings.start);
}
}
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = context || element;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(returnedValue)) {
returnedValue.push(response);
}
else if(returnedValue !== undefined) {
returnedValue = [returnedValue, response];
}
else if(response !== undefined) {
returnedValue = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
})
;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.slider.settings = {
silent : false,
debug : false,
verbose : false,
performance : true,
name : 'Slider',
namespace : 'slider',
error : {
method : 'The method you called is not defined.',
notrange : 'This slider is not a range slider'
},
metadata: {
thumbVal : 'thumbVal',
secondThumbVal : 'secondThumbVal'
},
min : 0,
max : 20,
step : 1,
start : 0,
end : 20,
labelType : 'number',
showLabelTicks : false,
smooth : false,
autoAdjustLabels : true,
labelDistance : 100,
preventCrossover : true,
fireOnInit : false,
interpretLabel : false,
//the decimal place to round to if step is undefined
decimalPlaces : 2,
// page up/down multiplier. How many more times the steps to take on page up/down press
pageMultiplier : 2,
selector: {
},
className : {
reversed : 'reversed',
disabled : 'disabled',
labeled : 'labeled',
ticked : 'ticked',
vertical : 'vertical',
range : 'range',
smooth : 'smooth'
},
keys : {
pageUp : 33,
pageDown : 34,
leftArrow : 37,
upArrow : 38,
rightArrow : 39,
downArrow : 40
},
labelTypes : {
number : 'number',
letter : 'letter'
},
onChange : function(value, thumbVal, secondThumbVal){},
onMove : function(value, thumbVal, secondThumbVal){},
};
})( jQuery, window, document );