PageSourceSearch

https://moi.go.th/moi/wp-content/plugins/nex-forms/js/jquery.bootstrap-touchspin.js?v7_5_8_23&ver=5.1.1

js moi.go.th collected 2026-10-01 10:39:10 UTC 20,858 bytes, 705 lines download raw bytes

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

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.