Files
2026-04-19 01:39:41 +08:00

513 lines
13 KiB
JavaScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function($){
$.fn.numberField = function(opts){
return $(this).each(function(){
if(this.tagName.toLowerCase() != 'input'){return ;}
if( typeof(opts) == 'string' ){
var instance = $(this).data('_numberField');
if( !instance ){return ;}
var args = Array.prototype.slice.call( arguments, 1 );
if( typeof(instance[opts]) === 'function' ){
instance[opts].apply(instance, args);
}
}
else {
var instance = $(this).data('_numberField');
if( instance ){return ;}
instance = new $.NumberField($(this),opts);
$(this).data('_numberField', instance);
}
});
}
$.NumberField = function(obj, opts){
this.input = obj;
this.opts = $.extend(true, {}, $.NumberField.defaults, opts);
this._init();
}
$.fn.getNumberField = function(){
return $.NumberField.getNumberField(this);
}
$.NumberField.getNumberField = function(obj){
obj = $(obj)
if(obj.length == 0) {
return ;
} else if (obj.length == 1){
return obj.data('_numberField');
} else if ( obj.length > 1) {
var array = [];
obj.each(function(idx){
array.push(this.data('_numberField'));
})
return array;
}
}
$.NumberField.prototype = {
constructor: $.NumberField,
_init: function(){
var opts = this.opts, min = parseFloat(opts.min), max = parseFloat(opts.max),
step = parseFloat(opts.step), precision = parseInt(opts.precision);
this.min = !isNaN(min) ? min : Number.NEGATIVE_INFINITY;
this.max = !isNaN(max) ? max : Number.MAX_VALUE;
this.step = !isNaN(step) ? step : 1;
this.precision = isNaN(precision) || !opts.decimal || precision < 0 ? 0 : precision;
this.allowedReg = this._getAllowedReg();
this.input.css('ime-mode', 'disabled');
this._initVal();
this._initDisabled();
this._bindEvent();
},
_getAllowedReg: function(){
var opts = this.opts, allowed = '0123456789', reg;
if(opts.decimal){
allowed += '.';
}
if(this.min < 0){
allowed += '-';
}
allowed = allowed.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
reg = new RegExp('[' + allowed + ']');
return reg;
},
_initVal: function(){
var val = this._getProcessedVal(this.opts.value);
if(val === false){
val = this._getProcessedVal(this.input.val());
if(val === false){
val = '';
}
}
this._val = this.originVal = val;
this.input.val(val);
},
_initDisabled: function(){
var opts = this.opts;
this._disabled = opts.disabled === true ? true : opts.disabled === false ? false : !!this.input.attr('disabled');
this.originDisabled = this._disabled;
this._handleDisabled(this._disabled);
},
_bindEvent: function(){
var self = this, opts = self.opts;
var KEYS = {
'up': 38,
'down': 40
}
//var mouseWheel = $.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel';
var mouseWheel = 'mousewheel';
this.input.on('keydown', function(e){
var which = e.which;
if( which == KEYS.up || which == KEYS.down ){
if( !opts.keyEnable ){ return ;}
var operator = which == KEYS.up ? 'plus' : 'minus';
self._handleAdjusting(operator);
e.preventDefault();
}
})
.on('keypress', function(e){
var charCode = typeof e.charCode != 'undefined' ? e.charCode : e.keyCode;
var keyChar = $.trim(String.fromCharCode(charCode));
if(charCode != 0 && !self.allowedReg.test(keyChar)){
e.preventDefault();
}
})
.on('keyup', function(e){
self._clearAutoRepeat();
})
.on('focus', function(e){
self.focus = true;
//self.wrap.addClass(opts.activeCls);
})
.on('blur', function(e){
self.focus = false;
//self.wrap.removeClass(opts.activeCls);
var val = $.trim(self.input.val());
//alert('blur')
//self._clearAutoRepeat();
if(val === self._val){return ;}
if(!self.setValue(val)){
self.input.val(self._val);
}
})
.on(mouseWheel,function(e){
e.preventDefault();
if (!self.focus || !opts.wheelEnable) {return ;}
e = e.originalEvent;
var delta = e.wheelDelta ? (e.wheelDelta / 120) : (- e.detail / 3);
var operator = delta == 1 ? 'plus' : 'minus';
var val = self.input.val();
if(val !== self._val && !self.setValue(val)){
self.input.val(this._val);
}
self._adjustVal(operator);
});
},
/**
*对原始值进行处理
*@return {false || string || number} 原始值为空返回''为NaN返回false为number返回处理好的数字
*/
_getProcessedVal: function(val){
if(typeof val == 'string' && $.trim(val) === '') {return '';}
val = parseFloat(val);
if(isNaN(val)){return false;}
val = val > this.max ? this.max : val < this.min ? this.min : val;
val = val.toFixed(this.precision);
if (!this.opts.forceDecimal) {
val = parseFloat(val);
}
return val;
},
enable: function(){
this._handleDisabled(false);
},
disable: function(){
this._handleDisabled(true);
},
_handleDisabled: function(disabled){
var opts = this.opts;
disabled === true ? this.input.addClass(opts.inputDisabledCls) : this.input.removeClass(opts.inputDisabledCls);
this._disabled = disabled;
this.input.attr('disabled', disabled);
},
/**
*有微调发生时,对微调进行处理
*/
_handleAdjusting: function(operator){
var val = this.input.val();
if(val !== this._val && !this.setValue(val)){
this.input.val(this._val);
}
//已经到达最大值,最小值时
if( (this._val === this.max && operator == 'plus') || (this._val === this.min && operator == 'minus') ){
return ;
}
if(this.opts.autoRepeat){
this._clearAutoRepeat();
this._setAutoRepeat(operator);
}
this._adjustVal(operator);
},
/**
*微调值
*/
_adjustVal: function(operator){
//已经到达最大值,最小值时
if( (this._val === this.max && operator == 'plus') || (this._val === this.min && operator == 'minus') ){
this._clearAutoRepeat();
return ;
}
var baseVal = this._val !== '' ? this._val : this.min < 0 && this.min > Number.NEGATIVE_INFINITY ? this.min : 0;
var val = operator == 'plus' ? baseVal + this.step : baseVal - this.step;
this.setValue(val);
},
_setAutoRepeat: function(operator){
var opts = this.opts, self = this;
self.autoTimer = window.setTimeout(function(){
self.autoRepeater = window.setInterval(function(){
self._adjustVal(operator);
}, opts.interval);
},opts.delay);
},
_clearAutoRepeat: function(){
if(this.autoTimer){
window.clearTimeout(this.autoTimer);
}
if(this.autoRepeater){
window.clearTimeout(this.autoRepeater);
}
},
setValue: function(val){
var opts = this.opts;
if(this._disabled){return ;}
val = this._getProcessedVal(val);
if(val === false){return ;}
this.input.val(val);
this._val = val;
return true;
}
}
$.NumberField.defaults = {
value: undefined,
max: undefined,
min: undefined,
step: 1,
decimal: false,
precision: 2,
disabled: undefined,
keyEnable: false,
wheelEnable: false,
autoRepeat: true,
delay: 400,
interval: 80,
inputCls: 'ui-input',
inputDisabledCls: 'ui-input-disabled'
}
})(jQuery);
/**
*Spinbox插件 扩展自 NumberField
*带微调按钮的数字输入框
*/
(function($){
$.fn.spinbox = function(opts){
return $(this).each(function(){
if( typeof(opts) == 'string' ){
var instance = $(this).data('_spinbox');
if( !instance ){return ;}
var args = Array.prototype.slice.call( arguments, 1 );
if( typeof(instance[opts]) === 'function' ){
instance[opts].apply(instance, args);
}
}
else {
var instance = $(this).data('_spinbox');
if( instance ){return ;}
instance = new $.Spinbox($(this),opts);
$(this).data('_spinbox', instance);
}
});
}
$.fn.getSpinbox = function(){
return $.Spinbox.getSpinbox(this);
}
$.Spinbox = function(obj, opts){
this.obj = obj;
this.opts = $.extend(true, {}, $.Spinbox.defaults, opts);
this._init();
}
$.Spinbox.getSpinbox = function(obj){
obj = $(obj)
if(obj.length == 0) {
return ;
} else if (obj.length == 1){
return obj.data('_spinbox');
} else if ( obj.length > 1) {
var array = [];
obj.each(function(idx){
array.push(this.data('_spinbox'));
})
return array;
}
}
$.Spinbox.prototype = {
constructor: $.Spinbox,
_init: function(){
this._createStruture();
this._initDisabled();
this._bindEvent();
},
_createStruture: function(){
var opts = this.opts, nextSibling, w = parseInt(opts.width), inputW;
if( this.obj[0].tagName.toLowerCase() == 'input' ) {
this.input = this.obj;
this.obj = this.obj.parent();
nextSibling = this.input.next().length == 0 ? null : this.input.next();
} else {
this.input = $('<input type="text" />');
}
this.input.attr('autocomplete', 'off').addClass(opts.inputCls).numberField(opts);
this.numberField = this.input.data('_numberField');
this.downBtn = $('<a />').addClass(opts.downBtnCls);
this.upBtn = $('<a />').addClass(opts.upBtnCls);
this.btnWrap = $('<span />').addClass(opts.btnWrapCls).append(this.upBtn,this.downBtn);
this.btns = this.btnWrap.children();
this.wrap = $('<span />').addClass(opts.wrapCls).append(this.input, this.btnWrap);
if(nextSibling){
this.wrap.insertBefore(nextSibling);
} else {
this.wrap.appendTo(this.obj);
}
if(w){
this.wrap.width(w);
inputW = w - this.btnWrap.outerWidth() - (this.input.outerWidth() - this.input.width());
this.input.width(inputW);
}
},
_initDisabled: function(){
var opts = this.opts;
this._disabled = opts.disabled === true ? true : opts.disabled === false ? false : undefined;
if(this._disabled === undefined){
this._disabled = !!this.input.attr('disabled');
}
this.defaultDisabled = this._disabled;
if(this._disabled === true){
this.disable();
}
},
_bindEvent: function(){
var self = this, opts = this.opts;
this.wrap.on('mouseover', function(e){
if(self._disabled){return ;}
self.wrap.addClass(opts.hoverCls);
}).on('mouseleave', function(e){
if(self._disabled){return ;}
self.wrap.removeClass(opts.hoverCls);
});
this.btnWrap.on('mouseover', function(e){
if(self._disabled){return ;}
$(this).addClass(opts.btnWrapHoverCls);
}).on('mouseleave', function(e){
if(self._disabled){return ;}
$(this).removeClass(opts.btnWrapHoverCls);
});
//IE下需处理dblClick事件,IE9以下dblClick只执行一次click事件
//var clickEvent = $.browser.msie && parseInt($.browser.version) < 9 ? 'mousedown dblclick' : 'mousedown';
var clickEvent = 'mousedown';
this.btns.on(clickEvent, function(e){
if(self._disabled){ return ;}
var operator = $(this)[0] == self.upBtn[0] ? 'plus' : 'minus';
self.input.focus();
if(e.type == 'mousedown'){
self.numberField._handleAdjusting(operator);
} else if(e.type == 'dblclick'){
self.numberField._adjustVal(operator);
}
e.preventDefault();
}).on('mouseup mouseleave', function(e){
self.numberField._clearAutoRepeat();
});
this.input.on('focus',function(e){
self.wrap.addClass(opts.activeCls);
}).on('blur', function(){
self.wrap.removeClass(opts.activeCls);
});
$(document).on('mousedown', function(e){
var target = e.target || e.srcElement;
if( $(target).closest(self.wrap).length == 0){
self.wrap.removeClass(opts.activeCls);
}
});
},
enable: function(){
this._handleDisabled(false);
},
disable: function(disabled){
disabled = typeof disabled == 'undefined' ? true : !!disabled;
this._handleDisabled(disabled);
},
_handleDisabled: function(disabled){
var opts = this.opts;
disabled === true ? this.wrap.addClass(opts.disabledCls) : this.wrap.removeClass(opts.disabledCls);
this._disabled = disabled;
this.numberField._handleDisabled(disabled);
},
getDisabled: function(){
return this._disabled;
},
getValue: function(){
this.numberField.getValue();
},
setValue: function(val){
return this.numberField.setValue(val);
}
}
$.Spinbox.defaults = $.extend(true, $.NumberField.defaults, {
/*min: undefined,
max: undefined,
step: 1, //每次增加的值
value: undefined,
width: undefined, //spinbox总宽
disabled: undefined,
keyEnable: true,
wheelEnable: true,
autoRepeat: true,
delay: 400,
interval: 50,*/
width: undefined,
wrapCls: 'ui-spinbox-wrap',
activeCls: 'ui-spinbox-active',
disabledCls: 'ui-spinbox-disabled',
hoverCls: 'ui-spinbox-hover',
inputCls: 'input-txt',
btnWrapCls: 'btn-wrap',
btnWrapHoverCls: 'btn-wrap-hover',
btnCls: 'btn',
downBtnCls: 'btn-down',
upBtnCls: 'btn-up'
})
})(jQuery);