PageSourceSearch

https://www.littlesandysquiltshop.com/1739468536/c/controls/range-slider/range-slider.directive.js

js littlesandysquiltshop.com collected 2026-09-24 14:05:12 UTC 10,110 bytes, 279 lines download raw bytes

1angular.module('rainApp').directive('rangeSlider', function ($document) {
2    return {
3        restrict: 'E',
4        scope: {
5            min: '=',
6            max: '=',
7            minValue: '=',
8            maxValue: '=',
9            isPriceFilter: '@',
10            isFloat: '=',
11            useDynamicRanges: '=',
12            onUpdate: '&',
13        },
14        templateUrl: function () {
15            return '/c/controls/range-slider/range-slider.template.html';
16        },
17        link: function (scope, element) {
18            var container = element[0].querySelector('.slider-container');
19            var track = container.querySelector('.slider-track');
20            var range = container.querySelector('.slider-range');
21            var thumbMin = container.querySelector('.slider-thumb.min');
22            var thumbMax = container.querySelector('.slider-thumb.max');
23
24            scope.inputMinValue = formatWithCommasAndCurrency(scope.minValue);
25            scope.inputMaxValue = formatWithCommasAndCurrency(scope.maxValue);
26
27            var activeThumb = null;
28
29            function getAdjustedRanges(dynamicRanges) {
30                var adjustedRanges = [];
31
32                for (var i = 0; i < dynamicRanges.length; i++) {
33                    var range = dynamicRanges[i];
34
35                    if (range.min >= scope.max) {
36                        break;
37                    }
38
39                    adjustedRanges.push({
40                        min: range.min,
41                        max: Math.min(range.max, scope.max),
42                        increment: range.increment
43                    });
44                }
45
46                return adjustedRanges;
47            }
48
49            function getTotalWeight(ranges) {
50                return ranges.reduce((sum, range) => sum + (range.max - range.min) / range.increment, 0);
51            }
52
53            function getValueFromPercentageDynamic(percent, ranges) {
54                var targetWeight = (percent / 100) * getTotalWeight(ranges);
55                var accumulatedWeight = 0;
56
57                for (var i = 0; i < ranges.length; i++) {
58                    var rangeWeight = (ranges[i].max - ranges[i].min) / ranges[i].increment;
59
60                    if (targetWeight <= accumulatedWeight + rangeWeight) {
61                        var stepsInRange = targetWeight - accumulatedWeight;
62                        return ranges[i].min + stepsInRange * ranges[i].increment;
63                    }
64
65                    accumulatedWeight += rangeWeight;
66                }
67
68                return scope.max;
69            }
70
71            function getPercentageFromValueDynamic(value, ranges) {
72                var accumulatedWeight = 0;
73
74                for (var i = 0; i < ranges.length; i++) {
75                    if (value <= ranges[i].max) {
76                        var stepsInRange = (value - ranges[i].min) / ranges[i].increment;
77                        return ((accumulatedWeight + stepsInRange) / getTotalWeight(ranges)) * 100;
78                    }
79
80                    accumulatedWeight += (ranges[i].max - ranges[i].min) / ranges[i].increment;
81                }
82
83                return 100;
84            }
85
86            function getValueFromPercentageLinear(percent) {
87                return scope.min + (percent / 100) * (scope.max - scope.min);
88            }
89
90            function getPercentageFromValueLinear(value) {
91                return ((value - scope.min) / (scope.max - scope.min)) * 100;
92            }
93
94            function getValueFromPercentage(percent) {
95                if (scope.useDynamicRanges) {
96                    var ranges = getAdjustedRanges(scope.useDynamicRanges);
97                    return getValueFromPercentageDynamic(percent, ranges);
98                }
99
100                return getValueFromPercentageLinear(percent);
101            }
102
103            function getPercentageFromValue(value) {
104                if (scope.useDynamicRanges) {
105                    var ranges = getAdjustedRanges(scope.useDynamicRanges);
106                    return getPercentageFromValueDynamic(value, ranges);
107                }
108
109                return getPercentageFromValueLinear(value);
110            }
111
112            function updatePositions() {
113                var percentMin = getPercentageFromValue(scope.minValue);
114                var percentMax = getPercentageFromValue(scope.maxValue);
115
116                thumbMin.style.left = `${percentMin}%`;
117                thumbMax.style.left = `${percentMax}%`;
118
119                range.style.left = `${percentMin}%`;
120                range.style.right = `${100 - percentMax}%`;
121
122                if (percentMin > 50) {
123                    thumbMin.style.zIndex = 2;
124                    thumbMax.style.zIndex = 1;
125                } else {
126                    thumbMin.style.zIndex = 1;
127                    thumbMax.style.zIndex = 2;
128                }
129            }
130
131            function setModelValue(percent) {
132                var isMin = activeThumb.classList.contains('min');
133                var value = getValueFromPercentage(percent);
134
135                if (isMin) {
136                    scope.minValue = Math.min(value, scope.maxValue);
137                    scope.inputMinValue = formatWithCommasAndCurrency(Math.min(value, scope.maxValue));
138                } else {
139                    scope.maxValue = Math.max(value, scope.minValue);
140                    scope.inputMaxValue = formatWithCommasAndCurrency(Math.max(value, scope.minValue));
141                }
142
143                scope.$apply();
144            }
145
146            function startDrag(event, thumb) {
147                event.preventDefault();
148                activeThumb = thumb;
149
150                $document.on('mousemove', onDrag);
151                $document.on('mouseup', stopDrag);
152            }
153
154            function onDrag(event) {
155                if (!activeThumb) {
156                    return;
157                }
158
159                var rect = track.getBoundingClientRect();
160                var percent = Math.min(100, Math.max(0, ((event.clientX - rect.left) / rect.width) * 100));
161
162                setModelValue(percent);
163            }
164
165            function stopDrag() {
166                activeThumb = null;
167
168                $document.off('mousemove', onDrag);
169                $document.off('mouseup', stopDrag);
170            }
171
172            scope.applyMinKeyUp = function (event) {
173                if (13 === event.keyCode) {
174                    scope.triggerMinUpdate();
175                }
176            }
177
178            scope.applyMaxKeyUp = function (event) {
179                if (13 === event.keyCode) {
180                    scope.triggerMaxUpdate();
181                }
182            }
183
184            scope.applyMinValue = function () {
185                validateMinValue();
186
187                scope.minValue = scope.inputMinValue;
188                scope.inputMinValue = formatWithCommasAndCurrency(scope.inputMinValue);
189
190                updatePositions();
191            }
192
193            scope.setMinValueWithoutCommas = function () {
194                if (scope.isFloat) {
195                    scope.inputMinValue = parseFloat(scope.minValue).toFixed(2);
196                } else {
197                    scope.inputMinValue = scope.minValue;
198                }
199            }
200
201            function validateMinValue() {
202                scope.inputMinValue = String(scope.inputMinValue).replace(/[^\d.]/g, '');
203
204                var minRangeValue = scope.min;
205                var maxRangeValue = scope.maxValue;
206
207                if (scope.inputMinValue < minRangeValue) {
208                    scope.inputMinValue = minRangeValue;
209                }
210                if (scope.inputMinValue > maxRangeValue) {
211                    scope.inputMinValue = maxRangeValue;
212                }
213            }
214
215            function formatWithCommasAndCurrency(value) {
216                var options = scope.isFloat
217                    ? { minimumFractionDigits: 2, maximumFractionDigits: 2, style: 'decimal' }
218                    : { minimumFractionDigits: 0, maximumFractionDigits: 0, style: 'decimal' };
219
220                var formatter = new Intl.NumberFormat(false, options);
221                return scope.isPriceFilter ? (window.currencySymbol || '$') + ' ' + formatter.format(value) : formatter.format(value);
222            }
223
224            scope.applyMaxValue = function () {
225                validateMaxValue();
226
227                scope.maxValue = scope.inputMaxValue;
228                scope.inputMaxValue = formatWithCommasAndCurrency(scope.inputMaxValue);
229
230                updatePositions();
231            }
232
233            scope.setMaxValueWithoutCommas = function () {
234                if (scope.isFloat) {
235                    scope.inputMaxValue = parseFloat(scope.maxValue).toFixed(2);
236                } else {
237                    scope.inputMaxValue = scope.maxValue;
238                }
239            }
240
241            function validateMaxValue() {
242                scope.inputMaxValue = parseFloat(String(scope.inputMaxValue).replace(/[^\d.]/g, ''));
243
244                var minRangeValue = scope.minValue;
245                var maxRangeValue = scope.max;
246
247                if (scope.inputMaxValue > maxRangeValue) {
248                    scope.inputMaxValue = maxRangeValue;
249                }
250
251                if (scope.inputMaxValue < minRangeValue) {
252                    scope.inputMaxValue = minRangeValue;
253                }
254            }
255
256            scope.triggerMinUpdate = function () {
257                scope.applyMinValue()
258                scope.onUpdate({ $event: { update: true } });
259            };
260
261            scope.triggerMaxUpdate = function () {
262                scope.applyMaxValue()
263                scope.onUpdate({ $event: { update: true } });
264            };
265
266            thumbMin.addEventListener('mousedown', function (event) {
267                startDrag(event, thumbMin)
268            });
269            thumbMax.addEventListener('mousedown', function (event) {
270                startDrag(event, thumbMax)
271            });
272
273            scope.$watchGroup(['minValue', 'maxValue'], updatePositions);
274            scope.$watchGroup(['min', 'max'], updatePositions);
275
276            updatePositions();
277        },
278    };
279});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.