Skip to content

Commit 24c0a2b

Browse files
authored
feat(slider): improve slider variants and gapratio
This PR enhances the slider component, so it - fixes some slider issues - tick color on inverted variant - tick position on vertical variant - wrong gapratio calculation when calculated number of labels is a prime number - adds internal caching of otherwise often repeated calculations - improves labelType "letter" option, - which now supports a custom letter string or array (was hardcoded before) - "increases" the letters in case more labels than given letters are needed (like the columns of a spreadsheet) - adds another variant vertical right aligned - adds an optional value fixed for autoAdjustLabels - adds another option highlightRange to slightly highlight the selected area range - supports the usage of ui label
1 parent 14bf847 commit 24c0a2b

File tree

4 files changed

+255
-50
lines changed

4 files changed

+255
-50
lines changed

src/definitions/modules/slider.js

Lines changed: 138 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
methodInvoked = typeof query === 'string',
3333
queryArguments = [].slice.call(arguments, 1),
3434

35-
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'],
36-
3735
SINGLE_STEP = 1,
3836
BIG_STEP = 2,
3937
NO_STEP = 0,
@@ -82,7 +80,6 @@
8280
position,
8381
secondPos,
8482
offset,
85-
precision,
8683
gapRatio = 1,
8784
previousValue,
8885

@@ -125,6 +122,7 @@
125122
clearInterval(instance.interval);
126123
module.unbind.events();
127124
module.unbind.slidingEvents();
125+
delete module.cache;
128126
$module.removeData(moduleNamespace);
129127
instance = undefined;
130128
},
@@ -141,7 +139,7 @@
141139
+ '<div class="thumb"></div>'
142140
+ '</div>');
143141
}
144-
precision = module.get.precision();
142+
module.clear.cache();
145143
$thumb = $module.find('.thumb:not(.second)');
146144
if (settings.showThumbTooltip) {
147145
$thumb
@@ -175,8 +173,14 @@
175173
module.setup.autoLabel();
176174
}
177175

176+
if (settings.highlightRange) {
177+
$labels.addClass(className.active);
178+
}
179+
178180
if (settings.showLabelTicks) {
179181
$module.addClass(className.ticked);
182+
} else if ($module.hasClass(className.ticked)) {
183+
settings.showLabelTicks = 'always';
180184
}
181185
}
182186
},
@@ -211,14 +215,20 @@
211215
} else {
212216
$labels = $module.append('<ul class="auto labels"></ul>').find('.labels');
213217
}
214-
for (var i = 0, len = module.get.numLabels(); i <= len; i++) {
218+
var step = module.get.step(),
219+
precision = module.get.precision(),
220+
len = module.get.numLabels(),
221+
ignoreLabels = len - (settings.autoAdjustLabels !== 'fixed' ? 0 : module.get.max().toString().length + 4)
222+
;
223+
for (var i = 0; i <= len; i++) {
215224
var
216-
labelText = module.get.label(i),
225+
stepValue = Math.round(((i * (step === 0 ? 1 : step)) + module.get.min()) * precision) / precision,
226+
labelText = module.get.label(i, stepValue),
217227
showLabel = settings.restrictedLabels.length === 0 || settings.restrictedLabels.indexOf(labelText) >= 0,
218228
$label = labelText !== '' && (showLabel || settings.showLabelTicks === 'always')
219-
? (!(i % module.get.gapRatio())
220-
? $('<li class="label">' + (showLabel ? labelText : '') + '</li>')
221-
: $('<li class="halftick label"></li>'))
229+
? ((!(i % module.get.gapRatio()) && i < ignoreLabels) || i === len
230+
? $('<li/>', { class: className.label, 'data-value': stepValue, html: showLabel ? labelText : '' })
231+
: $('<li/>', { class: 'halftick label', 'data-value': stepValue }))
222232
: null,
223233
ratio = i / len
224234
;
@@ -489,6 +499,12 @@
489499
},
490500
},
491501

502+
clear: {
503+
cache: function () {
504+
module.cache = {};
505+
},
506+
},
507+
492508
resync: function () {
493509
module.verbose('Resyncing thumb position based on value');
494510
if (module.is.range()) {
@@ -538,6 +554,25 @@
538554
},
539555

540556
is: {
557+
prime: function (n) {
558+
if (module.cache['prime' + n] === undefined) {
559+
var p = true;
560+
for (var i = 2, s = Math.sqrt(n); i <= s; i++) {
561+
if (n % i === 0) {
562+
p = false;
563+
564+
break;
565+
}
566+
}
567+
if (p) {
568+
p = n > 1;
569+
}
570+
571+
module.cache['prime' + n] = p;
572+
}
573+
574+
return module.cache['prime' + n];
575+
},
541576
range: function () {
542577
var isRange = $module.hasClass(className.range);
543578
if (!isRange && (settings.minRange || settings.maxRange)) {
@@ -652,62 +687,87 @@
652687
return margin || '0px';
653688
},
654689
precision: function () {
655-
var
656-
decimalPlaces,
657-
step = module.get.step()
658-
;
659-
if (step !== 0) {
660-
var split = String(step).split('.');
661-
decimalPlaces = split.length === 2 ? split[1].length : 0;
662-
} else {
663-
decimalPlaces = settings.decimalPlaces;
690+
if (module.cache.precision === undefined) {
691+
var
692+
decimalPlaces,
693+
step = module.get.step()
694+
;
695+
if (step !== 0) {
696+
var split = String(step).split('.');
697+
decimalPlaces = split.length === 2 ? split[1].length : 0;
698+
} else {
699+
decimalPlaces = settings.decimalPlaces;
700+
}
701+
var precision = Math.pow(10, decimalPlaces);
702+
module.debug('Precision determined', precision);
703+
module.cache.precision = precision;
664704
}
665-
var precision = Math.pow(10, decimalPlaces);
666-
module.debug('Precision determined', precision);
667705

668-
return precision;
706+
return module.cache.precision;
669707
},
670708
min: function () {
671709
return settings.min;
672710
},
673711
max: function () {
674-
var
675-
step = module.get.step(),
676-
min = module.get.min(),
677-
precision = module.get.precision(),
678-
quotient = step === 0 ? 0 : Math.floor(Math.round(((settings.max - min) / step) * precision) / precision),
679-
remainder = step === 0 ? 0 : (settings.max - min) % step
680-
;
712+
if (module.cache.max === undefined) {
713+
var
714+
step = module.get.step(),
715+
min = module.get.min(),
716+
precision = module.get.precision(),
717+
quotient = step === 0 ? 0 : Math.floor(Math.round(((settings.max - min) / step) * precision) / precision),
718+
remainder = step === 0 ? 0 : (settings.max - min) % step
719+
;
720+
if (remainder > 0) {
721+
module.debug('Max value not divisible by given step. Increasing max value.', settings.max, step);
722+
}
723+
module.cache.max = remainder === 0 ? settings.max : min + quotient * step;
724+
}
681725

682-
return remainder === 0 ? settings.max : min + quotient * step;
726+
return module.cache.max;
683727
},
684728
step: function () {
685729
return settings.step;
686730
},
687731
numLabels: function () {
688-
var step = module.get.step(),
689-
precision = module.get.precision(),
690-
value = Math.round(((module.get.max() - module.get.min()) / (step === 0 ? 1 : step)) * precision) / precision;
691-
module.debug('Determined that there should be ' + value + ' labels');
732+
if (module.cache.numLabels === undefined) {
733+
var step = module.get.step(),
734+
precision = module.get.precision(),
735+
value = Math.round(((module.get.max() - module.get.min()) / (step === 0 ? 1 : step)) * precision) / precision;
736+
module.debug('Determined that there should be ' + value + ' labels');
737+
module.cache.numLabels = value;
738+
}
692739

693-
return value;
740+
return module.cache.numLabels;
694741
},
695742
labelType: function () {
696743
return settings.labelType;
697744
},
698-
label: function (value) {
699-
if (interpretLabel) {
700-
return interpretLabel(value);
745+
label: function (value, stepValue) {
746+
if (isFunction(interpretLabel)) {
747+
return interpretLabel(value, stepValue, module);
701748
}
702749

703750
switch (settings.labelType) {
704751
case settings.labelTypes.number: {
705-
var step = module.get.step();
706-
707-
return Math.round(((value * (step === 0 ? 1 : step)) + module.get.min()) * precision) / precision;
752+
return stepValue;
708753
}
709754
case settings.labelTypes.letter: {
710-
return alphabet[value % 26];
755+
if (value < 0 || module.get.precision() > 1) {
756+
module.error(error.invalidLetterNumber, value);
757+
758+
return value;
759+
}
760+
var letterLabel = '',
761+
letters = Array.isArray(settings.letters) ? settings.letters : String(settings.letters).split(''),
762+
lettersLen = letters.length
763+
;
764+
765+
while (stepValue >= 0) {
766+
letterLabel = letters[stepValue % lettersLen] + letterLabel;
767+
stepValue = Math.floor(stepValue / lettersLen) - 1;
768+
}
769+
770+
return letterLabel;
711771
}
712772
default: {
713773
return value;
@@ -717,6 +777,9 @@
717777
value: function () {
718778
return value;
719779
},
780+
settings: function () {
781+
return settings;
782+
},
720783
currentThumbValue: function () {
721784
return $currThumb !== undefined && $currThumb.hasClass('second') ? module.secondThumbVal : module.thumbVal;
722785
},
@@ -761,6 +824,7 @@
761824
if (settings.autoAdjustLabels) {
762825
var
763826
numLabels = module.get.numLabels(),
827+
primePlus = module.is.prime(numLabels) ? 1 : 0,
764828
trackLength = module.get.trackLength(),
765829
gapCounter = 1
766830
;
@@ -770,7 +834,7 @@
770834
// and apply only if the modulo of the operation is an odd number.
771835
if (trackLength > 0) {
772836
while ((trackLength / numLabels) * gapCounter < settings.labelDistance) {
773-
if (!(numLabels % gapCounter)) {
837+
if (!((numLabels + primePlus) % gapCounter) || settings.autoAdjustLabels === 'fixed') {
774838
gapRatio = gapCounter;
775839
}
776840
gapCounter += 1;
@@ -908,6 +972,7 @@
908972
},
909973
value: function (position) {
910974
var
975+
precision = module.get.precision(),
911976
startPos = module.is.reversed() ? module.get.trackEndPos() : module.get.trackStartPos(),
912977
endPos = module.is.reversed() ? module.get.trackStartPos() : module.get.trackEndPos(),
913978
ratio = (position - startPos) / (endPos - startPos),
@@ -976,6 +1041,30 @@
9761041
},
9771042

9781043
set: {
1044+
active: function (thumbVal, secondThumbVal) {
1045+
if (settings.highlightRange) {
1046+
if (secondThumbVal < thumbVal) {
1047+
var tempVal = secondThumbVal;
1048+
secondThumbVal = thumbVal;
1049+
thumbVal = tempVal;
1050+
}
1051+
var $children = $labels.find('.label');
1052+
$children.each(function (index) {
1053+
var
1054+
$child = $(this),
1055+
attrValue = $child.attr('data-value')
1056+
;
1057+
if (attrValue) {
1058+
attrValue = parseInt(attrValue, 10);
1059+
if (attrValue >= thumbVal && attrValue <= secondThumbVal) {
1060+
$child.addClass(className.active);
1061+
} else {
1062+
$child.removeClass(className.active);
1063+
}
1064+
}
1065+
});
1066+
}
1067+
},
9791068
value: function (newValue, fireChange) {
9801069
fireChange = fireChange !== false;
9811070
var toReset = previousValue === undefined;
@@ -1103,6 +1192,7 @@
11031192
position = newPos;
11041193
thumbVal = newValue;
11051194
}
1195+
module.set.active(thumbVal, secondThumbVal);
11061196
var
11071197
trackPosValue,
11081198
thumbPosValue,
@@ -1210,6 +1300,7 @@
12101300
} else {
12111301
return settings[name];
12121302
}
1303+
module.clear.cache();
12131304
},
12141305
internal: function (name, value) {
12151306
if ($.isPlainObject(name)) {
@@ -1382,6 +1473,7 @@
13821473
method: 'The method you called is not defined.',
13831474
notrange: 'This slider is not a range slider',
13841475
invalidRanges: 'Invalid range settings (start/end/minRange/maxRange)',
1476+
invalidLetterNumber: 'Negative values or decimal places for labelType: "letter" are not supported',
13851477
},
13861478

13871479
metadata: {
@@ -1404,6 +1496,7 @@
14041496
preventCrossover: true,
14051497
fireOnInit: false,
14061498
interpretLabel: false,
1499+
letters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
14071500

14081501
// the decimal place to round to if step is undefined
14091502
decimalPlaces: 2,
@@ -1421,6 +1514,8 @@
14211514
vertical: 'vertical',
14221515
range: 'range',
14231516
smooth: 'smooth',
1517+
label: 'label',
1518+
active: 'active',
14241519
},
14251520

14261521
keys: {
@@ -1433,6 +1528,7 @@
14331528
},
14341529

14351530
restrictedLabels: [],
1531+
highlightRange: false,
14361532
showThumbTooltip: false,
14371533
tooltipConfig: {
14381534
position: 'top center',

0 commit comments

Comments
 (0)