123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
'use strict';
modulum('TimeEditWidget', ['TimeEditWidgetBase', 'WidgetFactory'],
function(context, cls) {
cls.TimeEditWidget = context.oo.Class(cls.TimeEditWidgetBase, function($super) {
return {
__name: 'TimeEditWidget',
_groups: null,
_currentCursors: null,
_numericPressed: false,
_upArrow: null,
_downArrow: null,
_currentGroup: 0,
_previousGroup: 0,
_lastValid: null,
_initElement: function() {
$super._initElement.call(this);
this._groups = [
cls.DateTimeHelper.timeFragment(24),
cls.DateTimeHelper.timeFragment(60),
cls.DateTimeHelper.timeFragment(60)
];
this._lastValid = '00:00:00';
this._inputElement = this._element.getElementsByTagName('input')[0];
this._upArrow = this._element.getElementsByClassName('up')[0];
this._downArrow = this._element.getElementsByClassName('down')[0];
this._inputElement.on('input.TimeEditWidget', this._onInput.bind(this));
this._inputElement.on('mousedown.TimeEditWidget', cls.WidgetBase._onSelect.bind(this));
this.setValue(this._lastValid);
this._currentCursors = {
start: 0,
end: 0
};
this._inputElement.on("change.TimeEditWidget", function(event) {
this._inputElement.setAttribute("data-time", this._inputElement.value);
}.bind(this));
},
destroy: function() {
this._currentCursors = null;
this._upArrow = null;
this._downArrow = null;
this._inputElement.off('change.TimeEditWidget');
this._inputElement.off('input.TimeEditWidget');
this._inputElement.off('mousedown.TimeEditWidget');
$super.destroy.call(this);
},
manageMouseClick: function(domEvent) {
var target = domEvent.target;
if (target.isElementOrChildOf(this._upArrow)) {
this._onUpIcon(domEvent);
} else if (target.isElementOrChildOf(this._downArrow)) {
this._onDownIcon(domEvent);
} else if (target.isElementOrChildOf(this._inputElement)) {
this._onInputClick(domEvent);
}
return true;
},
manageKeyDown: function(keyString, domKeyEvent, repeat) {
var keyProcessed = false;
if (this.isEnabled() && !this.isReadOnly()) {
var start = this._inputElement.selectionStart;
var end = this._inputElement.selectionEnd;
keyProcessed = true;
switch (keyString) {
case "down":
this._decrease();
this.emit(context.constants.widgetEvents.change, false, true);
break;
case "up":
this._increase();
this.emit(context.constants.widgetEvents.change, false, true);
break;
case this.getStart():
case this.getEnd():
this._updateCurrentGroup();
keyProcessed = false;
break;
case ":":
case "shift+:":
case "ctrl+" + this.getEnd():
this._moveGroup(1);
this._updateSelection();
break;
case "ctrl+" + this.getStart():
this._moveGroup(-1);
this._updateSelection();
break;
case "backspace":
if (!this.isEditing() && !this.hasFocus()) {
return true;
}
if ((start === 0 && this.getValue().length === end) || this.getValue().charAt(end - 1) !== ':') {
keyProcessed = false;
}
break;
case "del":
if (!this.isEditing() && !this.hasFocus()) {
return true;
}
if ((start === 0 && this.getValue().length === end) || this.getValue().charAt(end) !== ':' || start === end - 2) {
keyProcessed = false;
}
break;
default:
keyProcessed = this._processKey(domKeyEvent, keyString);
}
}
if (keyProcessed) {
return true;
} else {
return $super.manageKeyDown.call(this, keyString, domKeyEvent, repeat);
}
},
manageKeyUp: function(keyString, domKeyEvent) {
$super.manageKeyUp.call(this, keyString, domKeyEvent);
var key = cls.KeyboardApplicationService.keymap[domKeyEvent.which];
var groupChanged = (key === "del" || key === "backspace") ? false : this._updateCurrentGroup();
var groupComplete = true;
if (this._numericPressed) {
this._numericPressed = false;
groupComplete = this._updateGroups(this.getValue());
if (groupComplete) {
this._moveGroup(1);
this._updateSelection();
}
}
if (groupChanged || groupComplete) {
var autoNextAuthorized = !this._elementState.isRestored() && cls.KeyboardHelper.isNumeric(domKeyEvent.gbcKey) &&
this._groups.length * 2 + this._groups.length - 1 === this.getValue().length && this._previousGroup + 1 === this._groups.length;
this.emit(context.constants.widgetEvents.change, true, undefined, autoNextAuthorized);
}
},
_processKey: function(event, keyString) {
var isModifier = cls.KeyboardHelper.isSpecialCommand(keyString);
var isValid = !isModifier && cls.KeyboardHelper.isNumeric(event.gbcKey) && !this._isMaxLength();
this._numericPressed = isValid;
if (isValid && this.getValue().length === 0) {
this._updateFromGroups();
this._updateSelection();
}
if (!isValid && !isModifier) {
event.preventCancelableDefault();
this._elementState.setRestored(true);
return true;
}
return false;
},
_increase: function() {
this.setEditing(true);
if (this._groups[this._currentGroup].increaseValue()) {
if (this._currentGroup > 0 && this._groups[this._currentGroup - 1].increaseValue()) {
if (this._currentGroup > 1) {
this._groups[0].increaseValue();
}
}
}
this._updateFromGroups();
this._updateSelection();
},
_decrease: function() {
this.setEditing(true);
if (this._groups[this._currentGroup].decreaseValue()) {
if (this._currentGroup > 0 && this._groups[this._currentGroup - 1].decreaseValue()) {
if (this._currentGroup > 1) {
this._groups[0].decreaseValue();
}
}
}
this._updateFromGroups();
this._updateSelection();
},
_moveGroup: function(where) {
if (where < 0) {
if (this._currentGroup !== 0) {
this._previousGroup = this._currentGroup;
this._currentGroup = this._currentGroup + where;
}
} else {
if (this._currentGroup < this._groups.length - 1) {
this._previousGroup = this._currentGroup;
this._currentGroup = this._currentGroup + where;
}
}
},
_updateCurrentGroup: function() {
var value = this.getValue(),
firstColon = value.indexOf(':'),
secondColon = value.lastIndexOf(':');
var position = this._inputElement.selectionEnd;
var newPosition = 0;
var oldPosition = this._currentGroup;
if (secondColon !== -1) {
newPosition = position <= firstColon ? 0 : (firstColon === secondColon || position <= secondColon ? 1 : 2);
} else {
oldPosition = 0;
}
oldPosition = Math.min(this._currentGroup, oldPosition);
this._previousGroup = this._currentGroup;
this._currentGroup = newPosition;
var hasChanged = newPosition !== oldPosition;
if (hasChanged && !this._isGroupComplete(oldPosition)) {
this._updateFromGroups();
}
return hasChanged;
},
_isGroupComplete: function(groupIndex) {
var value = this.getValue().split(':');
return this._groups[groupIndex].fromText(value[groupIndex]);
},
_updateGroups: function(value, force) {
var complete = true;
if (!this._useSeconds && this._groups.length === 3) {
this._groups.pop();
}
for (var i = 0; i < this._groups.length; i++) {
complete = complete && this._isGroupComplete(i);
}
if (complete || force) {
this._updateFromGroups();
this._lastValid = this.getValue();
}
return complete;
},
_updateFromGroups: function() {
var value = '';
for (var i = 0; i < this._groups.length; i++) {
value += (i > 0 ? ':' : '') + this._groups[i].getText();
}
this.setValue(value);
},
_updateSelection: function() {
var start = this._currentGroup * 3;
if (start < 0) {
start = 0;
}
if (start + 2 <= this.getValue().length) {
this.setCursors(start, start + 2, true);
}
},
_onInputClick: function(event) {
if (this.isEnabled() && !this.isReadOnly() && this.getValue() !== '') {
this._updateCurrentGroup();
this._updateSelection();
}
this._onRequestFocus(event);
},
_onUpIcon: function(evt) {
if (this.isEnabled() && !this.isReadOnly()) {
this._onRequestFocus(evt);
if (this.hasVMFocus()) {
this._inputElement.domFocus();
}
this._increase();
this.emit(context.constants.widgetEvents.change, false, true);
}
},
_onDownIcon: function(evt) {
if (this.isEnabled() && !this.isReadOnly()) {
this._onRequestFocus(evt);
if (this.hasVMFocus()) {
this._inputElement.domFocus();
}
this._decrease();
this.emit(context.constants.widgetEvents.change, false, true);
}
},
getCursors: function() {
return this._currentCursors;
},
setCursors: function(cursor, cursor2, doNotUpdateGroup) {
var start = cursor;
var end = cursor2;
if (cursor2 === -1) {
start = 0;
end = 2;
} else if (!cursor2) {
end = start;
}
this._currentCursors.start = start;
this._currentCursors.end = end;
this._inputElement.setCursorPosition(start, end);
if (!doNotUpdateGroup) {
this._updateCurrentGroup();
}
if (!cursor2) {
this._updateSelection();
}
},
setDisplayFormat: function(format) {
$super.setDisplayFormat.call(this, format);
this._updateGroups(this.getValue());
},
setValue: function(value, fromVM) {
if (this.getValue() !== value) {
$super.setValue.call(this, value, fromVM);
this._updateGroups(value);
}
this._elementState.backup(this._inputElement);
},
setFocus: function(fromMouse) {
$super.setFocus.call(this, fromMouse);
var currentCursors = this.getCursors();
this.setCursors(currentCursors.start, currentCursors.end);
}
};
});
cls.WidgetFactory.registerBuilder('TimeEdit', cls.TimeEditWidget);
});