Browse Source

Made range.js to match the format of the other js files. Added a undefined step range.

pull/4212/head
Gareth Daunton 8 years ago
parent
commit
35b994a1c2
1 changed files with 561 additions and 210 deletions
  1. 771
      src/definitions/modules/range.js

771
src/definitions/modules/range.js

@ -7,14 +7,28 @@
"use strict";
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.range = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1)
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules
@ -25,28 +39,28 @@ $.fn.range = function(parameters) {
? $.extend(true, {}, $.fn.range.settings, parameters)
: $.extend({}, $.fn.range.settings),
className = settings.className,
metadata = settings.metadata,
namespace = settings.namespace,
min = settings.min,
max = settings.max,
step = settings.step,
start = settings.start,
input = settings.input,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$thumb,
$track,
$trackFill,
element = this,
instance = $module.data(moduleNamespace),
reversed = $module.hasClass('reversed'),
$thumb,
$track,
$trackFill,
precision,
reversed = $module.hasClass(settings.className.reversed),
offset,
precision,
isTouch,
module
;
@ -54,227 +68,536 @@ $.fn.range = function(parameters) {
module = {
initialize: function() {
module.debug('Initializing range slider', settings);
isTouch = module.get.isTouch();
module.setup.layout();
module.bind.events();
module.read.metadata();
module.read.settings();
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of range', module);
instance = module;
$module.data(moduleNamespace, module);
$module.html("<div class='inner'><div class='track'></div><div class='track-fill'></div><div class='thumb'></div></div>");
$track = $module.find('.track');
$thumb = $module.find('.thumb');
$trackFill = $module.find('.track-fill');
offset = $thumb.width()/2;
// find precision of step, used in calculating the value
module.determinePrecision();
// set start location
module.setPositionBasedValue(settings.start);
// event listeners
$module.find('.track, .thumb, .inner').on('mousedown', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('mousedown', event);
});
$module.find('.track, .thumb, .inner').on('touchstart', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('touchstart', event);
});
$module.on('mousedown', function(event, originalEvent) {
module.rangeMousedown(event, false, originalEvent);
});
$module.on('touchstart', function(event, originalEvent) {
module.rangeMousedown(event, true, originalEvent);
});
},
determinePrecision: function() {
var split = String(settings.step).split('.');
var decimalPlaces;
if(split.length == 2) {
decimalPlaces = split[1].length;
} else {
decimalPlaces = 0;
}
precision = Math.pow(10, decimalPlaces);
},
determineValue: function(startPos, endPos, currentPos) {
if(reversed) {
var temp = startPos;
startPos = endPos;
endPos = temp;
}
var
ratio = (currentPos - startPos) / (endPos - startPos),
range = settings.max - settings.min,
difference = Math.round(ratio * range / step) * step
;
// Use precision to avoid ugly Javascript floating point rounding issues
// (like 35 * .01 = 0.35000000000000003)
difference = Math.round(difference * precision) / precision;
return difference + settings.min;
},
determinePosition: function(value) {
var
ratio = (value - settings.min) / (settings.max - settings.min),
trackPos = reversed ? $track.width() - ($trackFill.position().left + $trackFill.width()) : $trackFill.position().left
$module
.data(moduleNamespace, module)
;
return Math.round(ratio * $track.width()) + trackPos;
},
setValue: function(newValue) {
if(settings.input) {
$(settings.input).val(newValue);
}
if(settings.onChange) {
settings.onChange(newValue);
}
},
destroy: function() {
module.verbose('Destroying previous range for', $module);
clearInterval(instance.interval);
module.unbind.events();
module.unbind.documentEvents();
$module.removeData(moduleNamespace);
instance = undefined;
},
setPosition: function(value) {
if (reversed)
$thumb.css({right: String(value - offset) + 'px'});
else
$thumb.css({left: String(value - offset) + 'px'});
$trackFill.css({width: String(value) + 'px'});
},
setup: {
layout: function() {
$module.html("<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');
$track = $module.find('.track');
$trackFill = $module.find('.track-fill');
offset = $thumb.width()/2;
},
},
rangeMousedown: function(mdEvent, isTouch, originalEvent) {
if( !$module.hasClass('disabled') ) {
mdEvent.preventDefault();
var
trackLeft = $track.position().left,
trackOffset = $track.offset().left,
trackWidth = $track.width(),
trackStartPos = reversed ? trackLeft + trackWidth : trackLeft,
trackEndPos = reversed ? trackLeft : trackLeft + trackWidth,
pageX = isTouch ? originalEvent.originalEvent.touches[0].pageX : (typeof mdEvent.pageX != 'undefined') ? mdEvent.pageX : originalEvent.pageX,
newPos = reversed ? trackStartPos - pageX + trackOffset : pageX - trackOffset - trackStartPos,
value
;
// if(pageX >= trackFill && pageX <= trackFill + trackWidth) {
// value = module.setValueBasedPosition(newPos);
// }
var rangeMousemove = function(mmEvent) {
mmEvent.preventDefault();
if(isTouch) {
pageX = mmEvent.originalEvent.touches[0].pageX;
} else {
pageX = mmEvent.pageX;
}
newPos = reversed ? trackStartPos - pageX + trackOffset : pageX - trackOffset - trackStartPos;
if(pageX >= trackOffset && pageX <= trackOffset + trackWidth) {
value = module.setValueBasedPosition(newPos);
}
bind: {
events: function() {
// event listeners
$module.find('.track, .thumb, .inner').on('mousedown', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('mousedown', event);
module.event.down(event);
});
$module.find('.track, .thumb, .inner').on('touchstart', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('touchstart', event);
module.event.down(event);
});
$module.on('mousedown' + eventNamespace, module.event.down);
$module.on('touchstart' + eventNamespace, module.event.down);
},
documentEvents: function() {
if(module.get.isTouch()) {
$(document).on('touchmove' + eventNamespace, module.event.move);
$(document).on('touchend' + eventNamespace, module.event.up);
}
var rangeMouseup = function(muEvent) {
if(pageX >= trackOffset && pageX <= trackOffset + trackWidth) {
module.setValueMoveToValueBasedPosition(newPos);
}
if(isTouch) {
$(document).off('touchmove', rangeMousemove);
$(document).off('touchend', rangeMouseup);
}
else {
$(document).off('mousemove', rangeMousemove);
$(document).off('mouseup', rangeMouseup);
}
else {
$(document).on('mousemove' + eventNamespace, module.event.move);
$(document).on('mouseup' + eventNamespace, module.event.up);
}
if(isTouch) {
$(document).on('touchmove', rangeMousemove);
$(document).on('touchend', rangeMouseup);
}
},
unbind: {
events: function() {
$module.find('.track, .thumb, .inner').off('mousedown', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('mousedown', event);
module.event.mousedown(event);
});
$module.find('.track, .thumb, .inner').off('touchstart', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".range").trigger('touchstart', event);
module.event.touchstart(event);
});
$module.off('mousedown' + eventNamespace, module.event.down);
$module.off('touchstart' + eventNamespace, module.event.down);
},
documentEvents: function() {
if(module.get.isTouch()) {
$(document).off('touchmove' + eventNamespace, module.event.move);
$(document).off('touchend' + eventNamespace, module.event.up);
}
else {
$(document).on('mousemove', rangeMousemove);
$(document).on('mouseup', rangeMouseup);
$(document).off('mousemove' + eventNamespace, module.event.move);
$(document).off('mouseup' + eventNamespace, module.event.up);
}
}
},
},
},
setMaxPosition: function() {
var
trackLeft = $track.position().left,
trackWidth = $track.width(),
trackEndPos = reversed ? trackLeft : trackLeft + trackWidth
;
module.setPosition(trackEndPos);
event: {
down: function(event, originalEvent) {
event.preventDefault();
module.bind.documentEvents();
},
move: function(event, originalEvent) {
event.preventDefault();
var
pageX = module.determine.eventXPos(event, originalEvent),
newPos = module.determine.pos(pageX)
;
if (pageX >= module.get.trackOffset() && pageX <= module.get.trackOffset() + module.get.trackWidth()) {
module.set.valueBasedPosition(newPos);
}
},
up: function(event, originalEvent) {
event.preventDefault();
var
pageX = module.determine.eventXPos(event, originalEvent),
newPos = module.determine.pos(pageX)
;
if(pageX >= module.get.trackOffset() && pageX <= module.get.trackOffset() + module.get.trackWidth()) {
module.set.valueMoveToValueBasedPosition(newPos);
}
module.unbind.documentEvents();
},
},
setMinPosition: function() {
var
trackLeft = $track.position().left,
trackWidth = $track.width(),
trackStartPos = reversed ? trackLeft + trackWidth : trackLeft
;
module.setPosition(trackStartPos);
get: {
isTouch: function () {
try {
document.createEvent('TouchEvent');
return true;
} catch (e) {
return false;
}
},
trackOffset: function() {
return $track.offset().left;
},
trackWidth: function() {
return $track.width();
},
trackLeft: function() {
return $track.position().left;
},
trackStartPos: function() {
return reversed ? module.get.trackLeft() + module.get.trackWidth() : module.get.trackLeft();
},
trackEndPos: function() {
return reversed ? module.get.trackLeft() : module.get.trackLeft() + module.get.trackWidth();
},
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 module.min || settings.min;
},
max: function() {
return module.max || settings.max;
},
step: function() {
return module.step || settings.step;
},
},
determine: {
pos: function(pagePos) {
return reversed ? module.get.trackStartPos() - pagePos + module.get.trackOffset() : pagePos - module.get.trackOffset() - module.get.trackStartPos();
},
value: function(position) {
var
startPos = reversed ? module.get.trackEndPos() : module.get.trackStartPos(),
endPos = 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)
difference = Math.round(difference * precision) / precision;
module.verbose('Cutting ')
return difference - module.get.min();
},
positionFromValue: function(value) {
var
min = module.get.min(),
max = module.get.max(),
trackWidth = module.get.trackWidth(),
ratio = (value - min) / (max - min),
trackPos = reversed ? trackWidth - ($trackFill.position().left + $trackFill.width()) : $trackFill.position().left,
position = Math.round(ratio * trackWidth) + trackPos
;
module.verbose('Determined position: ' + position + ' from value: ' + value);
return position;
},
eventXPos: function(event, originalEvent) {
return isTouch ? originalEvent.originalEvent.touches[0].pageX : (typeof event.pageX != 'undefined') ? event.pageX : originalEvent.pageX
},
},
set: {
value: function(newValue) {
if(input) {
$(input).val(newValue);
}
settings.onChange.call(element, newValue);
module.debug('Setting range value to ' + newValue);
},
max: function(value) {
module.max = value;
},
min: function(value) {
module.min = value;
},
step: function(value) {
module.step = value;
},
position: function(value) {
if (reversed)
$thumb.css({right: String(value - offset) + 'px'});
else
$thumb.css({left: String(value - offset) + 'px'});
$trackFill.css({width: String(value) + 'px'});
module.position = value;
module.debug('Setting range position to ' + value);
},
positionBasedValue: function(value) {
var
min = module.get.min(),
max = module.get.max()
;
if(value >= min && value <= max) {
var position = module.determine.positionFromValue(value);
module.set.position(position);
module.set.value(value);
} else if (value <= min) {
module.goto.min();
module.set.value(min);
} else {
module.goto.max();
module.set.value(max);
}
},
valueMoveToValueBasedPosition: function(position) {
var
value = module.determine.value(position),
min = module.get.min(),
max = module.get.max(),
pos
;
if (value <= min) {
value = min;
} else if (value >= max){
value = max;
}
pos = module.determine.positionFromValue(value);
module.set.value(value);
module.set.position(pos);
},
valueBasedPosition: function(position) {
var
value = module.determine.value(position),
min = module.get.min(),
max = module.get.max()
;
if(value >= min && value <= max) {
module.set.position(position);
} else if (value <= min) {
module.goto.min();
value = min;
} else {
module.goto.max();
value = max;
}
module.set.value(value);
},
},
goto: {
max: function() {
module.set.position(module.get.trackEndPos());
},
min: function() {
module.set.position(module.get.trackStartPos());
},
},
setPositionBasedValue: function(value) {
if(value >= settings.min && value <= settings.max) {
var position = module.determinePosition(value);
module.setPosition(position);
module.setValue(value);
} else if (value <= settings.min) {
module.setMinPosition();
module.setValue(settings.min);
} else {
module.setMaxPosition();
module.setValue(settings.max);
remove : {
state: function() {
module.verbose('Removing stored state');
delete module.min;
delete module.max;
delete module.value;
delete module.position;
}
},
},
setValueMoveToValueBasedPosition: function(position) {
var
trackLeft = $track.position().left,
trackWidth = $track.width(),
trackStartPos = reversed ? trackLeft + trackWidth : trackLeft,
trackEndPos = reversed ? trackLeft : trackLeft + trackWidth,
value = module.determineValue(trackStartPos, trackEndPos, position),
pos
;
if (value <= settings.min) {
value = settings.min;
} else if (value >= settings.max){
value = settings.max;
read: {
metadata: function() {
var
data = {
value : $module.data(metadata.value),
min : $module.data(metadata.min),
max : $module.data(metadata.max),
step : $module.data(metadata.step),
}
;
if(data.value) {
module.debug('Current value set from metadata', data.value);
module.set.value(data.value);
module.set.positionBasedValue(data.value);
}
if(data.min) {
module.debug('Current min set from metadata', data.min);
module.set.value(data.min);
module.set.positionBasedValue(data.min);
}
if(data.max) {
module.debug('Current max set from metadata', data.max);
module.set.value(data.max);
module.set.positionBasedValue(data.max);
}
if(data.step) {
module.debug('Current step set from metadata', data.step);
module.set.value(data.step);
module.set.positionBasedValue(data.step);
}
},
settings: function() {
if(settings.min !== false) {
module.debug('Current min set in settings', settings.min);
module.set.min(settings.min);
}
if(settings.max !== false) {
module.debug('Current max set from settings', settings.max);
module.set.max(settings.max);
}
if(settings.step !== false) {
module.debug('Current step set from settings', settings.step);
module.set.step(settings.step);
}
if(settings.start !== false) {
module.debug('Start position set from settings', settings.start);
module.set.positionBasedValue(settings.start);
}
}
pos = module.determinePosition(value);
module.setValue(value);
module.setPosition(pos);
},
setValueBasedPosition: function(position) {
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
trackLeft = $track.position().left,
trackWidth = $track.width(),
trackStartPos = reversed ? trackLeft + trackWidth : trackLeft,
trackEndPos = reversed ? trackLeft : trackLeft + trackWidth,
value = module.determineValue(trackStartPos, trackEndPos, position)
object = instance,
maxDepth,
found,
response
;
if(value >= settings.min && value <= settings.max) {
module.setPosition(position);
} else if (value <= settings.min) {
module.setMinPosition();
value = settings.min;
} else {
module.setMaxPosition();
value = settings.max;
passedArguments = passedArguments || queryArguments;
context = element || context;
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;
}
});
}
module.setValue(value);
},
invoke: function(query) {
switch(query) {
case 'set value':
if(queryArguments.length > 0) {
instance.setPositionBasedValue(queryArguments[0]);
}
break;
}
},
};
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) {
@ -283,26 +606,54 @@ $.fn.range = function(parameters) {
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
})
;
return this;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.range.settings = {
silent : false,
debug : false,
verbose : false,
performance : true,
name : 'Range',
namespace : 'range',
min : 0,
max : false,
step : 1,
start : 0,
input : false,
error : {
method : 'The method you called is not defined.',
},
metadata: {
value : 'value',
min : 'min',
max : 'max',
step : 'step'
},
min : 0,
max : 20,
step : 1,
start : 0,
input : false,
//the decimal place to round to if step is undefined
decimalPlaces : 2,
className : {
reversed : 'reversed'
},
onChange : function(value){},

Loading…
Cancel
Save