aboutsummaryrefslogtreecommitdiffstats
path: root/library/jRange/jquery.range.js
diff options
context:
space:
mode:
authorStefan Parviainen <saparvia@caterva.eu>2015-01-05 18:30:12 +0100
committerStefan Parviainen <saparvia@caterva.eu>2015-01-05 18:30:12 +0100
commit128b0008eef797050cf5146fb1dd69505c4439d4 (patch)
tree65d6b6214ee48322bd5a5c84e0ac9bcde09ff13a /library/jRange/jquery.range.js
parent7791d28a5d24193a01ce004988ba6767f45835ba (diff)
downloadvolse-hubzilla-128b0008eef797050cf5146fb1dd69505c4439d4.tar.gz
volse-hubzilla-128b0008eef797050cf5146fb1dd69505c4439d4.tar.bz2
volse-hubzilla-128b0008eef797050cf5146fb1dd69505c4439d4.zip
Replace jslider with jRange
Diffstat (limited to 'library/jRange/jquery.range.js')
-rw-r--r--library/jRange/jquery.range.js297
1 files changed, 297 insertions, 0 deletions
diff --git a/library/jRange/jquery.range.js b/library/jRange/jquery.range.js
new file mode 100644
index 000000000..978b3e7ba
--- /dev/null
+++ b/library/jRange/jquery.range.js
@@ -0,0 +1,297 @@
+/*jshint multistr:true, curly: false */
+/*global jQuery:false, define: false */
+/**
+ * jRange - Awesome range control
+ *
+ * Written by
+ * ----------
+ * Nitin Hayaran (nitinhayaran@gmail.com)
+ *
+ * Licensed under the MIT (MIT-LICENSE.txt).
+ *
+ * @author Nitin Hayaran
+ * @version 0.1-RELEASE
+ *
+ * Dependencies
+ * ------------
+ * jQuery (http://jquery.com)
+ *
+ **/
+ ;
+ (function($, window, document, undefined) {
+ 'use strict';
+
+ var jRange = function(){
+ return this.init.apply(this, arguments);
+ };
+ jRange.prototype = {
+ defaults : {
+ onstatechange : function(){},
+ isRange : false,
+ showLabels : true,
+ showScale : true,
+ step : 1,
+ format: '%s',
+ theme : 'theme-green',
+ width : 300
+ },
+ 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>\
+ <div class="pointer high"></div><div class="pointer-label">456789</div>\
+ <div class="clickable-dummy"></div>\
+ </div>\
+ <div class="scale"></div>\
+ </div>',
+ 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.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.render();
+ },
+ 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 ){
+ console.log('jRange : no width found, returning');
+ return;
+ }else{
+ this.domNode.width( this.options.width || this.inputNode.width() );
+ this.inputNode.hide();
+ }
+
+ if(this.isSingle()){
+ this.lowPointer.hide();
+ this.lowLabel.hide();
+ }
+ if(!this.options.showLabels){
+ this.labels.hide();
+ }
+ this.attachEvents();
+ if(this.options.showScale){
+ this.renderScale();
+ }
+ this.setValue(this.options.value);
+ },
+ isSingle: function(){
+ if(typeof(this.options.value) === 'number'){
+ return true;
+ }
+ return (this.options.value.indexOf(',') !== -1 || this.options.isRange) ?
+ false : true;
+ },
+ attachEvents: function(){
+ this.clickableBar.click($.proxy(this.barClicked, this));
+ this.pointers.mousedown($.proxy(this.onDragStart, this));
+ this.pointers.bind('dragstart', function(event) { event.preventDefault(); });
+ },
+ onDragStart: function(e){
+ if(e.which !== 1){return;}
+ e.stopPropagation(); e.preventDefault();
+ var pointer = $(e.target);
+ pointer.addClass('focused');
+ 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));
+ },
+ onDrag: function(pointer, e){
+ e.stopPropagation(); e.preventDefault();
+ var position = e.clientX - this.domNode.offset().left;
+ this.domNode.trigger('change', [this, pointer, position]);
+ },
+ onDragEnd: function(){
+ this.pointers.removeClass('focused');
+ this.labels.removeClass('focused');
+ $(document).off('.slider');
+ $(document).off('.slider');
+ },
+ barClicked: function(e){
+ var x = e.pageX - this.clickableBar.offset().left;
+ if(this.isSingle())
+ this.setPosition(this.pointers.last(), x, true, true);
+ 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){
+ var min, max;
+ if(self.isSingle()){
+ min = 0;
+ max = self.domNode.width();
+ }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){
+ var leftPos,
+ lowPos = this.lowPointer.position().left,
+ highPos = this.highPointer.position().left,
+ circleWidth = this.highPointer.width() / 2;
+ if(!isPx){
+ position = this.prcToPx(position);
+ }
+ 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()){
+ leftPos = 0;
+ }else{
+ leftPos = lowPos + circleWidth;
+ }
+ this.bar[animate?'animate':'css']({
+ 'width' : Math.round(highPos + circleWidth - leftPos),
+ 'left' : leftPos
+ });
+ this.showPointerValue(pointer, position, animate);
+ },
+ // will be called from outside
+ 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()){
+ this.setPosition(this.highPointer, prc[1]);
+ }else{
+ this.setPosition(this.lowPointer, prc[0]);
+ this.setPosition(this.highPointer, prc[1]);
+ }
+ },
+ 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++ ){
+ str += '<span style="left: ' + i * prc + '%">' + (s[i] != '|' ? '<ins>' + s[i] + '</ins>' : '') + '</span>';
+ }
+ this.scale.html(str);
+
+ $('ins', this.scale).each(function () {
+ $(this).css({
+ marginLeft: -$(this).outerWidth() / 2
+ });
+ });
+ },
+ getBarWidth: function(){
+ var values = this.options.value.split(',');
+ if(values.length > 1){
+ return parseInt(values[1], 10) - parseInt(values[0], 10);
+ }else{
+ return parseInt(values[0], 10);
+ }
+ },
+ 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{
+ 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});
+ 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 );
+ return [lowPrc, highPrc];
+ },
+ prcToPx: function(prc){
+ return (this.domNode.width() * prc) / 100;
+ },
+ 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;
+ },
+ setInputValue: function(pointer, v){
+ // if(!isChanged) return;
+ if(this.isSingle()){
+ this.options.value = v.toString();
+ }else{
+ var values = this.options.value.split(',');
+ if(pointer.hasClass('low')){
+ this.options.value = v + ',' + values[1];
+ }else{
+ this.options.value = values[0] + ',' + v;
+ }
+ }
+ 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;
+ }
+ };
+
+ /*$.jRange = function (node, options) {
+ var jNode = $(node);
+ if(!jNode.data('jrange')){
+ jNode.data('jrange', new jRange(node, options));
+ }
+ return jNode.data('jrange');
+ };
+
+ $.fn.jRange = function (options) {
+ return this.each(function(){
+ $.jRange(this, options);
+ });
+ };*/
+
+ var pluginName = 'jRange';
+ // A really lightweight plugin wrapper around the constructor,
+ // preventing against multiple instantiations
+ $.fn[pluginName] = function(option) {
+ var args = arguments,
+ result;
+
+ this.each(function() {
+ var $this = $(this),
+ data = $.data(this, 'plugin_' + pluginName),
+ options = typeof option === 'object' && option;
+ if (!data) {
+ $this.data('plugin_' + pluginName, (data = new jRange(this, options)));
+ }
+ // if first argument is a string, call silimarly named function
+ // this gives flexibility to call functions of the plugin e.g.
+ // - $('.dial').plugin('destroy');
+ // - $('.dial').plugin('render', $('.new-child'));
+ if (typeof option === 'string') {
+ result = data[option].apply(data, Array.prototype.slice.call(args, 1));
+ }
+ });
+
+ // To enable plugin returns values
+ return result || this;
+ };
+
+})(jQuery, window, document); \ No newline at end of file