mirror of
https://github.com/Hutchy68/pivot.git
synced 2024-11-24 11:29:04 +01:00
282 lines
9.6 KiB
JavaScript
282 lines
9.6 KiB
JavaScript
|
;(function ($, window, document, undefined) {
|
||
|
'use strict';
|
||
|
|
||
|
Foundation.libs.slider = {
|
||
|
name : 'slider',
|
||
|
|
||
|
version : '5.5.2',
|
||
|
|
||
|
settings : {
|
||
|
start : 0,
|
||
|
end : 100,
|
||
|
step : 1,
|
||
|
precision : null,
|
||
|
initial : null,
|
||
|
display_selector : '',
|
||
|
vertical : false,
|
||
|
trigger_input_change : false,
|
||
|
on_change : function () {}
|
||
|
},
|
||
|
|
||
|
cache : {},
|
||
|
|
||
|
init : function (scope, method, options) {
|
||
|
Foundation.inherit(this, 'throttle');
|
||
|
this.bindings(method, options);
|
||
|
this.reflow();
|
||
|
},
|
||
|
|
||
|
events : function () {
|
||
|
var self = this;
|
||
|
|
||
|
$(this.scope)
|
||
|
.off('.slider')
|
||
|
.on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider',
|
||
|
'[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) {
|
||
|
if (!self.cache.active) {
|
||
|
e.preventDefault();
|
||
|
self.set_active_slider($(e.target));
|
||
|
}
|
||
|
})
|
||
|
.on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) {
|
||
|
if (!!self.cache.active) {
|
||
|
e.preventDefault();
|
||
|
if ($.data(self.cache.active[0], 'settings').vertical) {
|
||
|
var scroll_offset = 0;
|
||
|
if (!e.pageY) {
|
||
|
scroll_offset = window.scrollY;
|
||
|
}
|
||
|
self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
|
||
|
} else {
|
||
|
self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
.on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) {
|
||
|
self.remove_active_slider();
|
||
|
})
|
||
|
.on('change.fndtn.slider', function (e) {
|
||
|
self.settings.on_change();
|
||
|
});
|
||
|
|
||
|
self.S(window)
|
||
|
.on('resize.fndtn.slider', self.throttle(function (e) {
|
||
|
self.reflow();
|
||
|
}, 300));
|
||
|
|
||
|
// update slider value as users change input value
|
||
|
this.S('[' + this.attr_name() + ']').each(function () {
|
||
|
var slider = $(this),
|
||
|
handle = slider.children('.range-slider-handle')[0],
|
||
|
settings = self.initialize_settings(handle);
|
||
|
|
||
|
if (settings.display_selector != '') {
|
||
|
$(settings.display_selector).each(function(){
|
||
|
if (this.hasOwnProperty('value')) {
|
||
|
$(this).change(function(){
|
||
|
// is there a better way to do this?
|
||
|
slider.foundation("slider", "set_value", $(this).val());
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
get_cursor_position : function (e, xy) {
|
||
|
var pageXY = 'page' + xy.toUpperCase(),
|
||
|
clientXY = 'client' + xy.toUpperCase(),
|
||
|
position;
|
||
|
|
||
|
if (typeof e[pageXY] !== 'undefined') {
|
||
|
position = e[pageXY];
|
||
|
} else if (typeof e.originalEvent[clientXY] !== 'undefined') {
|
||
|
position = e.originalEvent[clientXY];
|
||
|
} else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') {
|
||
|
position = e.originalEvent.touches[0][clientXY];
|
||
|
} else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') {
|
||
|
position = e.currentPoint[xy];
|
||
|
}
|
||
|
|
||
|
return position;
|
||
|
},
|
||
|
|
||
|
set_active_slider : function ($handle) {
|
||
|
this.cache.active = $handle;
|
||
|
},
|
||
|
|
||
|
remove_active_slider : function () {
|
||
|
this.cache.active = null;
|
||
|
},
|
||
|
|
||
|
calculate_position : function ($handle, cursor_x) {
|
||
|
var self = this,
|
||
|
settings = $.data($handle[0], 'settings'),
|
||
|
handle_l = $.data($handle[0], 'handle_l'),
|
||
|
handle_o = $.data($handle[0], 'handle_o'),
|
||
|
bar_l = $.data($handle[0], 'bar_l'),
|
||
|
bar_o = $.data($handle[0], 'bar_o');
|
||
|
|
||
|
requestAnimationFrame(function () {
|
||
|
var pct;
|
||
|
|
||
|
if (Foundation.rtl && !settings.vertical) {
|
||
|
pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1);
|
||
|
} else {
|
||
|
pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1);
|
||
|
}
|
||
|
|
||
|
pct = settings.vertical ? 1 - pct : pct;
|
||
|
|
||
|
var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision);
|
||
|
|
||
|
self.set_ui($handle, norm);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
set_ui : function ($handle, value) {
|
||
|
var settings = $.data($handle[0], 'settings'),
|
||
|
handle_l = $.data($handle[0], 'handle_l'),
|
||
|
bar_l = $.data($handle[0], 'bar_l'),
|
||
|
norm_pct = this.normalized_percentage(value, settings.start, settings.end),
|
||
|
handle_offset = norm_pct * (bar_l - handle_l) - 1,
|
||
|
progress_bar_length = norm_pct * 100,
|
||
|
$handle_parent = $handle.parent(),
|
||
|
$hidden_inputs = $handle.parent().children('input[type=hidden]');
|
||
|
|
||
|
if (Foundation.rtl && !settings.vertical) {
|
||
|
handle_offset = -handle_offset;
|
||
|
}
|
||
|
|
||
|
handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset;
|
||
|
this.set_translate($handle, handle_offset, settings.vertical);
|
||
|
|
||
|
if (settings.vertical) {
|
||
|
$handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%');
|
||
|
} else {
|
||
|
$handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%');
|
||
|
}
|
||
|
|
||
|
$handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider');
|
||
|
|
||
|
$hidden_inputs.val(value);
|
||
|
if (settings.trigger_input_change) {
|
||
|
$hidden_inputs.trigger('change.fndtn.slider');
|
||
|
}
|
||
|
|
||
|
if (!$handle[0].hasAttribute('aria-valuemin')) {
|
||
|
$handle.attr({
|
||
|
'aria-valuemin' : settings.start,
|
||
|
'aria-valuemax' : settings.end
|
||
|
});
|
||
|
}
|
||
|
$handle.attr('aria-valuenow', value);
|
||
|
|
||
|
if (settings.display_selector != '') {
|
||
|
$(settings.display_selector).each(function () {
|
||
|
if (this.hasAttribute('value')) {
|
||
|
$(this).val(value);
|
||
|
} else {
|
||
|
$(this).text(value);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
normalized_percentage : function (val, start, end) {
|
||
|
return Math.min(1, (val - start) / (end - start));
|
||
|
},
|
||
|
|
||
|
normalized_value : function (val, start, end, step, precision) {
|
||
|
var range = end - start,
|
||
|
point = val * range,
|
||
|
mod = (point - (point % step)) / step,
|
||
|
rem = point % step,
|
||
|
round = ( rem >= step * 0.5 ? step : 0);
|
||
|
return ((mod * step + round) + start).toFixed(precision);
|
||
|
},
|
||
|
|
||
|
set_translate : function (ele, offset, vertical) {
|
||
|
if (vertical) {
|
||
|
$(ele)
|
||
|
.css('-webkit-transform', 'translateY(' + offset + 'px)')
|
||
|
.css('-moz-transform', 'translateY(' + offset + 'px)')
|
||
|
.css('-ms-transform', 'translateY(' + offset + 'px)')
|
||
|
.css('-o-transform', 'translateY(' + offset + 'px)')
|
||
|
.css('transform', 'translateY(' + offset + 'px)');
|
||
|
} else {
|
||
|
$(ele)
|
||
|
.css('-webkit-transform', 'translateX(' + offset + 'px)')
|
||
|
.css('-moz-transform', 'translateX(' + offset + 'px)')
|
||
|
.css('-ms-transform', 'translateX(' + offset + 'px)')
|
||
|
.css('-o-transform', 'translateX(' + offset + 'px)')
|
||
|
.css('transform', 'translateX(' + offset + 'px)');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
limit_to : function (val, min, max) {
|
||
|
return Math.min(Math.max(val, min), max);
|
||
|
},
|
||
|
|
||
|
initialize_settings : function (handle) {
|
||
|
var settings = $.extend({}, this.settings, this.data_options($(handle).parent())),
|
||
|
decimal_places_match_result;
|
||
|
|
||
|
if (settings.precision === null) {
|
||
|
decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/);
|
||
|
settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0;
|
||
|
}
|
||
|
|
||
|
if (settings.vertical) {
|
||
|
$.data(handle, 'bar_o', $(handle).parent().offset().top);
|
||
|
$.data(handle, 'bar_l', $(handle).parent().outerHeight());
|
||
|
$.data(handle, 'handle_o', $(handle).offset().top);
|
||
|
$.data(handle, 'handle_l', $(handle).outerHeight());
|
||
|
} else {
|
||
|
$.data(handle, 'bar_o', $(handle).parent().offset().left);
|
||
|
$.data(handle, 'bar_l', $(handle).parent().outerWidth());
|
||
|
$.data(handle, 'handle_o', $(handle).offset().left);
|
||
|
$.data(handle, 'handle_l', $(handle).outerWidth());
|
||
|
}
|
||
|
|
||
|
$.data(handle, 'bar', $(handle).parent());
|
||
|
return $.data(handle, 'settings', settings);
|
||
|
},
|
||
|
|
||
|
set_initial_position : function ($ele) {
|
||
|
var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'),
|
||
|
initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start),
|
||
|
$handle = $ele.children('.range-slider-handle');
|
||
|
this.set_ui($handle, initial);
|
||
|
},
|
||
|
|
||
|
set_value : function (value) {
|
||
|
var self = this;
|
||
|
$('[' + self.attr_name() + ']', this.scope).each(function () {
|
||
|
$(this).attr(self.attr_name(), value);
|
||
|
});
|
||
|
if (!!$(this.scope).attr(self.attr_name())) {
|
||
|
$(this.scope).attr(self.attr_name(), value);
|
||
|
}
|
||
|
self.reflow();
|
||
|
},
|
||
|
|
||
|
reflow : function () {
|
||
|
var self = this;
|
||
|
self.S('[' + this.attr_name() + ']').each(function () {
|
||
|
var handle = $(this).children('.range-slider-handle')[0],
|
||
|
val = $(this).attr(self.attr_name());
|
||
|
self.initialize_settings(handle);
|
||
|
|
||
|
if (val) {
|
||
|
self.set_ui($(handle), parseFloat(val));
|
||
|
} else {
|
||
|
self.set_initial_position($(this));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}(jQuery, window, window.document));
|