You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
316 lines
12 KiB
316 lines
12 KiB
/** |
|
* guy |
|
* @class BI.Input 一个button和一行数 组成的一行listitem |
|
* @extends BI.Single |
|
* @type {*|void|Object} |
|
*/ |
|
BI.Input = BI.inherit(BI.Single, { |
|
_defaultConfig: function () { |
|
var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); |
|
return BI.extend(conf, { |
|
baseCls: (conf.baseCls || "") + " bi-input display-block overflow-dot", |
|
tagName: "input", |
|
validationChecker: BI.emptyFn, |
|
quitChecker: BI.emptyFn, // 按确定键能否退出编辑 |
|
allowBlank: false |
|
}); |
|
}, |
|
|
|
_init: function () { |
|
BI.Input.superclass._init.apply(this, arguments); |
|
var self = this; |
|
var ctrlKey = false; |
|
var keyCode = null; |
|
var inputEventValid = false; |
|
var _keydown = BI.debounce(function (keyCode) { |
|
self.onKeyDown(keyCode, ctrlKey); |
|
self._keydown_ = false; |
|
}, 300); |
|
var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, { |
|
"leading": true, |
|
"trailing": false |
|
}); |
|
this._focusDebounce = BI.debounce(BI.bind(this._focus, this), BI.EVENT_RESPONSE_TIME, { |
|
"leading": true, |
|
"trailing": false |
|
}); |
|
this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, { |
|
"leading": true, |
|
"trailing": false |
|
}); |
|
this.element |
|
.keydown(function (e) { |
|
inputEventValid = false; |
|
ctrlKey = e.ctrlKey || e.metaKey; // mac的cmd支持一下 |
|
keyCode = e.keyCode; |
|
self.fireEvent(BI.Input.EVENT_QUICK_DOWN, arguments); |
|
}) |
|
.keyup(function (e) { |
|
keyCode = null; |
|
if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { |
|
self._keydown_ = true; |
|
_keydown(e.keyCode); |
|
} |
|
}) |
|
.on("input propertychange", function (e) { |
|
// 输入内容全选并直接删光,如果按键没放开就失去焦点不会触发keyup,被focusout覆盖了 |
|
// 其中propertychange在元素属性发生改变的时候就会触发 是为了兼容IE8 |
|
// 通过keyCode判断会漏掉输入法点击输入(右键粘贴暂缓) |
|
var originalEvent = e.originalEvent; |
|
if (BI.isNull(originalEvent.propertyName) || originalEvent.propertyName === "value") { |
|
inputEventValid = true; |
|
self._keydown_ = true; |
|
_keydown(keyCode); |
|
keyCode = null; |
|
} |
|
}) |
|
.click(function (e) { |
|
e.stopPropagation(); |
|
_clk(); |
|
}) |
|
.mousedown(function (e) { |
|
self.element.val(self.element.val()); |
|
}) |
|
.focus(function (e) { // 可以不用冒泡 |
|
self._focusDebounce(); |
|
}) |
|
.focusout(function (e) { |
|
self._blurDebounce(); |
|
}); |
|
if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { |
|
this.setValue(this.options.value); |
|
} |
|
}, |
|
|
|
_focus: function () { |
|
this.element.addClass("bi-input-focus"); |
|
this._checkValidationOnValueChange(); |
|
this._isEditing = true; |
|
if (this.getValue() == "") { |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_EMPTY); |
|
} |
|
this.fireEvent(BI.Input.EVENT_FOCUS); |
|
}, |
|
|
|
_blur: function () { |
|
var self = this; |
|
if (self._keydown_ === true) { |
|
BI.delay(blur, 300); |
|
} else { |
|
blur(); |
|
} |
|
|
|
function blur () { |
|
if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { |
|
self.element.val(self._lastValidValue ? self._lastValidValue : ""); |
|
self._checkValidationOnValueChange(); |
|
self._defaultState(); |
|
} |
|
self.element.removeClass("bi-input-focus"); |
|
self._isEditing = false; |
|
self._start = false; |
|
if (self.isValid()) { |
|
var lastValidValue = self._lastValidValue; |
|
self._lastValidValue = self.getValue(); |
|
self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); |
|
self.fireEvent(BI.Input.EVENT_CONFIRM); |
|
if (self._lastValidValue !== lastValidValue) { |
|
self.fireEvent(BI.Input.EVENT_CHANGE_CONFIRM); |
|
} |
|
} |
|
self.fireEvent(BI.Input.EVENT_BLUR); |
|
} |
|
}, |
|
|
|
_click: function () { |
|
if (this._isEditing !== true) { |
|
this.selectAll(); |
|
this.fireEvent(BI.Input.EVENT_CLICK); |
|
} |
|
}, |
|
|
|
onClick: function () { |
|
this._click(); |
|
}, |
|
|
|
onKeyDown: function (keyCode, ctrlKey) { |
|
if (!this.isValid() || BI.trim(this._lastChangedValue) !== BI.trim(this.getValue())) { |
|
this._checkValidationOnValueChange(); |
|
} |
|
if (this.isValid() && BI.trim(this.getValue()) !== "") { |
|
if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") |
|
|| (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { |
|
this._start = true; |
|
this._pause = false; |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_START); |
|
} |
|
} |
|
if (keyCode == BI.KeyCode.ENTER) { |
|
if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { |
|
this.blur(); |
|
this.fireEvent(BI.Input.EVENT_ENTER); |
|
} else { |
|
this.fireEvent(BI.Input.EVENT_RESTRICT); |
|
} |
|
} |
|
if (keyCode == BI.KeyCode.SPACE) { |
|
this.fireEvent(BI.Input.EVENT_SPACE); |
|
} |
|
if (keyCode == BI.KeyCode.BACKSPACE && this._lastValue == "") { |
|
this.fireEvent(BI.Input.EVENT_REMOVE); |
|
} |
|
if (keyCode == BI.KeyCode.BACKSPACE || keyCode == BI.KeyCode.DELETE) { |
|
this.fireEvent(BI.Input.EVENT_BACKSPACE); |
|
} |
|
this.fireEvent(BI.Input.EVENT_KEY_DOWN); |
|
|
|
// _valueChange中会更新_lastValue, 这边缓存用以后续STOP事件服务 |
|
var lastValue = this._lastValue; |
|
if(BI.trim(this.getValue()) !== BI.trim(this._lastValue || "")){ |
|
this._valueChange(); |
|
} |
|
if (BI.isEndWithBlank(this.getValue())) { |
|
this._pause = true; |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); |
|
this.fireEvent(BI.Input.EVENT_PAUSE); |
|
this._defaultState(); |
|
} else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && |
|
BI.trim(this.getValue()) === "" && (lastValue !== null && BI.trim(lastValue) !== "")) { |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_STOP); |
|
} |
|
}, |
|
|
|
// 初始状态 |
|
_defaultState: function () { |
|
if (this.getValue() == "") { |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_EMPTY); |
|
} |
|
this._lastValue = this.getValue(); |
|
this._lastSubmitValue = null; |
|
}, |
|
|
|
_valueChange: function () { |
|
if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_CHANGE); |
|
this._lastSubmitValue = BI.trim(this.getValue()); |
|
} |
|
if (this.getValue() == "") { |
|
this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); |
|
this.fireEvent(BI.Input.EVENT_EMPTY); |
|
} |
|
this._lastValue = this.getValue(); |
|
}, |
|
|
|
_checkValidationOnValueChange: function () { |
|
var o = this.options; |
|
var v = this.getValue(); |
|
this.setValid( |
|
(o.allowBlank === true && BI.trim(v) == "") || |
|
(BI.isNotEmptyString(BI.trim(v)) |
|
&& (v === this._lastChangedValue || |
|
o.validationChecker.apply(this, [BI.trim(v)]) !== false)) |
|
); |
|
}, |
|
|
|
focus: function () { |
|
if (!this.element.is(":visible")) { |
|
throw new Error("input输入框在不可见下不能focus"); |
|
} |
|
if (!this._isEditing === true) { |
|
this.element.focus(); |
|
this.selectAll(); |
|
} |
|
}, |
|
|
|
blur: function () { |
|
if (!this.element.is(":visible")) { |
|
throw new Error("input输入框在不可见下不能blur"); |
|
} |
|
if (this._isEditing === true) { |
|
this.element.blur(); |
|
this._blurDebounce(); |
|
} |
|
}, |
|
|
|
selectAll: function () { |
|
if (!this.element.is(":visible")) { |
|
throw new Error("input输入框在不可见下不能select"); |
|
} |
|
this.element.select(); |
|
this._isEditing = true; |
|
}, |
|
|
|
setValue: function (textValue) { |
|
this.element.val(textValue); |
|
BI.nextTick(BI.bind(function () { |
|
this._checkValidationOnValueChange(); |
|
this._defaultState(); |
|
if (this.isValid()) { |
|
this._lastValidValue = this._lastSubmitValue = this.getValue(); |
|
} |
|
}, this)); |
|
}, |
|
|
|
getValue: function () { |
|
return this.element.val() || ""; |
|
}, |
|
|
|
isEditing: function () { |
|
return this._isEditing; |
|
}, |
|
|
|
getLastValidValue: function () { |
|
return this._lastValidValue; |
|
}, |
|
|
|
getLastChangedValue: function () { |
|
return this._lastChangedValue; |
|
}, |
|
|
|
_setValid: function () { |
|
BI.Input.superclass._setValid.apply(this, arguments); |
|
if (this.isValid()) { |
|
this._lastChangedValue = this.getValue(); |
|
this.element.removeClass("bi-input-error"); |
|
this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); |
|
} else { |
|
if (this._lastChangedValue === this.getValue()) { |
|
this._lastChangedValue = null; |
|
} |
|
this.element.addClass("bi-input-error"); |
|
this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); |
|
} |
|
}, |
|
|
|
_setEnable: function (b) { |
|
BI.Input.superclass._setEnable.apply(this, [b]); |
|
this.element[0].disabled = !b; |
|
} |
|
}); |
|
BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; |
|
|
|
BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; |
|
BI.Input.EVENT_CLICK = "EVENT_CLICK"; |
|
BI.Input.EVENT_BLUR = "EVENT_BLUR"; |
|
BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; |
|
BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; |
|
BI.Input.EVENT_SPACE = "EVENT_SPACE"; |
|
BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; |
|
|
|
BI.Input.EVENT_START = "EVENT_START"; |
|
BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; |
|
BI.Input.EVENT_STOP = "EVENT_STOP"; |
|
BI.Input.EVENT_CHANGE_CONFIRM = "EVENT_CHANGE_CONFIRM"; |
|
BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; |
|
BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; |
|
BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; |
|
BI.Input.EVENT_VALID = "EVENT_VALID"; |
|
BI.Input.EVENT_ERROR = "EVENT_ERROR"; |
|
BI.Input.EVENT_ENTER = "EVENT_ENTER"; |
|
BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; |
|
BI.shortcut("bi.input", BI.Input);
|
|
|