1/*! 2 * JavaScript Custom Forms : Number Module 3 * 4 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf 5 * Released under the MIT license (LICENSE.txt) 6 * 7 * Version: 1.2.3 8 */ 9 10(function(jcf) { 11 12jcf.addModule(function($) { 13 'use strict'; 14 15 return { 16 name: 'Number', 17 selector: 'input[type="number"]', 18 options: { 19 realElementClass: 'jcf-real-element', 20 fakeStructure: '<span class="jcf-number"><span class="jcf-btn-inc"></span><span class="jcf-btn-dec"></span></span>', 21 btnIncSelector: '.jcf-btn-inc', 22 btnDecSelector: '.jcf-btn-dec', 23 pressInterval: 150 24 }, 25 matchElement: function(element) { 26 if(element.hasClass('disable-jcf')) 27 { 28 return false; 29 } 30 return element.is(this.selector); 31 }, 32 init: function() { 33 this.initStructure(); 34 this.attachEvents(); 35 this.refresh(); 36 }, 37 initStructure: function() { 38 this.page = $('html'); 39 this.realElement = $(this.options.element).addClass(this.options.realElementClass); 40 this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement); 41 this.btnDec = this.fakeElement.find(this.options.btnDecSelector); 42 this.btnInc = this.fakeElement.find(this.options.btnIncSelector); 43 44 // set initial values 45 this.initialValue = parseFloat(this.realElement.val()) || 0; 46 this.minValue = parseFloat(this.realElement.attr('min')); 47 this.maxValue = parseFloat(this.realElement.attr('max')); 48 this.stepValue = parseFloat(this.realElement.attr('step')) || 1; 49 50 // check attribute values 51 this.minValue = isNaN(this.minValue) ? -Infinity : this.minValue; 52 this.maxValue = isNaN(this.maxValue) ? Infinity : this.maxValue; 53 54 // handle range 55 if (isFinite(this.maxValue)) { 56 this.maxValue -= (this.maxValue - this.minValue) % this.stepValue; 57 } 58 }, 59 attachEvents: function() { 60 this.realElement.on({ 61 focus: this.onFocus 62 }); 63 this.btnDec.add(this.btnInc).on('jcf-pointerdown', this.onBtnPress); 64 }, 65 onBtnPress: function(e) { 66 var self = this, 67 increment; 68 69 if (!this.realElement.is(':disabled')) { 70 increment = this.btnInc.is(e.currentTarget); 71 72 self.step(increment); 73 clearInterval(this.stepTimer); 74 this.stepTimer = setInterval(function() { 75 self.step(increment); 76 }, this.options.pressInterval); 77 78 this.page.on('jcf-pointerup', this.onBtnRelease); 79 } 80 }, 81 onBtnRelease: function() { 82 clearInterval(this.stepTimer); 83 this.page.off('jcf-pointerup', this.onBtnRelease); 84 }, 85 onFocus: function() { 86 this.fakeElement.addClass(this.options.focusClass); 87 this.realElement.on({ 88 blur: this.onBlur, 89 keydown: this.onKeyPress 90 }); 91 }, 92 onBlur: function() { 93 this.fakeElement.removeClass(this.options.focusClass); 94 this.realElement.off({ 95 blur: this.onBlur, 96 keydown: this.onKeyPress 97 }); 98 }, 99 onKeyPress: function(e) { 100 if (e.which === 38 || e.which === 40) { 101 e.preventDefault(); 102 this.step(e.which === 38); 103 } 104 }, 105 step: function(increment) { 106 var originalValue = parseFloat(this.realElement.val()), 107 newValue = originalValue || 0, 108 addValue = this.stepValue * (increment ? 1 : -1), 109 edgeNumber = isFinite(this.minValue) ? this.minValue : this.initialValue - Math.abs(newValue * this.stepValue), 110 diff = Math.abs(edgeNumber - newValue) % this.stepValue; 111 112 // handle step diff 113 if (diff) { 114 if (increment) { 115 newValue += addValue - diff; 116 } else { 117 newValue -= diff; 118 } 119 } else { 120 newValue += addValue; 121 } 122 123 // handle min/max limits 124 if (newValue < this.minValue) { 125 newValue = this.minValue; 126 } else if (newValue > this.maxValue) { 127 newValue = this.maxValue; 128 } 129 130 // update value in real input if its changed 131 if (newValue !== originalValue) { 132 //this.realElement.val(newValue).trigger('change'); 133 this.realElement.val(newValue).change(); 134 this.refresh(); 135 } 136 }, 137 refresh: function() { 138 var isDisabled = this.realElement.is(':disabled'), 139 currentValue = parseFloat(this.realElement.val()); 140 141 // handle disabled state 142 this.fakeElement.toggleClass(this.options.disabledClass, isDisabled); 143 144 // refresh button classes 145 this.btnDec.toggleClass(this.options.disabledClass, currentValue === this.minValue); 146 this.btnInc.toggleClass(this.options.disabledClass, currentValue === this.maxValue); 147 }, 148 destroy: function() { 149 // restore original structure 150 this.realElement.removeClass(this.options.realElementClass).insertBefore(this.fakeElement); 151 this.fakeElement.remove(); 152 clearInterval(this.stepTimer); 153 154 // remove event handlers 155 this.page.off('jcf-pointerup', this.onBtnRelease); 156 this.realElement.off({ 157 keydown: this.onKeyPress, 158 focus: this.onFocus, 159 blur: this.onBlur 160 }); 161 } 162 }; 163}); 164 165}(jcf));
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.