Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | espaco | 1 | /* |
| 2 | * Fuel UX Spinner |
||
| 3 | * https://github.com/ExactTarget/fuelux |
||
| 4 | * |
||
| 5 | * Copyright (c) 2012 ExactTarget |
||
| 6 | * Licensed under the MIT license. |
||
| 7 | */ |
||
| 8 | |||
| 9 | !function ($) { |
||
| 10 | // SPINNER CONSTRUCTOR AND PROTOTYPE |
||
| 11 | |||
| 12 | var Spinner = function (element, options) { |
||
| 13 | this.$element = $(element); |
||
| 14 | this.options = $.extend({}, $.fn.spinner.defaults, options); |
||
| 15 | this.$input = this.$element.find('.spinner-input'); |
||
| 16 | this.$element.on('keyup', this.$input, $.proxy(this.change, this)); |
||
| 17 | |||
| 18 | if (this.options.hold) { |
||
| 19 | this.$element.on('mousedown', '.spinner-up', $.proxy(function() { this.startSpin(true); } , this)); |
||
| 20 | this.$element.on('mouseup', '.spinner-up, .spinner-down', $.proxy(this.stopSpin, this)); |
||
| 21 | this.$element.on('mouseout', '.spinner-up, .spinner-down', $.proxy(this.stopSpin, this)); |
||
| 22 | this.$element.on('mousedown', '.spinner-down', $.proxy(function() {this.startSpin(false);} , this)); |
||
| 23 | } else { |
||
| 24 | this.$element.on('click', '.spinner-up', $.proxy(function() { this.step(true); } , this)); |
||
| 25 | this.$element.on('click', '.spinner-down', $.proxy(function() { this.step(false); }, this)); |
||
| 26 | } |
||
| 27 | |||
| 28 | this.switches = { |
||
| 29 | count: 1, |
||
| 30 | enabled: true |
||
| 31 | }; |
||
| 32 | |||
| 33 | if (this.options.speed === 'medium') { |
||
| 34 | this.switches.speed = 300; |
||
| 35 | } else if (this.options.speed === 'fast') { |
||
| 36 | this.switches.speed = 100; |
||
| 37 | } else { |
||
| 38 | this.switches.speed = 500; |
||
| 39 | } |
||
| 40 | |||
| 41 | this.lastValue = null; |
||
| 42 | |||
| 43 | this.render(); |
||
| 44 | |||
| 45 | if (this.options.disabled) { |
||
| 46 | this.disable(); |
||
| 47 | } |
||
| 48 | }; |
||
| 49 | |||
| 50 | Spinner.prototype = { |
||
| 51 | constructor: Spinner, |
||
| 52 | |||
| 53 | render: function () { |
||
| 54 | var inputValue = this.$input.val(); |
||
| 55 | |||
| 56 | if (inputValue) { |
||
| 57 | this.value(inputValue); |
||
| 58 | } else { |
||
| 59 | this.$input.val(this.options.value); |
||
| 60 | } |
||
| 61 | |||
| 62 | this.$input.attr('maxlength', (this.options.max + '').split('').length); |
||
| 63 | }, |
||
| 64 | |||
| 65 | change: function () { |
||
| 66 | var newVal = this.$input.val(); |
||
| 67 | |||
| 68 | if(newVal/1){ |
||
| 69 | this.options.value = newVal/1; |
||
| 70 | }else{ |
||
| 71 | newVal = newVal.replace(/[^0-9]/g,''); |
||
| 72 | this.$input.val(newVal); |
||
| 73 | this.options.value = newVal/1; |
||
| 74 | } |
||
| 75 | |||
| 76 | this.triggerChangedEvent(); |
||
| 77 | }, |
||
| 78 | |||
| 79 | stopSpin: function () { |
||
| 80 | clearTimeout(this.switches.timeout); |
||
| 81 | this.switches.count = 1; |
||
| 82 | this.triggerChangedEvent(); |
||
| 83 | }, |
||
| 84 | |||
| 85 | triggerChangedEvent: function () { |
||
| 86 | var currentValue = this.value(); |
||
| 87 | if (currentValue === this.lastValue) return; |
||
| 88 | |||
| 89 | this.lastValue = currentValue; |
||
| 90 | |||
| 91 | // Primary changed event |
||
| 92 | this.$element.trigger('changed', currentValue); |
||
| 93 | |||
| 94 | // Undocumented, kept for backward compatibility |
||
| 95 | this.$element.trigger('change'); |
||
| 96 | }, |
||
| 97 | |||
| 98 | startSpin: function (type) { |
||
| 99 | |||
| 100 | if (!this.options.disabled) { |
||
| 101 | var divisor = this.switches.count; |
||
| 102 | |||
| 103 | if (divisor === 1) { |
||
| 104 | this.step(type); |
||
| 105 | divisor = 1; |
||
| 106 | } else if (divisor < 3){ |
||
| 107 | divisor = 1.5; |
||
| 108 | } else if (divisor < 8){ |
||
| 109 | divisor = 2.5; |
||
| 110 | } else { |
||
| 111 | divisor = 4; |
||
| 112 | } |
||
| 113 | |||
| 114 | this.switches.timeout = setTimeout($.proxy(function() {this.iterator(type);} ,this),this.switches.speed/divisor); |
||
| 115 | this.switches.count++; |
||
| 116 | } |
||
| 117 | }, |
||
| 118 | |||
| 119 | iterator: function (type) { |
||
| 120 | this.step(type); |
||
| 121 | this.startSpin(type); |
||
| 122 | }, |
||
| 123 | |||
| 124 | step: function (dir) { |
||
| 125 | var curValue = this.options.value; |
||
| 126 | var limValue = dir ? this.options.max : this.options.min; |
||
| 127 | |||
| 128 | if ((dir ? curValue < limValue : curValue > limValue)) { |
||
| 129 | var newVal = curValue + (dir ? 1 : -1) * this.options.step; |
||
| 130 | |||
| 131 | if (dir ? newVal > limValue : newVal < limValue) { |
||
| 132 | this.value(limValue); |
||
| 133 | } else { |
||
| 134 | this.value(newVal); |
||
| 135 | } |
||
| 136 | } else if (this.options.cycle) { |
||
| 137 | var cycleVal = dir ? this.options.min : this.options.max; |
||
| 138 | this.value(cycleVal); |
||
| 139 | } |
||
| 140 | }, |
||
| 141 | |||
| 142 | value: function (value) { |
||
| 143 | if (!isNaN(parseFloat(value)) && isFinite(value)) { |
||
| 144 | value = parseFloat(value); |
||
| 145 | this.options.value = value; |
||
| 146 | this.$input.val(value); |
||
| 147 | return this; |
||
| 148 | } else { |
||
| 149 | return this.options.value; |
||
| 150 | } |
||
| 151 | }, |
||
| 152 | |||
| 153 | disable: function () { |
||
| 154 | this.options.disabled = true; |
||
| 155 | this.$input.attr('disabled',''); |
||
| 156 | this.$element.find('button').addClass('disabled'); |
||
| 157 | }, |
||
| 158 | |||
| 159 | enable: function () { |
||
| 160 | this.options.disabled = false; |
||
| 161 | this.$input.removeAttr("disabled"); |
||
| 162 | this.$element.find('button').removeClass('disabled'); |
||
| 163 | } |
||
| 164 | }; |
||
| 165 | |||
| 166 | |||
| 167 | // SPINNER PLUGIN DEFINITION |
||
| 168 | |||
| 169 | $.fn.spinner = function (option,value) { |
||
| 170 | var methodReturn; |
||
| 171 | |||
| 172 | var $set = this.each(function () { |
||
| 173 | var $this = $(this); |
||
| 174 | var data = $this.data('spinner'); |
||
| 175 | var options = typeof option === 'object' && option; |
||
| 176 | |||
| 177 | if (!data) $this.data('spinner', (data = new Spinner(this, options))); |
||
| 178 | if (typeof option === 'string') methodReturn = data[option](value); |
||
| 179 | }); |
||
| 180 | |||
| 181 | return (methodReturn === undefined) ? $set : methodReturn; |
||
| 182 | }; |
||
| 183 | |||
| 184 | $.fn.spinner.defaults = { |
||
| 185 | value: 1, |
||
| 186 | min: 1, |
||
| 187 | max: 999, |
||
| 188 | step: 1, |
||
| 189 | hold: true, |
||
| 190 | speed: 'medium', |
||
| 191 | disabled: false |
||
| 192 | }; |
||
| 193 | |||
| 194 | $.fn.spinner.Constructor = Spinner; |
||
| 195 | |||
| 196 | |||
| 197 | // SPINNER DATA-API |
||
| 198 | |||
| 199 | $(function () { |
||
| 200 | $('body').on('mousedown.spinner.data-api', '.spinner', function () { |
||
| 201 | var $this = $(this); |
||
| 202 | if ($this.data('spinner')) return; |
||
| 203 | $this.spinner($this.data()); |
||
| 204 | }); |
||
| 205 | }); |
||
| 206 | |||
| 207 | }(window.jQuery); |