UNPKG

nuijs

Version:

nui框架

396 lines (377 loc) 13.1 kB
/** * @func 数字输入 */ Nui.define(function(require){ var component = require('../core/component'); var util = require('../core/util'); return this.extend(component, { _options:{ /** * @func 整数长度 */ integer:4, /** * @func 小数长度 */ decimal:2, /** * @func 设置正数最大值 */ max:0, /** * @func 设置负数最小值 */ min:0, /** * @func 补零位数,值为负数则末尾不能有0 */ zeroize:0, /** * @func 是否允许值为0 */ zero:false, /** * @func 是否允许值为负数 */ minus:true, /** * @func 过滤输入的值 * @param {String} value 当前输入框内容 */ filter:null, /** * @func 输入时,当值改变时回调 * @param {Object} self 当前实例对象 * @param {String} value 当前输入框内容 * @param {Object} elem 当前输入框元素jQuery对象 */ onChange:null, /** * @func 失焦时回调 * @param {Object} self 当前实例对象 * @param {String} value 当前输入框内容 * @param {Object} elem 当前输入框元素jQuery对象 */ onBlur:null }, _event:function(){ var self = this, opts = self._options, count = 1; self._on('focus', self.target, function(e, elem){ self._default = self._dom.value; self._focus = true }) self._on('blur', self.target, function(e, elem){ self._focus = false; var val = self._filter(Nui.trim(elem.val())) elem.val(val) self._callback('Blur', [val, self.target]) }) self._on('keydown', self.target, function(e, elem){ var code = e.keyCode; self._focus = true; count = 1; //输入拦截 if( (!e.ctrlKey && !e.altKey && $.inArray(code, self._disCodes) !== -1) ){ return false } }) self._on('contextmenu', self.target, function(e, elem){ count = 1 }) var change = function(){ if(count === 1 && self._default !== Nui.trim(self._dom.value)){ self._change(true) } } //解决IE8-propertychange事件间歇性失效问题 self._on('keyup', self.target, function(e, elem){ change() }) //解决部分浏览器剪切或者粘帖时不触发input或者propertychange事件 //因为剪切粘帖事件会优先执行,因此加定时器延后执行 self._on('paste cut', self.target, function(e, elem){ setTimeout(function(){ change() }) }) self._on('propertychange', self.target, function(e, elem){ count++; //self._focus防止IE8-赋值时执行 //self._bsie解决IE8-赋值死循环问题(赋值时会触发propertychange事件) if(self._focus && !self._bsie){ self._bsie = true self._change() self._bsie = false } }) self._on('input', self.target, function(e, elem){ count++; self._change() }) }, _exec:function(){ if(this._getTarget()){ this._initData() this._event() } }, _initData:function(){ var self = this, opts = self._options; self._dom = self.target[0]; self._default = self._dom.value; //禁用输入法(仅限IE) self._dom.style.imeMode = 'disabled'; self._integer = opts.integer|0; self._decimal = opts.decimal|0; self._max = self._min = ''; if(self._integer < 0){ self._integer = 0 } if(self._decimal < 0){ self._decimal = 0 } var integer = self._integer; var decimal = self._decimal; while(integer--){ self._max += '9' } if(self._decimal && self._max){ self._max += '.' while(decimal--){ self._max += '9' } } if(opts.max > 0){ self._max = opts.max.toString() } if(opts.minus && self._max){ self._min = '-' + self._max } if(opts.min < 0){ self._min = opts.min.toString() } self._diskey() }, /** * @func 设置禁止输入的按键 */ _diskey:function(){ var self = this, opts = self._options; var disCodes = [].concat( //括号斜杠引号 self._resolve(219, 222), //字母 self._resolve(65, 90), //一些可视负号 [186, 188, 192, 226] ) //加减 if(!opts.minus){ disCodes = disCodes.concat(107, 109, 189) } //小数点 if(!self._decimal){ disCodes = disCodes.concat(110, 190) } self._disCodes = disCodes; }, //设置临界值 _breakValue:function(val){ if(this._max > 0 && val > parseFloat(this._max)){ val = this._max } else if(this._min < 0 && val < parseFloat(this._min)){ val = this._min } return val }, /** * @func 分解按键代码 */ _resolve:function(start, end){ var codes = [] for(var i=start; i<=end; i++){ codes.push(i) } return codes }, /** * @func 输入时回调,会过滤掉特殊字符 */ _change:function(flag){ var self = this, len = arguments.length, opts = self._options, dom = self._dom, val = Nui.trim(dom.value); //负数 var minus = ''; //整数部分 var integer = ''; //小数部分 var decimal = ''; //字符数量 var length = val.length; //焦点位置 var index = util.getFocusIndex(dom); //转换半角符号以及过滤非数字减号加号小数点符号 val = self._convert(val).replace(/[^+*\-/=\d\.]+/g, ''); if(typeof opts.filter === 'function'){ var _val = opts.filter.call(opts, val); val = typeof _val === 'string' ? _val : val; } //存储负数符号 if(opts.minus && val.split('-').length % 2 === 0){ minus = '-' if(val.indexOf('+') !== -1){ minus = '' } } val = val.replace(/[+*\-/=]/g, ''); var temp = val.split('.'); integer = temp[0] || ''; if(self._integer){ integer = integer.substr(0, self._integer) } if(self._decimal && temp[1] !== undefined){ decimal = '.' + (temp[1] || '').substr(0, self._decimal) } val = self._breakValue(minus + integer + decimal); if(!flag){ dom.value = val } index += (val.length - length) if(self._default !== val){ self._callback('Change', [self._filter(val), self.target]) self._default = val } else{ return } //重新给输入框填充过滤后的值后,焦点会在最后,因此要重新将焦点移到操作部位 try{ dom.setSelectionRange(index, index); } catch(e){ clearTimeout(self._timer); self._timer = setTimeout(function(){ try{ if(self._focus){ var range = dom.createTextRange(); range.moveStart('character', index); range.moveEnd('character', -(val.length - index)); range.select() } } catch(e){ } }) } }, /** * @func 过滤最终值,比如将.1转为0.1 */ _filter:function(value){ var self = this, opts = self._options; if(!value){ return '' } value = value.replace(/^0+([^0]+)/, '$1') .replace(/^\./, '0.') .replace(/^\-\./, '-0.') .replace(/\.$/, '') if(!value || (!opts.zero && !parseFloat(value))){ return '' } value = self._breakValue(value); if(self._decimal){ var arr = value.split('.'); var integer = arr[0]; var decimal = (arr[1] || '').replace(/0+$/, ''); if(opts.zeroize > 0){ var count = opts.zeroize - decimal.length; while(count > 0){ decimal += '0'; count-- } } else if(opts.zeroize < 0){ decimal = decimal.replace(/0+$/, '') } if(decimal === ''){ value = integer } else{ value = integer + '.' + decimal } } return value }, /** * @func 输入时全角符号转换为半角符号 */ _convert:function(val){ var map = { '0':'0', '1':'1', '2':'2', '3':'3', '4':'4', '5':'5', '6':'6', '7':'7', '8':'8', '9':'9', '.':'.', '。':'.', '+':'+', '-':'-', '*':'*', '×':'*', '、':'/', '/':'/', '=':'=' } var str = []; for(var i in map){ str.push(i) } return val.replace(new RegExp(str.join('|'), 'g'), function(val){ return map[val] }) }, _delete:function(){ if(this.target){ this.target.css('ime-mode', 'normal') } delete this._focus; delete this._bsie; component.exports._delete.call(this); }, value:function(val){ var self = this, dom = self._dom, obj, _val = parseFloat(val); if(isNaN(_val)){ val = '' } else if(!_val){ val = 0 } if(dom && dom.nui){ Nui.each(dom.nui, function(v, k){ if(k !== name && typeof v.value === 'function' && v._setStyle && v._createRules){ obj = v; return false } }) } if(obj || dom){ val = self._filter(val.toString()) if(obj){ obj.value(val) } else if(dom){ dom.value = val } self._default = val } } }) })