PageSourceSearch

https://www.medienanstalt-nrw.de/_assets/c0a77ee2190b6f632c84e3f57…/jquery.bootstrap-touchspin.js?1788163121

js medienanstalt-nrw.de collected 2026-09-24 09:17:16 UTC 23,091 bytes, 749 lines download raw bytes

vendor: 1,227 bytes, lines 1-45
1/*
2 *  Bootstrap TouchSpin - v4.3.0
3 *  A mobile and touch friendly input spinner component for Bootstrap 3 & 4.
4 *  http://www.virtuosoft.eu/code/bootstrap-touchspin/
5 *
6 *  Made by István Ujj-Mészáros
7 *  Under Apache License v2.0 License
8 */
9(function(factory) {
10  if (typeof define === 'function' && define.amd) {
11    define(['jquery'], factory);
12  } else if (typeof module === 'object' && module.exports) {
13    module.exports = function(root, jQuery) {
14      if (jQuery === undefined) {
15        if (typeof window !== 'undefined') {
16          jQuery = require('jquery');
17        }
18        else {
19          jQuery = require('jquery')(root);
20        }
21      }
22      factory(jQuery);
23      return jQuery;
24    };
25  } else {
26    factory(jQuery);
27  }
28}(function($) {
29  'use strict';
30
31  var _currentSpinnerId = 0;
32
33  $.fn.TouchSpin = function(options) {
34
35    var defaults = {
36      min: 0, // If null, there is no minimum enforced
37      max: 100, // If null, there is no maximum enforced
38      initval: '',
39      replacementval: '',
40      firstclickvalueifempty: null,
41      step: 1,
42      decimals: 0,
43      stepinterval: 100,
44      forcestepdivisibility: 'round', // none | floor | round | ceil
45      stepintervaldelay: 500,
46      verticalbuttons: false,
47      verticalup: '+',
48      verticaldown: '-',
49      verticalupclass: '',
50      verticaldownclass: '',
51      prefix: '',
52      postfix: '',
53      prefix_extraclass: '',
54      postfix_extraclass: '',
55      booster: true,
56      boostat: 10,
57      maxboostedstep: false,
58      mousewheel: true,
59      buttondown_class: 'btn btn-primary',
60      buttonup_class: 'btn btn-primary',
61      buttondown_txt: '-',
62      buttonup_txt: '+',
63      callback_before_calculation: function(value) {
64        return value;
65      },
66      callback_after_calculation: function(value) {
67        return value;
68      }
69    };
70
71    var attributeMap = {
72      min: 'min',
73      max: 'max',
74      initval: 'init-val',
75      replacementval: 'replacement-val',
76      firstclickvalueifempty: 'first-click-value-if-empty',
77      step: 'step',
78      decimals: 'decimals',
79      stepinterval: 'step-interval',
80      verticalbuttons: 'vertical-buttons',
81      verticalupclass: 'vertical-up-class',
82      verticaldownclass: 'vertical-down-class',
83      forcestepdivisibility: 'force-step-divisibility',
84      stepintervaldelay: 'step-interval-delay',
85      prefix: 'prefix',
86      postfix: 'postfix',
87      prefix_extraclass: 'prefix-extra-class',
88      postfix_extraclass: 'postfix-extra-class',
89      booster: 'booster',
90      boostat: 'boostat',
91      maxboostedstep: 'max-boosted-step',
92      mousewheel: 'mouse-wheel',
93      buttondown_class: 'button-down-class',
94      buttonup_class: 'button-up-class',
95      buttondown_txt: 'button-down-txt',
96      buttonup_txt: 'button-up-txt'
97    };
98
99    return this.each(function() {
100
101      var settings,
102        originalinput = $(this),
103        originalinput_data = originalinput.data(),
104        _detached_prefix,
105        _detached_postfix,
106        container,
107        elements,
108        value,
109        downSpinTimer,
110        upSpinTimer,
111        downDelayTimeout,
112        upDelayTimeout,
113        spincount = 0,
114        spinning = false;
115
116      init();
117
118      function init() {
119        if (originalinput.data('alreadyinitialized')) {
120          return;
121        }
122
123        originalinput.data('alreadyinitialized', true);
124        _currentSpinnerId += 1;
125        originalinput.data('spinnerid', _currentSpinnerId);
126
127        if (!originalinput.is('input')) {
128          console.log('Must be an input.');
129          return;
130        }
131
132        _initSettings();
133        _setInitval();
134        _checkValue();
135        _buildHtml();
136        _initElements();
137        _hideEmptyPrefixPostfix();
138        _bindEvents();
139        _bindEventsInterface();
140      }
141
142      function _setInitval() {
143        if (settings.initval !== '' && originalinput.val() === '') {
144          originalinput.val(settings.initval);
145        }
146      }
147
148      function changeSettings(newsettings) {
149        _updateSettings(newsettings);
150        _checkValue();
151
152        var value = elements.input.val();
153
154        if (value !== '') {
155          value = Number(settings.callback_before_calculation(elements.input.val()));
156          elements.input.val(settings.callback_after_calculation(Number(value).toFixed(settings.decimals)));
157        }
158      }
159
160      function _initSettings() {
161        settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);
162      }
163
164      function _parseAttributes() {
165        var data = {};
166        $.each(attributeMap, function(key, value) {
167          var attrName = 'bts-' + value + '';
168          if (originalinput.is('[data-' + attrName + ']')) {
169            data[key] = originalinput.data(attrName);
170          }
171        });
172        return data;
173      }
174
175      function _destroy() {
176        var $parent = originalinput.parent();
177
178        stopSpin();
179
180        originalinput.off('.touchspin');
181
182        if ($parent.hasClass('bootstrap-touchspin-injected')) {
183          originalinput.siblings().remove();
184          originalinput.unwrap();
185        }
186        else {
187          $('.bootstrap-touchspin-injected', $parent).remove();
188          $parent.removeClass('bootstrap-touchspin');
189        }
190
191        originalinput.data('alreadyinitialized', false);
192      }
193
194      function _updateSettings(newsettings) {
195        settings = $.extend({}, settings, newsettings);
196
197        // Update postfix and prefix texts if those settings were changed.
198        if (newsettings.postfix) {
199          var $postfix = originalinput.parent().find('.bootstrap-touchspin-postfix');
200
201          if ($postfix.length === 0) {
202            _detached_postfix.insertAfter(originalinput);
203          }
204
205          originalinput.parent().find('.bootstrap-touchspin-postfix .input-group-text').text(newsettings.postfix);
206        }
207
208        if (newsettings.prefix) {
209          var $prefix = originalinput.parent().find('.bootstrap-touchspin-prefix');
210
211          if ($prefix.length === 0) {
212            _detached_prefix.insertBefore(originalinput);
213          }
214
215          originalinput.parent().find('.bootstrap-touchspin-prefix .input-group-text').text(newsettings.prefix);
216        }
217
218        _hideEmptyPrefixPostfix();
219      }
220
221      function _buildHtml() {
222        var initval = originalinput.val(),
223          parentelement = originalinput.parent();
224
225        if (initval !== '') {
226          initval = settings.callback_after_calculation(Number(initval).toFixed(settings.decimals));
227        }
228
229        originalinput.data('initvalue', initval).val(initval);
230        originalinput.addClass('form-control');
231
232        if (parentelement.hasClass('input-group')) {
233          _advanceInputGroup(parentelement);
234        }
235        else {
236          _buildInputGroup();
237        }
238      }
239
240      function _advanceInputGroup(parentelement) {
241        parentelement.addClass('bootstrap-touchspin');
242
243        var prev = originalinput.prev(),
244          next = originalinput.next();
245
246        var downhtml,
247          uphtml,
248          prefixhtml = '<span class="input-group-addon input-group-prepend bootstrap-touchspin-prefix input-group-prepend bootstrap-touchspin-injected"><span class="input-group-text">' + settings.prefix + '</span></span>',
249          postfixhtml = '<span class="input-group-addon input-group-append bootstrap-touchspin-postfix input-group-append bootstrap-touchspin-injected"><span class="input-group-text">' + settings.postfix + '</span></span>';
250
251        if (prev.hasClass('input-group-btn') || prev.hasClass('input-group-prepend')) {
252          downhtml = '<button class="' + settings.buttondown_class + ' bootstrap-touchspin-down bootstrap-touchspin-injected" type="button">' + settings.buttondown_txt + '</button>';
253          prev.append(downhtml);
254        }
255        else {
256          downhtml = '<span class="input-group-btn input-group-prepend bootstrap-touchspin-injected"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-down" type="button">' + settings.buttondown_txt + '</button></span>';
257          $(downhtml).insertBefore(originalinput);
258        }
259
260        if (next.hasClass('input-group-btn') || next.hasClass('input-group-append')) {
261          uphtml = '<button class="' + settings.buttonup_class + ' bootstrap-touchspin-up bootstrap-touchspin-injected" type="button">' + settings.buttonup_txt + '</button>';
262          next.prepend(uphtml);
263        }
264        else {
265          uphtml = '<span class="input-group-btn input-group-append bootstrap-touchspin-injected"><button class="' + settings.buttonup_class + ' bootstrap-touchspin-up" type="button">' + settings.buttonup_txt + '</button></span>';
266          $(uphtml).insertAfter(originalinput);
267        }
268
269        $(prefixhtml).insertBefore(originalinput);
270        $(postfixhtml).insertAfter(originalinput);
271
272        container = parentelement;
273      }
274
275      function _buildInputGroup() {
276        var html;
277
278        var inputGroupSize = '';
279        if (originalinput.hasClass('input-sm')) {
280          inputGroupSize = 'input-group-sm';
281        }
282
283        if (originalinput.hasClass('input-lg')) {
284          inputGroupSize = 'input-group-lg';
285        }
286
287        if (settings.verticalbuttons) {
288          html = '<div class="input-group ' + inputGroupSize + ' bootstrap-touchspin bootstrap-touchspin-injected"><span class="input-group-addon input-group-prepend bootstrap-touchspin-prefix"><span class="input-group-text">' + settings.prefix + '</span></span><span class="input-group-addon bootstrap-touchspin-postfix input-group-append"><span class="input-group-text">' + settings.postfix + '</span></span><span class="input-group-btn-vertical"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-up ' + settings.verticalupclass + '" type="button">' + settings.verticalup + '</button><button class="' + settings.buttonup_class + ' bootstrap-touchspin-down ' + settings.verticaldownclass + '" type="button">' + settings.verticaldown + '</button></span></div>';
289        }
290        else {
291          html = '<div class="input-group bootstrap-touchspin bootstrap-touchspin-injected"><span class="input-group-btn input-group-prepend"><button class="' + settings.buttondown_class + ' bootstrap-touchspin-down" type="button">' + settings.buttondown_txt + '</button></span><span class="input-group-addon bootstrap-touchspin-prefix input-group-prepend"><span class="input-group-text">' + settings.prefix + '</span></span><span class="input-group-addon bootstrap-touchspin-postfix input-group-append"><span class="input-group-text">' + settings.postfix + '</span></span><span class="input-group-btn input-group-append"><button class="' + settings.buttonup_class + ' bootstrap-touchspin-up" type="button">' + settings.buttonup_txt + '</button></span></div>';
292        }
293
294        container = $(html).insertBefore(originalinput);
295
296        $('.bootstrap-touchspin-prefix', container).after(originalinput);
297
298        if (originalinput.hasClass('input-sm')) {
299          container.addClass('input-group-sm');
300        }
301        else if (originalinput.hasClass('input-lg')) {
302          container.addClass('input-group-lg');
303        }
304      }
305
306      function _initElements() {
307        elements = {
308          down: $('.bootstrap-touchspin-down', container),
309          up: $('.bootstrap-touchspin-up', container),
310          input: $('input', container),
311          prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),
312          postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)
313        };
314      }
315
316      function _hideEmptyPrefixPostfix() {
317        if (settings.prefix === '') {
318          _detached_prefix = elements.prefix.detach();
319        }
320
321        if (settings.postfix === '') {
322          _detached_postfix = elements.postfix.detach();
323        }
324      }
325
326      function _bindEvents() {
327        originalinput.on('keydown.touchspin', function(ev) {
328          var code = ev.keyCode || ev.which;
329
330          if (code === 38) {
331            if (spinning !== 'up') {
332              upOnce();
333              startUpSpin();
334            }
335            ev.preventDefault();
336          }
337          else if (code === 40) {
338            if (spinning !== 'down') {
339              downOnce();
340              startDownSpin();
341            }
342            ev.preventDefault();
343          }
344        });
345
346        originalinput.on('keyup.touchspin', function(ev) {
347          var code = ev.keyCode || ev.which;
348
349          if (code === 38) {
350            stopSpin();
351          }
352          else if (code === 40) {
353            stopSpin();
354          }
355        });
356
357        originalinput.on('blur.touchspin', function() {
358          _checkValue();
359          originalinput.val(settings.callback_after_calculation(originalinput.val()));
360        });
361
362        elements.down.on('keydown', function(ev) {
363          var code = ev.keyCode || ev.which;
364
365          if (code === 32 || code === 13) {
366            if (spinning !== 'down') {
367              downOnce();
368              startDownSpin();
369            }
370            ev.preventDefault();
371          }
372        });
373
374        elements.down.on('keyup.touchspin', function(ev) {
375          var code = ev.keyCode || ev.which;
376
377          if (code === 32 || code === 13) {
378            stopSpin();
379          }
380        });
381
382        elements.up.on('keydown.touchspin', function(ev) {
383          var code = ev.keyCode || ev.which;
384
385          if (code === 32 || code === 13) {
386            if (spinning !== 'up') {
387              upOnce();
388              startUpSpin();
389            }
390            ev.preventDefault();
391          }
392        });
393
394        elements.up.on('keyup.touchspin', function(ev) {
395          var code = ev.keyCode || ev.which;
396
397          if (code === 32 || code === 13) {
398            stopSpin();
399          }
400        });
401
402        elements.down.on('mousedown.touchspin', function(ev) {
403          elements.down.off('touchstart.touchspin');  // android 4 workaround
404
405          if (originalinput.is(':disabled')) {
406            return;
407          }
408
409          downOnce();
410          startDownSpin();
411
412          ev.preventDefault();
413          ev.stopPropagation();
414        });
415
416        elements.down.on('touchstart.touchspin', function(ev) {
417          elements.down.off('mousedown.touchspin');  // android 4 workaround
418
419          if (originalinput.is(':disabled')) {
420            return;
421          }
422
423          downOnce();
424          startDownSpin();
425
426          ev.preventDefault();
427          ev.stopPropagation();
428        });
429
430        elements.up.on('mousedown.touchspin', function(ev) {
431          elements.up.off('touchstart.touchspin');  // android 4 workaround
432
433          if (originalinput.is(':disabled')) {
434            return;
435          }
436
437          upOnce();
438          startUpSpin();
439
440          ev.preventDefault();
441          ev.stopPropagation();
442        });
443
444        elements.up.on('touchstart.touchspin', function(ev) {
445          elements.up.off('mousedown.touchspin');  // android 4 workaround
446
447          if (originalinput.is(':disabled')) {
448            return;
449          }
450
451          upOnce();
452          startUpSpin();
453
454          ev.preventDefault();
455          ev.stopPropagation();
456        });
457
458        elements.up.on('mouseup.touchspin mouseout.touchspin touchleave.touchspin touchend.touchspin touchcancel.touchspin', function(ev) {
459          if (!spinning) {
460            return;
461          }
462
463          ev.stopPropagation();
464          stopSpin();
465        });
466
467        elements.down.on('mouseup.touchspin mouseout.touchspin touchleave.touchspin touchend.touchspin touchcancel.touchspin', function(ev) {
468          if (!spinning) {
469            return;
470          }
471
472          ev.stopPropagation();
473          stopSpin();
474        });
475
476        elements.down.on('mousemove.touchspin touchmove.touchspin', function(ev) {
477          if (!spinning) {
478            return;
479          }
480
481          ev.stopPropagation();
482          ev.preventDefault();
483        });
484
485        elements.up.on('mousemove.touchspin touchmove.touchspin', function(ev) {
486          if (!spinning) {
487            return;
488          }
489
490          ev.stopPropagation();
491          ev.preventDefault();
492        });
493
494        originalinput.on('mousewheel.touchspin DOMMouseScroll.touchspin', function(ev) {
495          if (!settings.mousewheel || !originalinput.is(':focus')) {
496            return;
497          }
498
499          var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;
500
501          ev.stopPropagation();
502          ev.preventDefault();
503
504          if (delta < 0) {
505            downOnce();
506          }
507          else {
508            upOnce();
509          }
510        });
511      }
512
513      function _bindEventsInterface() {
514        originalinput.on('touchspin.destroy', function() {
515          _destroy();
516        });
517
518        originalinput.on('touchspin.uponce', function() {
519          stopSpin();
520          upOnce();
521        });
522
523        originalinput.on('touchspin.downonce', function() {
524          stopSpin();
525          downOnce();
526        });
527
528        originalinput.on('touchspin.startupspin', function() {
529          startUpSpin();
530        });
531
532        originalinput.on('touchspin.startdownspin', function() {
533          startDownSpin();
534        });
535
536        originalinput.on('touchspin.stopspin', function() {
537          stopSpin();
538        });
539
540        originalinput.on('touchspin.updatesettings', function(e, newsettings) {
541          changeSettings(newsettings);
542        });
543      }
544
545      function _forcestepdivisibility(value) {
546        switch (settings.forcestepdivisibility) {
547          case 'round':
548            return (Math.r
548ound(value / settings.step) * settings.step).toFixed(settings.decimals);
549          case 'floor':
550            return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);
551          case 'ceil':
552            return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);
553          default:
554            return value.toFixed(settings.decimals);
555        }
556      }
557
558      function _checkValue() {
559        var val, parsedval, returnval;
560
561        val = settings.callback_before_calculation(originalinput.val());
562
563        if (val === '') {
564          if (settings.replacementval !== '') {
565            originalinput.val(settings.replacementval);
566            originalinput.trigger('change');
567          }
568          return;
569        }
570
571        if (settings.decimals > 0 && val === '.') {
572          return;
573        }
574
575        parsedval = parseFloat(val);
576
577        if (isNaN(parsedval)) {
578          if (settings.replacementval !== '') {
579            parsedval = settings.replacementval;
580          }
581          else {
582            parsedval = 0;
583          }
584        }
585
586        returnval = parsedval;
587
588        if (parsedval.toString() !== val) {
589          returnval = parsedval;
590        }
591
592        if ((settings.min !== null) && (parsedval < settings.min)) {
593          returnval = settings.min;
594        }
595
596        if ((settings.max !== null) && (parsedval > settings.max)) {
597          returnval = settings.max;
598        }
599
600        returnval = _forcestepdivisibility(returnval);
601
602        if (Number(val).toString() !== returnval.toString()) {
603          originalinput.val(returnval);
604          originalinput.trigger('change');
605        }
606      }
607
608      function _getBoostedStep() {
609        if (!settings.booster) {
610          return settings.step;
611        }
612        else {
613          var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;
614
615          if (settings.maxboostedstep) {
616            if (boosted > settings.maxboostedstep) {
617              boosted = settings.maxboostedstep;
618              value = Math.round((value / boosted)) * boosted;
619            }
620          }
621
622          return Math.max(settings.step, boosted);
623        }
624      }
625
626      function valueIfIsNaN() {
627        if(typeof(settings.firstclickvalueifempty) === 'number') {
628          return settings.firstclickvalueifempty;
629        } else {
630          return (settings.min + settings.max) / 2;
631        }
632      }
633
634      function upOnce() {
635        _checkValue();
636
637        value = parseFloat(settings.callback_before_calculation(elements.input.val()));
638
639        var initvalue = value;
640        var boostedstep;
641
642        if (isNaN(value)) {
643          value = valueIfIsNaN();
644        } else {
645          boostedstep = _getBoostedStep();
646          value = value + boostedstep;
647        }
648
649        if ((settings.max !== null) && (value > settings.max)) {
650          value = settings.max;
651          originalinput.trigger('touchspin.on.max');
652          stopSpin();
653        }
654
655        elements.input.val(settings.callback_after_calculation(Number(value).toFixed(settings.decimals)));
656
657        if (initvalue !== value) {
658          originalinput.trigger('change');
659        }
660      }
661
662      function downOnce() {
663        _checkValue();
664
665        value = parseFloat(settings.callback_before_calculation(elements.input.val()));
666
667        var initvalue = value;
668        var boostedstep;
669
670        if (isNaN(value)) {
671          value = valueIfIsNaN();
672        } else {
673          boostedstep = _getBoostedStep();
674          value = value - boostedstep;
675        }
676
677        if ((settings.min !== null) && (value < settings.min)) {
678          value = settings.min;
679          originalinput.trigger('touchspin.on.min');
680          stopSpin();
681        }
682
683        elements.input.val(settings.callback_after_calculation(Number(value).toFixed(settings.decimals)));
684
685        if (initvalue !== value) {
686          originalinput.trigger('change');
687        }
688      }
689
690      function startDownSpin() {
691        stopSpin();
692
693        spincount = 0;
694        spinning = 'down';
695
696        originalinput.trigger('touchspin.on.startspin');
697        originalinput.trigger('touchspin.on.startdownspin');
698
699        downDelayTimeout = setTimeout(function() {
700          downSpinTimer = setInterval(function() {
701            spincount++;
702            downOnce();
703          }, settings.stepinterval);
704        }, settings.stepintervaldelay);
705      }
706
707      function startUpSpin() {
708        stopSpin();
709
710        spincount = 0;
711        spinning = 'up';
712
713        originalinput.trigger('touchspin.on.startspin');
714        originalinput.trigger('touchspin.on.startupspin');
715
716        upDelayTimeout = setTimeout(function() {
717          upSpinTimer = setInterval(function() {
718            spincount++;
719            upOnce();
720          }, settings.stepinterval);
721        }, settings.stepintervaldelay);
722      }
723
724      function stopSpin() {
725        clearTimeout(downDelayTimeout);
726        clearTimeout(upDelayTimeout);
727        clearInterval(downSpinTimer);
728        clearInterval(upSpinTimer);
729
730        switch (spinning) {
731          case 'up':
732            originalinput.trigger('touchspin.on.stopupspin');
733            originalinput.trigger('touchspin.on.stopspin');
734            break;
735          case 'down':
736            originalinput.trigger('touchspin.on.stopdownspin');
737            originalinput.trigger('touchspin.on.stopspin');
738            break;
739        }
740
741        spincount = 0;
742        spinning = false;
743      }
744
745    });
746
747  };
748
749}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.