infojune/resources/sass/materialize/js/range.js

264 lines
7.2 KiB
JavaScript

(function($, anim) {
'use strict';
let _defaults = {};
/**
* @class
*
*/
class Range extends Component {
/**
* Construct Range instance
* @constructor
* @param {Element} el
* @param {Object} options
*/
constructor(el, options) {
super(Range, el, options);
this.el.M_Range = this;
/**
* Options for the range
* @member Range#options
*/
this.options = $.extend({}, Range.defaults, options);
this._mousedown = false;
// Setup
this._setupThumb();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
static init(els, options) {
return super.init(this, els, options);
}
/**
* Get Instance
*/
static getInstance(el) {
let domElem = !!el.jquery ? el[0] : el;
return domElem.M_Range;
}
/**
* Teardown component
*/
destroy() {
this._removeEventHandlers();
this._removeThumb();
this.el.M_Range = undefined;
}
/**
* Setup Event Handlers
*/
_setupEventHandlers() {
this._handleRangeChangeBound = this._handleRangeChange.bind(this);
this._handleRangeMousedownTouchstartBound = this._handleRangeMousedownTouchstart.bind(this);
this._handleRangeInputMousemoveTouchmoveBound = this._handleRangeInputMousemoveTouchmove.bind(
this
);
this._handleRangeMouseupTouchendBound = this._handleRangeMouseupTouchend.bind(this);
this._handleRangeBlurMouseoutTouchleaveBound = this._handleRangeBlurMouseoutTouchleave.bind(
this
);
this.el.addEventListener('change', this._handleRangeChangeBound);
this.el.addEventListener('mousedown', this._handleRangeMousedownTouchstartBound);
this.el.addEventListener('touchstart', this._handleRangeMousedownTouchstartBound);
this.el.addEventListener('input', this._handleRangeInputMousemoveTouchmoveBound);
this.el.addEventListener('mousemove', this._handleRangeInputMousemoveTouchmoveBound);
this.el.addEventListener('touchmove', this._handleRangeInputMousemoveTouchmoveBound);
this.el.addEventListener('mouseup', this._handleRangeMouseupTouchendBound);
this.el.addEventListener('touchend', this._handleRangeMouseupTouchendBound);
this.el.addEventListener('blur', this._handleRangeBlurMouseoutTouchleaveBound);
this.el.addEventListener('mouseout', this._handleRangeBlurMouseoutTouchleaveBound);
this.el.addEventListener('touchleave', this._handleRangeBlurMouseoutTouchleaveBound);
}
/**
* Remove Event Handlers
*/
_removeEventHandlers() {
this.el.removeEventListener('change', this._handleRangeChangeBound);
this.el.removeEventListener('mousedown', this._handleRangeMousedownTouchstartBound);
this.el.removeEventListener('touchstart', this._handleRangeMousedownTouchstartBound);
this.el.removeEventListener('input', this._handleRangeInputMousemoveTouchmoveBound);
this.el.removeEventListener('mousemove', this._handleRangeInputMousemoveTouchmoveBound);
this.el.removeEventListener('touchmove', this._handleRangeInputMousemoveTouchmoveBound);
this.el.removeEventListener('mouseup', this._handleRangeMouseupTouchendBound);
this.el.removeEventListener('touchend', this._handleRangeMouseupTouchendBound);
this.el.removeEventListener('blur', this._handleRangeBlurMouseoutTouchleaveBound);
this.el.removeEventListener('mouseout', this._handleRangeBlurMouseoutTouchleaveBound);
this.el.removeEventListener('touchleave', this._handleRangeBlurMouseoutTouchleaveBound);
}
/**
* Handle Range Change
* @param {Event} e
*/
_handleRangeChange() {
$(this.value).html(this.$el.val());
if (!$(this.thumb).hasClass('active')) {
this._showRangeBubble();
}
let offsetLeft = this._calcRangeOffset();
$(this.thumb)
.addClass('active')
.css('left', offsetLeft + 'px');
}
/**
* Handle Range Mousedown and Touchstart
* @param {Event} e
*/
_handleRangeMousedownTouchstart(e) {
// Set indicator value
$(this.value).html(this.$el.val());
this._mousedown = true;
this.$el.addClass('active');
if (!$(this.thumb).hasClass('active')) {
this._showRangeBubble();
}
if (e.type !== 'input') {
let offsetLeft = this._calcRangeOffset();
$(this.thumb)
.addClass('active')
.css('left', offsetLeft + 'px');
}
}
/**
* Handle Range Input, Mousemove and Touchmove
*/
_handleRangeInputMousemoveTouchmove() {
if (this._mousedown) {
if (!$(this.thumb).hasClass('active')) {
this._showRangeBubble();
}
let offsetLeft = this._calcRangeOffset();
$(this.thumb)
.addClass('active')
.css('left', offsetLeft + 'px');
$(this.value).html(this.$el.val());
}
}
/**
* Handle Range Mouseup and Touchend
*/
_handleRangeMouseupTouchend() {
this._mousedown = false;
this.$el.removeClass('active');
}
/**
* Handle Range Blur, Mouseout and Touchleave
*/
_handleRangeBlurMouseoutTouchleave() {
if (!this._mousedown) {
let paddingLeft = parseInt(this.$el.css('padding-left'));
let marginLeft = 7 + paddingLeft + 'px';
if ($(this.thumb).hasClass('active')) {
anim.remove(this.thumb);
anim({
targets: this.thumb,
height: 0,
width: 0,
top: 10,
easing: 'easeOutQuad',
marginLeft: marginLeft,
duration: 100
});
}
$(this.thumb).removeClass('active');
}
}
/**
* Setup dropdown
*/
_setupThumb() {
this.thumb = document.createElement('span');
this.value = document.createElement('span');
$(this.thumb).addClass('thumb');
$(this.value).addClass('value');
$(this.thumb).append(this.value);
this.$el.after(this.thumb);
}
/**
* Remove dropdown
*/
_removeThumb() {
$(this.thumb).remove();
}
/**
* morph thumb into bubble
*/
_showRangeBubble() {
let paddingLeft = parseInt(
$(this.thumb)
.parent()
.css('padding-left')
);
let marginLeft = -7 + paddingLeft + 'px'; // TODO: fix magic number?
anim.remove(this.thumb);
anim({
targets: this.thumb,
height: 30,
width: 30,
top: -30,
marginLeft: marginLeft,
duration: 300,
easing: 'easeOutQuint'
});
}
/**
* Calculate the offset of the thumb
* @return {Number} offset in pixels
*/
_calcRangeOffset() {
let width = this.$el.width() - 15;
let max = parseFloat(this.$el.attr('max')) || 100; // Range default max
let min = parseFloat(this.$el.attr('min')) || 0; // Range default min
let percent = (parseFloat(this.$el.val()) - min) / (max - min);
return percent * width;
}
}
M.Range = Range;
if (M.jQueryLoaded) {
M.initializeJqueryWrapper(Range, 'range', 'M_Range');
}
Range.init($('input[type=range]'));
})(cash, M.anime);