PageSourceSearch

https://ahlik3.co.id/assets/themes/newfront/js/jquery.bootstrap-touchspin.js

js ahlik3.co.id collected 2026-09-26 20:34:30 UTC 25,066 bytes, 742 lines download raw bytes

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

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.