UNPKG

metro4

Version:

The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style

436 lines (362 loc) 14.9 kB
/* global Metro */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var DoubleSliderDefaultConfig = { doublesliderDeferred: 0, roundValue: true, min: 0, max: 100, accuracy: 0, showMinMax: false, minMaxPosition: Metro.position.TOP, valueMin: null, valueMax: null, hint: false, hintAlways: false, hintPositionMin: Metro.position.TOP, hintPositionMax: Metro.position.TOP, hintMaskMin: "$1", hintMaskMax: "$1", target: null, size: 0, clsSlider: "", clsBackside: "", clsComplete: "", clsMarker: "", clsMarkerMin: "", clsMarkerMax: "", clsHint: "", clsHintMin: "", clsHintMax: "", clsMinMax: "", clsMin: "", clsMax: "", onStart: Metro.noop, onStop: Metro.noop, onMove: Metro.noop, onChange: Metro.noop, onChangeValue: Metro.noop, onFocus: Metro.noop, onBlur: Metro.noop, onDoubleSliderCreate: Metro.noop }; Metro.doubleSliderSetup = function (options) { DoubleSliderDefaultConfig = $.extend({}, DoubleSliderDefaultConfig, options); }; if (typeof window["metroDoubleSliderSetup"] !== undefined) { Metro.doubleSliderSetup(window["metroDoubleSliderSetup"]); } Metro.Component('double-slider', { init: function( options, elem ) { this._super(elem, options, DoubleSliderDefaultConfig, { slider: null, valueMin: null, valueMax: null, keyInterval: false, id: Utils.elementId("slider") }); return this; }, _create: function(){ var element = this.element, o = this.options; this.valueMin = Utils.isValue(o.valueMin) ? +o.valueMin : +o.min; this.valueMax = Utils.isValue(o.valueMax) ? +o.valueMax : +o.max; this._createSlider(); this._createEvents(); this.val(this.valueMin, this.valueMax); this._fireEvent("double-slider-create", { element: element }) }, _createSlider: function(){ var element = this.element, o = this.options; var slider_wrapper = $("<div>").addClass("slider-wrapper"); var slider = $("<div>").addClass("slider").addClass(o.clsSlider).addClass(this.elem.className); var backside = $("<div>").addClass("backside").addClass(o.clsBackside); var complete = $("<div>").addClass("complete").addClass(o.clsComplete); var markerMin = $("<button>").attr("type", "button").addClass("marker marker-min").addClass(o.clsMarker).addClass(o.clsMarkerMin); var markerMax = $("<button>").attr("type", "button").addClass("marker marker-max").addClass(o.clsMarker).addClass(o.clsMarkerMax); var hintMin = $("<div>").addClass("hint hint-min").addClass(o.hintPositionMin + "-side").addClass(o.clsHint).addClass(o.clsHintMin); var hintMax = $("<div>").addClass("hint hint-max").addClass(o.hintPositionMax + "-side").addClass(o.clsHint).addClass(o.clsHintMax); var i; if (o.size > 0) { slider.outerWidth(o.size); } slider.insertBefore(element); element.appendTo(slider); slider_wrapper.insertBefore(slider); slider.appendTo(slider_wrapper); backside.appendTo(slider); complete.appendTo(slider); markerMin.appendTo(slider); markerMax.appendTo(slider); hintMin.appendTo(markerMin); hintMax.appendTo(markerMax); if (o.hintAlways === true) { $([hintMin, hintMax]).css({ display: "block" }).addClass("permanent-hint"); } if (o.showMinMax === true) { var min_max_wrapper = $("<div>").addClass("slider-min-max").addClass(o.clsMinMax); $("<span>").addClass("slider-text-min").addClass(o.clsMin).html(o.min).appendTo(min_max_wrapper); $("<span>").addClass("slider-text-max").addClass(o.clsMax).html(o.max).appendTo(min_max_wrapper); if (o.minMaxPosition === Metro.position.TOP) { min_max_wrapper.insertBefore(slider); } else { min_max_wrapper.insertAfter(slider); } } element[0].className = ''; if (o.copyInlineStyles === true) { for (i = 0; i < element[0].style.length; i++) { slider.css(element[0].style[i], element.css(element[0].style[i])); } } if (element.is(":disabled")) { this.disable(); } else { this.enable(); } this.slider = slider; }, _createEvents: function(){ var that = this, slider = this.slider, o = this.options; var marker = slider.find(".marker"); marker.on(Metro.events.startAll, function(){ var _marker = $(this); var hint = _marker.find(".hint"); if (o.hint === true && o.hintAlways !== true) { hint.fadeIn(300); } $(document).on(Metro.events.moveAll, function(e){ that._move(e); that._fireEvent("move", { min: that.valueMin, max: that.valueMax }); }, {ns: that.id}); $(document).on(Metro.events.stopAll, function(){ $(document).off(Metro.events.moveAll, {ns: that.id}); $(document).off(Metro.events.stopAll, {ns: that.id}); if (o.hintAlways !== true) { hint.fadeOut(300); } that._fireEvent("stop", { min: that.valueMin, max: that.valueMax }); }, {ns: that.id}); that._fireEvent("start", { min: that.valueMin, max: that.valueMax }); }); marker.on(Metro.events.focus, function(){ that._fireEvent("focus", { min: that.valueMin, max: that.valueMax }); }); marker.on(Metro.events.blur, function(){ that._fireEvent("blur", { min: that.valueMin, max: that.valueMax }); }); $(window).on(Metro.events.resize,function(){ that.val(that.valueMin, that.valueMax); }, {ns: that.id}); }, _convert: function(v, how){ var slider = this.slider, o = this.options; var length = slider.outerWidth() - slider.find(".marker").outerWidth(); switch (how) { case "pix2prc": return ( v * 100 / length ); case "pix2val": return ( this._convert(v, 'pix2prc') * ((o.max - o.min) / 100) + o.min ); case "val2prc": return ( (v - o.min)/( (o.max - o.min) / 100 ) ); case "prc2pix": return ( v / ( 100 / length )); case "val2pix": return ( this._convert(this._convert(v, 'val2prc'), 'prc2pix') ); } return 0; }, _correct: function(value){ var res = value; var accuracy = this.options.accuracy; var min = this.options.min, max = this.options.max; var _dec = function(v){ return v % 1 === 0 ? 0 : v.toString().split(".")[1].length; }; if (accuracy === 0 || isNaN(accuracy)) { return res; } res = Math.round(value/accuracy)*accuracy; if (res < min) { res = min; } if (res > max) { res = max; } return res.toFixed(_dec(accuracy)); }, _move: function(e){ var target = $(e.target).closest(".marker"); var isMin = target.hasClass("marker-min"); var slider = this.slider; var offset = slider.offset(), marker_size = slider.find(".marker").outerWidth(), markerMin = slider.find(".marker-min"), markerMax = slider.find(".marker-max"), length = slider.outerWidth(), cPix, cStart, cStop; cPix = Utils.pageXY(e).x - offset.left - marker_size / 2; if (isMin) { cStart = 0; cStop = parseInt(markerMax.css("left")) - marker_size; } else { cStart = parseInt(markerMin.css("left")) + marker_size; cStop = length - marker_size; } if (cPix < cStart || cPix > cStop) { return ; } this[isMin ? "valueMin" : "valueMax"] = this._correct(this._convert(cPix, 'pix2val')); this._redraw(); }, _hint: function(){ var that = this, o = this.options, slider = this.slider, hint = slider.find(".hint"); hint.each(function(){ var _hint = $(this); var isMin = _hint.hasClass("hint-min"); var _mask = isMin ? o.hintMaskMin : o.hintMaskMax; var value = +(isMin ? that.valueMin : that.valueMax) || 0; _hint.text(_mask.replace("$1", value.toFixed(Utils.decCount(o.accuracy)))) }); }, _value: function(){ var element = this.element, o = this.options; var v1 = +this.valueMin || 0, v2 = +this.valueMax || 0; var value; if (o.roundValue) { v1 = v1.toFixed(Utils.decCount(o.accuracy)); v2 = v2.toFixed(Utils.decCount(o.accuracy)); } value = [v1, v2].join(", "); if (element[0].tagName === "INPUT") { element.val(value); } if (o.target !== null) { var target = $(o.target); if (target.length !== 0) { $.each(target, function(){ var t = $(this); if (this.tagName === "INPUT") { t.val(value); } else { t.text(value); } t.trigger("change"); }); } } this._fireEvent("change-value", { val: value }); this._fireEvent("change", { val: value }); }, _marker: function(){ var slider = this.slider; var markerMin = slider.find(".marker-min"); var markerMax = slider.find(".marker-max"); var complete = slider.find(".complete"); var marker_size = parseInt(Utils.getStyleOne(markerMin, "width")); var slider_visible = Utils.isVisible(slider); if (slider_visible) { $([markerMin, markerMax]).css({ 'margin-top': 0, 'margin-left': 0 }); } if (slider_visible) { markerMin.css('left', this._convert(this.valueMin, 'val2pix')); markerMax.css('left', this._convert(this.valueMax, 'val2pix')); } else { markerMin.css({ 'left': (this._convert(this.valueMin, 'val2prc')) + "%", 'margin-top': this._convert(this.valueMin, 'val2prc') === 0 ? 0 : -1 * marker_size / 2 }); markerMax.css({ 'left': (this._convert(this.valueMax, 'val2prc')) + "%", 'margin-top': this._convert(this.valueMax, 'val2prc') === 0 ? 0 : -1 * marker_size / 2 }); } complete.css({ "left": this._convert(this.valueMin, 'val2pix'), "width": this._convert(this.valueMax, 'val2pix') - this._convert(this.valueMin, 'val2pix') }); }, _redraw: function(){ this._marker(); this._value(); this._hint(); }, val: function(vMin, vMax){ var o = this.options; if (!Utils.isValue(vMin) && !Utils.isValue(vMax)) { return [this.valueMin, this.valueMax]; } if (vMin < o.min) vMin = o.min; if (vMax < o.min) vMax = o.min; if (vMin > o.max) vMin = o.max; if (vMax > o.max) vMax = o.max; this.valueMin = this._correct(vMin); this.valueMax = this._correct(vMax); this._redraw(); }, changeValue: function(){ var element = this.element; var valMin = +element.attr("data-value-min"); var valMax = +element.attr("data-value-max"); this.val(valMin, valMax); }, disable: function(){ var element = this.element; element.data("disabled", true); element.parent().addClass("disabled"); }, enable: function(){ var element = this.element; element.data("disabled", false); element.parent().removeClass("disabled"); }, toggleState: function(){ if (this.elem.disabled) { this.disable(); } else { this.enable(); } }, changeAttribute: function(attributeName){ switch (attributeName) { case "data-value-min": this.changeValue(); break; case "data-value-max": this.changeValue(); break; case 'disabled': this.toggleState(); break; } }, destroy: function(){ var element = this.element, slider = this.slider; var marker = slider.find(".marker"); marker.off(Metro.events.startAll); marker.off(Metro.events.focus); marker.off(Metro.events.blur); marker.off(Metro.events.keydown); marker.off(Metro.events.keyup); slider.off(Metro.events.click); $(window).off(Metro.events.resize, {ns: this.id}); return element; } }); }(Metro, m4q));