comparison js/foundation/foundation.slider.js @ 0:7abe02bf29ec

initial commit
author Alex Krolick <whokilledtheelectricmonk@gmail.com>
date Sat, 07 Nov 2015 18:04:42 -0800
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7abe02bf29ec
1 ;(function ($, window, document, undefined) {
2 'use strict';
3
4 Foundation.libs.slider = {
5 name : 'slider',
6
7 version : '5.5.3',
8
9 settings : {
10 start : 0,
11 end : 100,
12 step : 1,
13 precision : 2,
14 initial : null,
15 display_selector : '',
16 vertical : false,
17 trigger_input_change : false,
18 on_change : function () {}
19 },
20
21 cache : {},
22
23 init : function (scope, method, options) {
24 Foundation.inherit(this, 'throttle');
25 this.bindings(method, options);
26 this.reflow();
27 },
28
29 events : function () {
30 var self = this;
31 $(this.scope)
32 .off('.slider')
33 .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider',
34 '[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) {
35 if (!self.cache.active) {
36 e.preventDefault();
37 self.set_active_slider($(e.target));
38 }
39 })
40 .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) {
41 if (!!self.cache.active) {
42 e.preventDefault();
43 if ($.data(self.cache.active[0], 'settings').vertical) {
44 var scroll_offset = 0;
45 if (!e.pageY) {
46 scroll_offset = window.scrollY;
47 }
48 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
49 } else {
50 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
51 }
52 }
53 })
54 .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) {
55 if(!self.cache.active) {
56 // if the user has just clicked into the slider without starting to drag the handle
57 var slider = $(e.target).attr('role') === 'slider' ? $(e.target) : $(e.target).closest('.range-slider').find("[role='slider']");
58
59 if (slider.length && (!slider.parent().hasClass('disabled') && !slider.parent().attr('disabled'))) {
60 self.set_active_slider(slider);
61 if ($.data(self.cache.active[0], 'settings').vertical) {
62 var scroll_offset = 0;
63 if (!e.pageY) {
64 scroll_offset = window.scrollY;
65 }
66 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
67 } else {
68 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
69 }
70 }
71 }
72 self.remove_active_slider();
73 })
74 .on('change.fndtn.slider', function (e) {
75 self.settings.on_change();
76 });
77
78 self.S(window)
79 .on('resize.fndtn.slider', self.throttle(function (e) {
80 self.reflow();
81 }, 300));
82
83 // update slider value as users change input value
84 this.S('[' + this.attr_name() + ']').each(function () {
85 var slider = $(this),
86 handle = slider.children('.range-slider-handle')[0],
87 settings = self.initialize_settings(handle);
88
89 if (settings.display_selector != '') {
90 $(settings.display_selector).each(function(){
91 if ($(this).attr('value')) {
92 $(this).off('change').on('change', function () {
93 slider.foundation("slider", "set_value", $(this).val());
94 });
95 }
96 });
97 }
98 });
99 },
100
101 get_cursor_position : function (e, xy) {
102 var pageXY = 'page' + xy.toUpperCase(),
103 clientXY = 'client' + xy.toUpperCase(),
104 position;
105
106 if (typeof e[pageXY] !== 'undefined') {
107 position = e[pageXY];
108 } else if (typeof e.originalEvent[clientXY] !== 'undefined') {
109 position = e.originalEvent[clientXY];
110 } else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') {
111 position = e.originalEvent.touches[0][clientXY];
112 } else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') {
113 position = e.currentPoint[xy];
114 }
115
116 return position;
117 },
118
119 set_active_slider : function ($handle) {
120 this.cache.active = $handle;
121 },
122
123 remove_active_slider : function () {
124 this.cache.active = null;
125 },
126
127 calculate_position : function ($handle, cursor_x) {
128 var self = this,
129 settings = $.data($handle[0], 'settings'),
130 handle_l = $.data($handle[0], 'handle_l'),
131 handle_o = $.data($handle[0], 'handle_o'),
132 bar_l = $.data($handle[0], 'bar_l'),
133 bar_o = $.data($handle[0], 'bar_o');
134
135 requestAnimationFrame(function () {
136 var pct;
137
138 if (Foundation.rtl && !settings.vertical) {
139 pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1);
140 } else {
141 pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1);
142 }
143
144 pct = settings.vertical ? 1 - pct : pct;
145
146 var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision);
147
148 self.set_ui($handle, norm);
149 });
150 },
151
152 set_ui : function ($handle, value) {
153 var settings = $.data($handle[0], 'settings'),
154 handle_l = $.data($handle[0], 'handle_l'),
155 bar_l = $.data($handle[0], 'bar_l'),
156 norm_pct = this.normalized_percentage(value, settings.start, settings.end),
157 handle_offset = norm_pct * (bar_l - handle_l) - 1,
158 progress_bar_length = norm_pct * 100,
159 $handle_parent = $handle.parent(),
160 $hidden_inputs = $handle.parent().children('input[type=hidden]');
161
162 if (Foundation.rtl && !settings.vertical) {
163 handle_offset = -handle_offset;
164 }
165
166 handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset;
167 this.set_translate($handle, handle_offset, settings.vertical);
168
169 if (settings.vertical) {
170 $handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%');
171 } else {
172 $handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%');
173 }
174
175 $handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider');
176
177 $hidden_inputs.val(value);
178 if (settings.trigger_input_change) {
179 $hidden_inputs.trigger('change.fndtn.slider');
180 }
181
182 if (!$handle[0].hasAttribute('aria-valuemin')) {
183 $handle.attr({
184 'aria-valuemin' : settings.start,
185 'aria-valuemax' : settings.end
186 });
187 }
188 $handle.attr('aria-valuenow', value);
189
190 if (settings.display_selector != '') {
191 $(settings.display_selector).each(function () {
192 if (this.hasAttribute('value')) {
193 $(this).val(value);
194 } else {
195 $(this).text(value);
196 }
197 });
198 }
199
200 },
201
202 normalized_percentage : function (val, start, end) {
203 return Math.min(1, (val - start) / (end - start));
204 },
205
206 normalized_value : function (val, start, end, step, precision) {
207 var range = end - start,
208 point = val * range,
209 mod = (point - (point % step)) / step,
210 rem = point % step,
211 round = ( rem >= step * 0.5 ? step : 0);
212 return ((mod * step + round) + start).toFixed(precision);
213 },
214
215 set_translate : function (ele, offset, vertical) {
216 if (vertical) {
217 $(ele)
218 .css('-webkit-transform', 'translateY(' + offset + 'px)')
219 .css('-moz-transform', 'translateY(' + offset + 'px)')
220 .css('-ms-transform', 'translateY(' + offset + 'px)')
221 .css('-o-transform', 'translateY(' + offset + 'px)')
222 .css('transform', 'translateY(' + offset + 'px)');
223 } else {
224 $(ele)
225 .css('-webkit-transform', 'translateX(' + offset + 'px)')
226 .css('-moz-transform', 'translateX(' + offset + 'px)')
227 .css('-ms-transform', 'translateX(' + offset + 'px)')
228 .css('-o-transform', 'translateX(' + offset + 'px)')
229 .css('transform', 'translateX(' + offset + 'px)');
230 }
231 },
232
233 limit_to : function (val, min, max) {
234 return Math.min(Math.max(val, min), max);
235 },
236
237 initialize_settings : function (handle) {
238 var settings = $.extend({}, this.settings, this.data_options($(handle).parent())),
239 decimal_places_match_result;
240
241 if (settings.precision === null) {
242 decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/);
243 settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0;
244 }
245
246 if (settings.vertical) {
247 $.data(handle, 'bar_o', $(handle).parent().offset().top);
248 $.data(handle, 'bar_l', $(handle).parent().outerHeight());
249 $.data(handle, 'handle_o', $(handle).offset().top);
250 $.data(handle, 'handle_l', $(handle).outerHeight());
251 } else {
252 $.data(handle, 'bar_o', $(handle).parent().offset().left);
253 $.data(handle, 'bar_l', $(handle).parent().outerWidth());
254 $.data(handle, 'handle_o', $(handle).offset().left);
255 $.data(handle, 'handle_l', $(handle).outerWidth());
256 }
257
258 $.data(handle, 'bar', $(handle).parent());
259 return $.data(handle, 'settings', settings);
260 },
261
262 set_initial_position : function ($ele) {
263 var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'),
264 initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start),
265 $handle = $ele.children('.range-slider-handle');
266 this.set_ui($handle, initial);
267 },
268
269 set_value : function (value) {
270 var self = this;
271 $('[' + self.attr_name() + ']', this.scope).each(function () {
272 $(this).attr(self.attr_name(), value);
273 });
274 if (!!$(this.scope).attr(self.attr_name())) {
275 $(this.scope).attr(self.attr_name(), value);
276 }
277 self.reflow();
278 },
279
280 reflow : function () {
281 var self = this;
282 self.S('[' + this.attr_name() + ']').each(function () {
283 var handle = $(this).children('.range-slider-handle')[0],
284 val = $(this).attr(self.attr_name());
285 self.initialize_settings(handle);
286
287 if (val) {
288 self.set_ui($(handle), parseFloat(val));
289 } else {
290 self.set_initial_position($(this));
291 }
292 });
293 }
294 };
295
296 }(jQuery, window, window.document));