Blame | Letzte Änderung | Log anzeigen | RSS feed
(function($) {'use strict';var _currentSpinnerId = 0;function _scopedEventName(name, id) {return name + '.touchspin_' + id;}function _scopeEventNames(names, id) {return $.map(names, function(name) {return _scopedEventName(name, id);});}$.fn.TouchSpin = function(options) {if (options === 'destroy') {this.each(function() {var originalinput = $(this),originalinput_data = originalinput.data();$(document).off(_scopeEventNames(['mouseup','touchend','touchcancel','mousemove','touchmove','scroll','scrollstart'], originalinput_data.spinnerid).join(' '));});return;}var defaults = {min: 0,max: 100,initval: '',replacementval: '',step: 1,decimals: 0,stepinterval: 100,forcestepdivisibility: 'round', // none | floor | round | ceilstepintervaldelay: 500,verticalbuttons: false,verticalupclass: 'glyphicon glyphicon-chevron-up',verticaldownclass: 'glyphicon glyphicon-chevron-down',prefix: '',postfix: '',prefix_extraclass: '',postfix_extraclass: '',booster: true,boostat: 10,maxboostedstep: false,mousewheel: true,buttondown_class: 'btn btn-default',buttonup_class: 'btn btn-default',buttondown_txt: '-',buttonup_txt: '+'};var attributeMap = {min: 'min',max: 'max',initval: 'init-val',replacementval: 'replacement-val',step: 'step',decimals: 'decimals',stepinterval: 'step-interval',verticalbuttons: 'vertical-buttons',verticalupclass: 'vertical-up-class',verticaldownclass: 'vertical-down-class',forcestepdivisibility: 'force-step-divisibility',stepintervaldelay: 'step-interval-delay',prefix: 'prefix',postfix: 'postfix',prefix_extraclass: 'prefix-extra-class',postfix_extraclass: 'postfix-extra-class',booster: 'booster',boostat: 'boostat',maxboostedstep: 'max-boosted-step',mousewheel: 'mouse-wheel',buttondown_class: 'button-down-class',buttonup_class: 'button-up-class',buttondown_txt: 'button-down-txt',buttonup_txt: 'button-up-txt'};return this.each(function() {var settings,originalinput = $(this),originalinput_data = originalinput.data(),container,elements,value,downSpinTimer,upSpinTimer,downDelayTimeout,upDelayTimeout,spincount = 0,spinning = false;init();function init() {if (originalinput.data('alreadyinitialized')) {return;}originalinput.data('alreadyinitialized', true);_currentSpinnerId += 1;originalinput.data('spinnerid', _currentSpinnerId);if (!originalinput.is('input')) {console.log('Must be an input.');return;}_initSettings();_setInitval();_checkValue();_buildHtml();_initElements();_hideEmptyPrefixPostfix();_bindEvents();_bindEventsInterface();elements.input.css('display', 'block');}function _setInitval() {if (settings.initval !== '' && originalinput.val() === '') {originalinput.val(settings.initval);}}function changeSettings(newsettings) {_updateSettings(newsettings);_checkValue();var value = elements.input.val();if (value !== '') {value = Number(elements.input.val());elements.input.val(value.toFixed(settings.decimals));}}function _initSettings() {settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);}function _parseAttributes() {var data = {};$.each(attributeMap, function(key, value) {var attrName = 'bts-' + value + '';if (originalinput.is('[data-' + attrName + ']')) {data[key] = originalinput.data(attrName);}});return data;}function _updateSettings(newsettings) {settings = $.extend({}, settings, newsettings);// Update postfix and prefix texts if those settings were changed.if (newsettings.postfix) {originalinput.parent().find('.bootstrap-touchspin-postfix').text(newsettings.postfix);}if (newsettings.prefix) {originalinput.parent().find('.bootstrap-touchspin-prefix').text(newsettings.prefix);}}function _buildHtml() {var initval = originalinput.val(),parentelement = originalinput.parent();if (initval !== '') {initval = Number(initval).toFixed(settings.decimals);}originalinput.data('initvalue', initval).val(initval);originalinput.addClass('form-control');if (parentelement.hasClass('input-group')) {_advanceInputGroup(parentelement);}else {_buildInputGroup();}}function _advanceInputGroup(parentelement) {parentelement.addClass('bootstrap-touchspin');var prev = originalinput.prev(),next = originalinput.next();var downhtml,uphtml,prefixhtml = '<span class="input-group-addon bootstrap-touchspin-prefix">' + settings.prefix + '</span>',postfixhtml = '<span class="input-group-addon bootstrap-touchspin-postfix">' + settings.postfix + '</span>';if (prev.hasClass('input-group-btn')) {downhtml = '<button class="' + settings.buttondown_class + ' bootstrap-touchspin-down" type="button">' + settings.buttondown_txt + '</button>';prev.append(downhtml);}else {downhtml = '<span class="input-group-btn"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-down" type="button">' + settings.buttondown_txt + '</button></span>';$(downhtml).insertBefore(originalinput);}if (next.hasClass('input-group-btn')) {uphtml = '<button class="' + settings.buttonup_class + ' bootstrap-touchspin-up" type="button">' + settings.buttonup_txt + '</button>';next.prepend(uphtml);}else {uphtml = '<span class="input-group-btn"><button class="' + settings.buttonup_class + ' bootstrap-touchspin-up" type="button">' + settings.buttonup_txt + '</button></span>';$(uphtml).insertAfter(originalinput);}$(prefixhtml).insertBefore(originalinput);$(postfixhtml).insertAfter(originalinput);container = parentelement;}function _buildInputGroup() {var html;if (settings.verticalbuttons) {html = '<div class="input-group bootstrap-touchspin"><span class="input-group-addon bootstrap-touchspin-prefix">' + settings.prefix + '</span><span class="input-group-addon bootstrap-touchspin-postfix">' + settings.postfix + '</span><span class="input-group-btn-vertical"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-up" type="button"><i class="' + settings.verticalupclass + '"></i></button><button class="' + settings.buttonup_class + ' bootstrap-touchspin-down" type="button"><i class="' + settings.verticaldownclass + '"></i></button></span></div>';}else {html = '<div class="input-group bootstrap-touchspin"><span class="input-group-btn"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-down" type="button">' + settings.buttondown_txt + '</button></span><span class="input-group-addon bootstrap-touchspin-prefix">' + settings.prefix + '</span><span class="input-group-addon bootstrap-touchspin-postfix">' + settings.postfix + '</span><span class="input-group-btn"><button class="' + settings.buttonup_class + ' bootstrap-touchspin-up" type="button">' + settings.buttonup_txt + '</button></span></div>';}container = $(html).insertBefore(originalinput);$('.bootstrap-touchspin-prefix', container).after(originalinput);if (originalinput.hasClass('input-sm')) {container.addClass('input-group-sm');}else if (originalinput.hasClass('input-lg')) {container.addClass('input-group-lg');}}function _initElements() {elements = {down: $('.bootstrap-touchspin-down', container),up: $('.bootstrap-touchspin-up', container),input: $('input', container),prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)};}function _hideEmptyPrefixPostfix() {if (settings.prefix === '') {elements.prefix.hide();}if (settings.postfix === '') {elements.postfix.hide();}}function _bindEvents() {originalinput.on('keydown', function(ev) {var code = ev.keyCode || ev.which;if (code === 38) {if (spinning !== 'up') {upOnce();startUpSpin();}ev.preventDefault();}else if (code === 40) {if (spinning !== 'down') {downOnce();startDownSpin();}ev.preventDefault();}});originalinput.on('keyup', function(ev) {var code = ev.keyCode || ev.which;if (code === 38) {stopSpin();}else if (code === 40) {stopSpin();}});originalinput.on('blur', function() {_checkValue();});elements.down.on('keydown', function(ev) {var code = ev.keyCode || ev.which;if (code === 32 || code === 13) {if (spinning !== 'down') {downOnce();startDownSpin();}ev.preventDefault();}});elements.down.on('keyup', function(ev) {var code = ev.keyCode || ev.which;if (code === 32 || code === 13) {stopSpin();}});elements.up.on('keydown', function(ev) {var code = ev.keyCode || ev.which;if (code === 32 || code === 13) {if (spinning !== 'up') {upOnce();startUpSpin();}ev.preventDefault();}});elements.up.on('keyup', function(ev) {var code = ev.keyCode || ev.which;if (code === 32 || code === 13) {stopSpin();}});elements.down.on('mousedown.touchspin', function(ev) {elements.down.off('touchstart.touchspin'); // android 4 workaroundif (originalinput.is(':disabled')) {return;}downOnce();startDownSpin();ev.preventDefault();ev.stopPropagation();});elements.down.on('touchstart.touchspin', function(ev) {elements.down.off('mousedown.touchspin'); // android 4 workaroundif (originalinput.is(':disabled')) {return;}downOnce();startDownSpin();ev.preventDefault();ev.stopPropagation();});elements.up.on('mousedown.touchspin', function(ev) {elements.up.off('touchstart.touchspin'); // android 4 workaroundif (originalinput.is(':disabled')) {return;}upOnce();startUpSpin();ev.preventDefault();ev.stopPropagation();});elements.up.on('touchstart.touchspin', function(ev) {elements.up.off('mousedown.touchspin'); // android 4 workaroundif (originalinput.is(':disabled')) {return;}upOnce();startUpSpin();ev.preventDefault();ev.stopPropagation();});elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {if (!spinning) {return;}ev.stopPropagation();stopSpin();});elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {if (!spinning) {return;}ev.stopPropagation();stopSpin();});elements.down.on('mousemove touchmove', function(ev) {if (!spinning) {return;}ev.stopPropagation();ev.preventDefault();});elements.up.on('mousemove touchmove', function(ev) {if (!spinning) {return;}ev.stopPropagation();ev.preventDefault();});$(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {if (!spinning) {return;}ev.preventDefault();stopSpin();});$(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {if (!spinning) {return;}ev.preventDefault();stopSpin();});originalinput.on('mousewheel DOMMouseScroll', function(ev) {if (!settings.mousewheel || !originalinput.is(':focus')) {return;}var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;ev.stopPropagation();ev.preventDefault();if (delta < 0) {downOnce();}else {upOnce();}});}function _bindEventsInterface() {originalinput.on('touchspin.uponce', function() {stopSpin();upOnce();});originalinput.on('touchspin.downonce', function() {stopSpin();downOnce();});originalinput.on('touchspin.startupspin', function() {startUpSpin();});originalinput.on('touchspin.startdownspin', function() {startDownSpin();});originalinput.on('touchspin.stopspin', function() {stopSpin();});originalinput.on('touchspin.updatesettings', function(e, newsettings) {changeSettings(newsettings);});}function _forcestepdivisibility(value) {switch (settings.forcestepdivisibility) {case 'round':return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);case 'floor':return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);case 'ceil':return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);default:return value;}}function _checkValue() {var val, parsedval, returnval;val = originalinput.val();if (val === '') {if (settings.replacementval !== '') {originalinput.val(settings.replacementval);originalinput.trigger('change');}return;}if (settings.decimals > 0 && val === '.') {return;}parsedval = parseFloat(val);if (isNaN(parsedval)) {if (settings.replacementval !== '') {parsedval = settings.replacementval;}else {parsedval = 0;}}returnval = parsedval;if (parsedval.toString() !== val) {returnval = parsedval;}if (parsedval < settings.min) {returnval = settings.min;}if (parsedval > settings.max) {returnval = settings.max;}returnval = _forcestepdivisibility(returnval);if (Number(val).toString() !== returnval.toString()) {originalinput.val(returnval);originalinput.trigger('change');}}function _getBoostedStep() {if (!settings.booster) {return settings.step;}else {var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;if (settings.maxboostedstep) {if (boosted > settings.maxboostedstep) {boosted = settings.maxboostedstep;value = Math.round((value / boosted)) * boosted;}}return Math.max(settings.step, boosted);}}function upOnce() {_checkValue();value = parseFloat(elements.input.val());if (isNaN(value)) {value = 0;}var initvalue = value,boostedstep = _getBoostedStep();value = value + boostedstep;if (value > settings.max) {value = settings.max;originalinput.trigger('touchspin.on.max');stopSpin();}elements.input.val(Number(value).toFixed(settings.decimals));if (initvalue !== value) {originalinput.trigger('change');}}function downOnce() {_checkValue();value = parseFloat(elements.input.val());if (isNaN(value)) {value = 0;}var initvalue = value,boostedstep = _getBoostedStep();value = value - boostedstep;if (value < settings.min) {value = settings.min;originalinput.trigger('touchspin.on.min');stopSpin();}elements.input.val(value.toFixed(settings.decimals));if (initvalue !== value) {originalinput.trigger('change');}}function startDownSpin() {stopSpin();spincount = 0;spinning = 'down';originalinput.trigger('touchspin.on.startspin');originalinput.trigger('touchspin.on.startdownspin');downDelayTimeout = setTimeout(function() {downSpinTimer = setInterval(function() {spincount++;downOnce();}, settings.stepinterval);}, settings.stepintervaldelay);}function startUpSpin() {stopSpin();spincount = 0;spinning = 'up';originalinput.trigger('touchspin.on.startspin');originalinput.trigger('touchspin.on.startupspin');upDelayTimeout = setTimeout(function() {upSpinTimer = setInterval(function() {spincount++;upOnce();}, settings.stepinterval);}, settings.stepintervaldelay);}function stopSpin() {clearTimeout(downDelayTimeout);clearTimeout(upDelayTimeout);clearInterval(downSpinTimer);clearInterval(upSpinTimer);switch (spinning) {case 'up':originalinput.trigger('touchspin.on.stopupspin');originalinput.trigger('touchspin.on.stopspin');break;case 'down':originalinput.trigger('touchspin.on.stopdownspin');originalinput.trigger('touchspin.on.stopspin');break;}spincount = 0;spinning = false;}});};})(jQuery);