/*jshint undef: true, unused:true */ /*global jQuery: true */ /*!========================================================================= * Bootstrap TouchSpin * v1.3.1 * * A mobile and touch friendly input spinner component for Bootstrap 3. * * https://github.com/istvan-meszaros/bootstrap-touchspin * http://www.virtuosoft.eu/code/bootstrap-touchspin/ * * Copyright 2013 István Ujj-Mészáros * * Thanks for the contributors: * Stefan Bauer - https://github.com/sba * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ====================================================================== */ (function($) { "use strict"; $.fn.TouchSpin = function(options) { return this.each(function() { var settings, originalinput = $(this), container, elements, // added by keenthemes to set fixed input groups value, downSpinTimer, upSpinTimer, downDelayTimeout, upDelayTimeout, spincount = 0, spinning = false; init(); function init() { if (originalinput.data("alreadyinitialized")) { return; } originalinput.data("alreadyinitialized", true); if (!originalinput.is("input")) { console.log("Must be an input."); return; } _initSettings(); _checkValue(); _buildHtml(); _initElements(); _bindEvents(); _bindEventsInterface(); } function _initSettings() { settings = $.extend({ min: 0, max: 100, step: 1, decimals: 0, stepinterval: 100, stepintervaldelay: 500, prefix: "", postfix: "", booster: true, boostat: 10, maxboostedstep: false, mousewheel: true }, options); } function _buildHtml() { originalinput.data("initvalue", originalinput.val()).val(Number(originalinput.val()).toFixed(settings.decimals)); var html = '
' + settings.prefix + '' + settings.postfix + '
'; container = $(html).insertBefore(originalinput); $(".bootstrap-touchspin-prefix", container).after(originalinput); $("").appendTo("head"); originalinput.addClass("form-control"); } function _initElements() { elements = { down: $(".bootstrap-touchspin-down", container), up: $(".bootstrap-touchspin-up", container), input: $("input", container), prefix: $(".bootstrap-touchspin-prefix", container), postfix: $(".bootstrap-touchspin-postfix", container) }; } 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(); } else { _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 touchstart", function(ev) { downOnce(); startDownSpin(); ev.preventDefault(); ev.stopPropagation(); }); elements.up.on("mousedown touchstart", function(ev) { 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("mouseup touchend touchcancel", function(ev) { if (!spinning) { return; } ev.preventDefault(); stopSpin(); }); $(document).on("mousemove touchmove scroll scrollstart", function(ev) { if (!spinning) { return; } ev.preventDefault(); stopSpin(); }); if (settings.mousewheel) { originalinput.bind("mousewheel DOMMouseScroll", function(ev) { var delta = ev.originalEvent.wheelDelta || -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(); }); } function _checkValue() { var val, parsedval, returnval; val = originalinput.val(); if (settings.decimals > 0 && val === ".") { return; } parsedval = parseFloat(val); if (isNaN(parsedval)) { parsedval = 0; } returnval = parsedval; if (parsedval.toString() !== val) { returnval = parsedval; } if (parsedval < settings.min) { returnval = settings.min; } if (parsedval > settings.max) { returnval = settings.max; } 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() { value = parseFloat(elements.input.val()); if (isNaN(value)) { value = 0; } var initvalue = value, boostedstep = _getBoostedStep(); value = value + boostedstep; if (value > settings.max) { stopSpin(); value = settings.max; originalinput.trigger("touchspin.max"); } elements.input.val(Number(value).toFixed(settings.decimals)); if (initvalue !== value) { originalinput.trigger("change"); } } function downOnce() { value = parseFloat(elements.input.val()); if (isNaN(value)) { value = 0; } var initvalue = value, boostedstep = _getBoostedStep(); value = value - boostedstep; if (value < settings.min) { stopSpin(); value = settings.min; originalinput.trigger("touchspin.min"); } elements.input.val(value.toFixed(settings.decimals)); if (initvalue !== value) { originalinput.trigger("change"); } } function startDownSpin() { stopSpin(); spincount = 0; spinning = "down"; downDelayTimeout = setTimeout(function() { downSpinTimer = setInterval(function() { spincount++; downOnce(); }, settings.stepinterval); }, settings.stepintervaldelay); } function startUpSpin() { stopSpin(); spincount = 0; spinning = "up"; upDelayTimeout = setTimeout(function() { upSpinTimer = setInterval(function() { spincount++; upOnce(); }, settings.stepinterval); }, settings.stepintervaldelay); } function stopSpin() { clearTimeout(downDelayTimeout); clearTimeout(upDelayTimeout); clearInterval(downSpinTimer); clearInterval(upSpinTimer); spincount = 0; spinning = false; } }); }; })(jQuery);