diff options
Diffstat (limited to 'library/jRange/jquery.range.js')
-rw-r--r-- | library/jRange/jquery.range.js | 240 |
1 files changed, 137 insertions, 103 deletions
diff --git a/library/jRange/jquery.range.js b/library/jRange/jquery.range.js index b3208387d..860b74511 100644 --- a/library/jRange/jquery.range.js +++ b/library/jRange/jquery.range.js @@ -17,27 +17,26 @@ * jQuery (http://jquery.com) * **/ - ; - (function($, window, document, undefined) { +; +(function($, window, document, undefined) { 'use strict'; - var jRange = function(){ + var jRange = function() { return this.init.apply(this, arguments); }; jRange.prototype = { - defaults : { - onstatechange : function(){}, - isRange : false, - showLabels : true, - showScale : true, - step : 1, + defaults: { + onstatechange: function() {}, + isRange: false, + showLabels: true, + showScale: true, + step: 1, format: '%s', - theme : 'theme-green', - width : 300, - minRange: 0, - maxRange: 'auto' + theme: 'theme-green', + width: 300, + disable: false }, - template : '<div class="slider-container">\ + template: '<div class="slider-container">\ <div class="back-bar">\ <div class="selected-bar"></div>\ <div class="pointer low"></div><div class="pointer-label">123456</div>\ @@ -46,214 +45,247 @@ </div>\ <div class="scale"></div>\ </div>', - init : function(node, options){ + init: function(node, options) { this.options = $.extend({}, this.defaults, options); this.inputNode = $(node); - this.options.value = this.inputNode.val() || (this.options.isRange ? this.options.from+','+this.options.from : this.options.from); + this.options.value = this.inputNode.val() || (this.options.isRange ? this.options.from + ',' + this.options.from : this.options.from); this.domNode = $(this.template); this.domNode.addClass(this.options.theme); this.inputNode.after(this.domNode); this.domNode.on('change', this.onChange); - this.pointers = $('.pointer', this.domNode); - this.lowPointer = this.pointers.first(); - this.highPointer = this.pointers.last(); - this.labels = $('.pointer-label', this.domNode); - this.lowLabel = this.labels.first(); - this.highLabel = this.labels.last(); - this.scale = $('.scale', this.domNode); - this.bar = $('.selected-bar', this.domNode); - this.clickableBar = this.domNode.find('.clickable-dummy'); - this.interval = this.options.to - this.options.from; + this.pointers = $('.pointer', this.domNode); + this.lowPointer = this.pointers.first(); + this.highPointer = this.pointers.last(); + this.labels = $('.pointer-label', this.domNode); + this.lowLabel = this.labels.first(); + this.highLabel = this.labels.last(); + this.scale = $('.scale', this.domNode); + this.bar = $('.selected-bar', this.domNode); + this.clickableBar = this.domNode.find('.clickable-dummy'); + this.interval = this.options.to - this.options.from; this.render(); }, - render: function(){ + render: function() { // Check if inputNode is visible, and have some width, so that we can set slider width accordingly. - if( this.inputNode.width() === 0 && !this.options.width ){ + if (this.inputNode.width() === 0 && !this.options.width) { console.log('jRange : no width found, returning'); return; - }else{ - this.domNode.width( this.options.width || this.inputNode.width() ); + } else { + this.domNode.width(this.options.width || this.inputNode.width()); this.inputNode.hide(); } - if(this.isSingle()){ + if (this.isSingle()) { this.lowPointer.hide(); this.lowLabel.hide(); } - if(!this.options.showLabels){ + if (!this.options.showLabels) { this.labels.hide(); } this.attachEvents(); - if(this.options.showScale){ + if (this.options.showScale) { this.renderScale(); } this.setValue(this.options.value); }, - isSingle: function(){ - if(typeof(this.options.value) === 'number'){ + isSingle: function() { + if (typeof(this.options.value) === 'number') { return true; } return (this.options.value.indexOf(',') !== -1 || this.options.isRange) ? - false : true; + false : true; }, - attachEvents: function(){ + attachEvents: function() { this.clickableBar.click($.proxy(this.barClicked, this)); - this.pointers.mousedown($.proxy(this.onDragStart, this)); - this.pointers.bind('dragstart', function(event) { event.preventDefault(); }); + this.pointers.on('mousedown touchstart', $.proxy(this.onDragStart, this)); + this.pointers.bind('dragstart', function(event) { + event.preventDefault(); + }); }, - onDragStart: function(e){ - if(e.which !== 1){return;} - e.stopPropagation(); e.preventDefault(); + onDragStart: function(e) { + if ( this.options.disable || (e.type === 'mousedown' && e.which !== 1)) { + return; + } + e.stopPropagation(); + e.preventDefault(); var pointer = $(e.target); this.pointers.removeClass('last-active'); pointer.addClass('focused last-active'); - this[(pointer.hasClass('low')?'low':'high') + 'Label'].addClass('focused'); - $(document).on('mousemove.slider', $.proxy(this.onDrag, this, pointer)); - $(document).on('mouseup.slider', $.proxy(this.onDragEnd, this)); + this[(pointer.hasClass('low') ? 'low' : 'high') + 'Label'].addClass('focused'); + $(document).on('mousemove.slider touchmove.slider', $.proxy(this.onDrag, this, pointer)); + $(document).on('mouseup.slider touchend.slider touchcancel.slider', $.proxy(this.onDragEnd, this)); }, - onDrag: function(pointer, e){ - e.stopPropagation(); e.preventDefault(); + onDrag: function(pointer, e) { + e.stopPropagation(); + e.preventDefault(); + + if (e.originalEvent.touches && e.originalEvent.touches.length) { + e = e.originalEvent.touches[0]; + } else if (e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { + e = e.originalEvent.changedTouches[0]; + } + var position = e.clientX - this.domNode.offset().left; this.domNode.trigger('change', [this, pointer, position]); }, - onDragEnd: function(){ + onDragEnd: function(e) { this.pointers.removeClass('focused'); this.labels.removeClass('focused'); $(document).off('.slider'); - $(document).off('.slider'); }, - barClicked: function(e){ + barClicked: function(e) { + if(this.options.disable) return; var x = e.pageX - this.clickableBar.offset().left; - if(this.isSingle()) + if (this.isSingle()) this.setPosition(this.pointers.last(), x, true, true); - else{ + else { var pointer = Math.abs(parseInt(this.pointers.first().css('left'), 10) - x + this.pointers.first().width() / 2) < Math.abs(parseInt(this.pointers.last().css('left'), 10) - x + this.pointers.first().width() / 2) ? this.pointers.first() : this.pointers.last(); this.setPosition(pointer, x, true, true); } }, - onChange: function(e, self, pointer, position){ + onChange: function(e, self, pointer, position) { var min, max; - if(self.isSingle()){ + if (self.isSingle()) { min = 0; max = self.domNode.width(); - }else{ - min = pointer.hasClass('high')? self.lowPointer.position().left + self.lowPointer.width() / 2 : 0; + } else { + min = pointer.hasClass('high') ? self.lowPointer.position().left + self.lowPointer.width() / 2 : 0; max = pointer.hasClass('low') ? self.highPointer.position().left + self.highPointer.width() / 2 : self.domNode.width(); } var value = Math.min(Math.max(position, min), max); self.setPosition(pointer, value, true); }, - setPosition: function(pointer, position, isPx, animate){ + setPosition: function(pointer, position, isPx, animate) { var leftPos, lowPos = this.lowPointer.position().left, highPos = this.highPointer.position().left, circleWidth = this.highPointer.width() / 2; - if(!isPx){ + if (!isPx) { position = this.prcToPx(position); } - if(pointer[0] === this.highPointer[0]){ - highPos = Math.round(position - circleWidth); - }else{ - lowPos = Math.round(position - circleWidth); + if (pointer[0] === this.highPointer[0]) { + highPos = Math.round(position - circleWidth); + } else { + lowPos = Math.round(position - circleWidth); } - pointer[animate?'animate':'css']({'left': Math.round(position - circleWidth)}); - if(this.isSingle()){ + pointer[animate ? 'animate' : 'css']({ + 'left': Math.round(position - circleWidth) + }); + if (this.isSingle()) { leftPos = 0; - }else{ + } else { leftPos = lowPos + circleWidth; } - this.bar[animate?'animate':'css']({ - 'width' : Math.round(highPos + circleWidth - leftPos), - 'left' : leftPos - }); + this.bar[animate ? 'animate' : 'css']({ + 'width': Math.round(highPos + circleWidth - leftPos), + 'left': leftPos + }); this.showPointerValue(pointer, position, animate); + this.isReadonly(); }, // will be called from outside - setValue: function(value){ + setValue: function(value) { var values = value.toString().split(','); this.options.value = value; - var prc = this.valuesToPrc( values.length === 2 ? values : [0, values[0]] ); - if(this.isSingle()){ + var prc = this.valuesToPrc(values.length === 2 ? values : [0, values[0]]); + if (this.isSingle()) { this.setPosition(this.highPointer, prc[1]); - }else{ + } else { this.setPosition(this.lowPointer, prc[0]); this.setPosition(this.highPointer, prc[1]); } }, - renderScale: function(){ + renderScale: function() { var s = this.options.scale || [this.options.from, this.options.to]; var prc = Math.round((100 / (s.length - 1)) * 10) / 10; var str = ''; - for(var i = 0; i < s.length ; i++ ){ + for (var i = 0; i < s.length; i++) { str += '<span style="left: ' + i * prc + '%">' + (s[i] != '|' ? '<ins>' + s[i] + '</ins>' : '') + '</span>'; } this.scale.html(str); - $('ins', this.scale).each(function () { + $('ins', this.scale).each(function() { $(this).css({ marginLeft: -$(this).outerWidth() / 2 }); }); }, - getBarWidth: function(){ + getBarWidth: function() { var values = this.options.value.split(','); - if(values.length > 1){ + if (values.length > 1) { return parseInt(values[1], 10) - parseInt(values[0], 10); - }else{ + } else { return parseInt(values[0], 10); } }, - showPointerValue: function(pointer, position, animate){ - var label = $('.pointer-label', this.domNode)[pointer.hasClass('low')?'first':'last'](); + showPointerValue: function(pointer, position, animate) { + var label = $('.pointer-label', this.domNode)[pointer.hasClass('low') ? 'first' : 'last'](); var text; var value = this.positionToValue(position); - if($.isFunction(this.options.format)){ - var type = this.isSingle() ? undefined : (pointer.hasClass('low') ? 'low':'high'); - text = this.options.format(value, type); - }else{ + if ($.isFunction(this.options.format)) { + var type = this.isSingle() ? undefined : (pointer.hasClass('low') ? 'low' : 'high'); + text = this.options.format(value, type); + } else { text = this.options.format.replace('%s', value); } var width = label.html(text).width(), left = position - width / 2; left = Math.min(Math.max(left, 0), this.options.width - width); - label[animate?'animate':'css']({left: left}); + label[animate ? 'animate' : 'css']({ + left: left + }); this.setInputValue(pointer, value); }, - valuesToPrc: function(values){ - var lowPrc = ( ( values[0] - this.options.from ) * 100 / this.interval ), - highPrc = ( ( values[1] - this.options.from ) * 100 / this.interval ); + valuesToPrc: function(values) { + var lowPrc = ((values[0] - this.options.from) * 100 / this.interval), + highPrc = ((values[1] - this.options.from) * 100 / this.interval); return [lowPrc, highPrc]; }, - prcToPx: function(prc){ + prcToPx: function(prc) { return (this.domNode.width() * prc) / 100; }, - positionToValue: function(pos){ + positionToValue: function(pos) { var value = (pos / this.domNode.width()) * this.interval; value = value + this.options.from; - return Math.round(value / this.options.step) * this.options.step; + return Math.round(value / this.options.step) * this.options.step; }, - setInputValue: function(pointer, v){ + setInputValue: function(pointer, v) { // if(!isChanged) return; - if(this.isSingle()){ + if (this.isSingle()) { this.options.value = v.toString(); - }else{ + } else { var values = this.options.value.split(','); - if(pointer.hasClass('low')){ + if (pointer.hasClass('low')) { this.options.value = v + ',' + values[1]; - }else{ + } else { this.options.value = values[0] + ',' + v; } } - if( this.inputNode.val() !== this.options.value ){ + if (this.inputNode.val() !== this.options.value) { this.inputNode.val(this.options.value); this.options.onstatechange.call(this, this.options.value); } }, - getValue: function(){ - return this.options.value; - } + getValue: function() { + return this.options.value; + }, + isReadonly: function(){ + this.domNode.toggleClass('slider-readonly', this.options.disable); + }, + disable: function(){ + this.options.disable = true; + this.isReadonly(); + }, + enable: function(){ + this.options.disable = false; + this.isReadonly(); + }, + toggleDisable: function(){ + this.options.disable = !this.options.disable; + this.isReadonly(); + } }; /*$.jRange = function (node, options) { @@ -275,7 +307,7 @@ // preventing against multiple instantiations $.fn[pluginName] = function(option) { var args = arguments, - result; + result; this.each(function() { var $this = $(this), @@ -283,7 +315,9 @@ options = typeof option === 'object' && option; if (!data) { $this.data('plugin_' + pluginName, (data = new jRange(this, options))); - $(window).resize(function() { data.setValue(data.getValue()); }); // Update slider position when window is resized to keep it in sync with scale + $(window).resize(function() { + data.setValue(data.getValue()); + }); // Update slider position when window is resized to keep it in sync with scale } // if first argument is a string, call silimarly named function // this gives flexibility to call functions of the plugin e.g. |