123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
'use strict';
modulum('ComboBoxWidget', ['ComboBoxWidgetBase', 'WidgetFactory'],
function(context, cls) {
cls.ComboBoxWidget = context.oo.Class(cls.ComboBoxWidgetBase, function($super) {
return {
__name: 'ComboBoxWidget',
__dataContentPlaceholderSelector: '.gbc_dataContentPlaceholder',
_editWidget: null,
_dropDown: null,
_typedLetters: "",
_typedLettersCacheHandler: null,
_focusHandler: null,
_editFocusHandler: null,
_dropDownSelectHandler: null,
_visibilityChangeHandler: null,
_toggleIcon: null,
_placeholderText: '',
_currentValue: "",
_lastVMValue: "",
_allowMultipleValues: false,
_initLayout: function() {
if (!this._ignoreLayout) {
this._layoutInformation = new cls.LayoutInformation(this);
this._layoutEngine = new cls.ComboBoxLayoutEngine(this);
this._layoutInformation.setReservedDecorationSpace(2);
this._layoutInformation.setSingleLineContentOnly(true);
}
},
_initElement: function() {
$super._initElement.call(this);
this._toggleIcon = this.getElement().querySelector("i.toggle");
this.setStyle('i.toggle', {
'min-width': window.scrollBarSize + 'px',
});
this._editWidget = cls.WidgetFactory.createWidget('EditWidget', this.getBuildParameters());
this._editWidget.setFocusable(false);
this._editWidget.setParentWidget(this);
this._element.prependChild(this._editWidget.getElement());
this._dropDown = cls.WidgetFactory.createWidget('ListDropDown', this.getBuildParameters());
this._dropDown.setParentWidget(this);
this._dropDown.fallbackMaxHeight = 300;
this._dropDown.hide();
this._dropDownSelectHandler = this._dropDown.when(context.constants.widgetEvents.select, this._onSelectValue.bind(this));
this._focusHandler = this.when(context.constants.widgetEvents.focus, this._onFocus.bind(this));
this._dropDown.onClose(this._onFocus.bind(this));
this._dropDown.onClose(this._onClose.bind(this));
this._editWidget._inputElement.on('blur.ComboBoxWidget', this._onBlur.bind(this));
this._editFocusHandler = this._editWidget.when(context.constants.widgetEvents.requestFocus,
this._onEditRequestFocus.bind(this));
this._visibilityChangeHandler = this._dropDown
.when(context.constants.widgetEvents.visibilityChange, this._updateEditState.bind(this));
this.setAriaAttribute("owns", this._dropDown.getRootClassName());
this.setAriaAttribute("labelledby", this._editWidget.getRootClassName());
},
destroy: function() {
if (this._focusHandler) {
this._focusHandler();
this._focusHandler = null;
}
if (this._editFocusHandler) {
this._editFocusHandler();
this._editFocusHandler = null;
}
if (this._dropDownSelectHandler) {
this._dropDownSelectHandler();
this._dropDownSelectHandler = null;
}
if (this._visibilityChangeHandler) {
this._visibilityChangeHandler();
this._visibilityChangeHandler = null;
}
this._editWidget._inputElement.off('blur.ComboBoxWidget');
if (this._dropDown) {
this._dropDown.destroy();
this._dropDown = null;
}
this._typedLettersCacheHandler = null;
this._editWidget.destroy();
this._editWidget = null;
$super.destroy.call(this);
},
setWidgetMode: function(mode, active) {
this._allowMultipleValues = mode === "Construct";
this._dropDown.allowMultipleChoices(this._allowMultipleValues);
this._updateEditState();
this._updateTextTransform();
},
canInputText: function() {
return $super.canInputText.call(this) && this._allowMultipleValues;
},
_getFormattedValue: function(value) {
var values = (value || "").split("|").map(function(itemValue) {
var found = this._dropDown.findByValue(itemValue);
return found && found.text || itemValue;
}.bind(this));
if (values[0] === "") {
values.splice(0, 1);
}
return values.join("|");
},
_onEditRequestFocus: function(event, sender, domEvent) {
this.emit(context.constants.widgetEvents.requestFocus, domEvent);
},
_updateEditValue: function() {
this._editWidget.setValue(this._getFormattedValue(this._currentValue));
},
_updateEditState: function() {
var readOnly = this._dropDown.isVisible() || !this.canInputText();
this._editWidget.setReadOnly(readOnly);
},
_onClose: function() {
this._toggleIcon.toggleClass("dd-open", this._dropDown.isVisible());
},
manageMouseClick: function(domEvent) {
this._onRequestFocus(domEvent);
if (this.isEnabled() && !(this._isQueryEditable && domEvent.target.tagName === 'INPUT')) {
this._dropDown.setCurrentValue(this.getValue());
this._dropDown.show();
this._toggleIcon.toggleClass("dd-open", this._dropDown.isVisible());
}
return true;
},
_onFocus: function() {
if (this._editWidget && this.isEnabled()) {
this._editWidget.getInputElement().domFocus();
}
},
_onBlur: function() {
if (!this._dropDown.isVisible()) {
this.emit(context.constants.widgetEvents.blur);
} else if (!this.hasFocus()) {
this._dropDown.hide();
}
},
_onSelectValue: function(event, src, value) {
this.setEditing(true);
this.setValue(value);
},
managePriorityKeyDown: function(keyString, domKeyEvent, repeat) {
var keyProcessed = false;
if (this._dropDown.isVisible()) {
keyProcessed = this._dropDown.managePriorityKeyDown(keyString, domKeyEvent, repeat);
}
if (keyProcessed) {
return true;
}
return $super.managePriorityKeyDown.call(this, keyString, domKeyEvent, repeat);
},
manageKeyDown: function(keyString, domKeyEvent, repeat) {
var keyProcessed = false;
if (this.isEnabled()) {
if (keyString === "alt+up" || keyString === "alt+down") {
this._dropDown.setCurrentValue(this.getValue());
}
keyProcessed = this._dropDown.managePriorityKeyDown(keyString, domKeyEvent, repeat);
if (!keyProcessed) {
keyProcessed = this._processKey(domKeyEvent, keyString);
}
}
if (keyProcessed) {
return true;
}
return $super.manageKeyDown.call(this, keyString, domKeyEvent, repeat);
},
_processKey: function(event, keyString) {
if (event.which <= 0) {
return false;
}
var key = event.gbcKey;
if (key.length > 1) {
return false;
}
if (this._typedLettersCacheHandler) {
this._clearTimeout(this._typedLettersCacheHandler);
this._typedLettersCacheHandler = 0;
}
if (!this._dropDown.isVisible()) {
if (this.canInputText()) {
return false;
}
}
var lastChar = key.toLocaleLowerCase();
this._typedLettersCacheHandler = this._registerTimeout(this._clearTypedLettersCache.bind(this), 400);
this._typedLetters += lastChar;
var found = this._dropDown.findStartingByText(this._typedLetters, this._typedLetters.length === 1);
if (!found) {
this._typedLetters = lastChar;
found = this._dropDown.findStartingByText(this._typedLetters, true);
}
if (found) {
this._dropDown.navigateToItem(found);
if (!this._dropDown.isVisible()) {
this.setEditing(this._oldValue !== found.value);
this.setValue(found.value);
}
return true;
}
return false;
},
_clearTypedLettersCache: function() {
this._typedLettersCacheHandler = 0;
this._typedLetters = "";
},
getValueAtPosition: function(pos) {
return this._dropDown.getValueAtPosition(pos);
},
getItems: function() {
return this._dropDown.getItems();
},
setChoices: function(choices) {
var list = choices;
if (!Array.isArray(choices)) {
list = choices ? [choices] : [];
}
this._dropDown.setItems(list);
if (this._dropDown.isVisible()) {
this._dropDown.setSelectedValues(this.getValue());
this._dropDown.setCurrentValue(this.getValue());
}
this._updateSelectedValue();
if (this._layoutEngine) {
this._layoutEngine.invalidateMeasure();
}
},
_updateSelectedValue: function() {
var selectedValue = this.isEditing() ? this._editWidget.getValue() : this._lastVMValue;
var foundInList = this._dropDown.findByText(selectedValue);
if (foundInList) {
this._currentValue = foundInList.text;
} else {
foundInList = this._dropDown.findByValue(selectedValue);
this._currentValue = foundInList && foundInList.value || "";
}
if (!foundInList) {
this._editWidget.setValue('');
} else {
this._editWidget.setValue(foundInList.text);
}
},
showDropDown: function() {
this.emit(context.constants.widgetEvents.requestFocus, null);
this._dropDown.setCurrentValue(this.getValue());
this._dropDown.show();
},
toggleDropDown: function() {
this._dropDown.setCurrentValue(this.getValue());
this._dropDown.toggle();
},
getDropDown: function() {
return this._dropDown;
},
getValue: function() {
var editValue = this.getEditValue(),
formattedValue = this._getFormattedValue(this._currentValue);
if (this._isQueryEditable && editValue && editValue !== formattedValue && editValue.trim().length > 0) {
var itemList = editValue.split("|").map(function(t) {
var item = this._dropDown.findByText(t, false);
return item ? item.value : t;
}.bind(this));
if (this._editWidget && itemList.length > 0 && this.canInputText()) {
this._currentValue = itemList.join("|");
this._editWidget.setValue(this._getFormattedValue(this._currentValue));
}
return this._currentValue || "";
}
return this.canInputText() && !this._dropDown.isVisible() &&
editValue !== formattedValue ? editValue : this._currentValue || "";
},
getClipboardValue: function() {
var value = this._dropDown.getCurrentValue();
var item = this._dropDown.findByValue(value);
return item ? item.text : value;
},
getEditValue: function() {
return this._editWidget && this._editWidget.getValue() || "";
},
setValue: function(value, fromVM) {
$super.setValue.call(this, value, fromVM);
if (this.hasFocus()) {
if (this._editWidget) {
this._editWidget.getInputElement().setSelectionRange(0, 0);
} else {
this._element.setSelectionRange(0, 0);
}
}
if (fromVM) {
if (this._editWidget) {
this._editWidget.setEditing(false);
}
this._lastVMValue = value;
}
this._setValue(value, fromVM);
},
_setValue: function(value, fromVM) {
var currentValue, valueChanged = false;
if (this._allowMultipleValues) {
if (this._dropDown.isVisible()) {
if (fromVM) {
this._currentValue = value;
this._updateEditValue();
} else {
var commandList = ["=", "<>", "!="];
var hasConstructCommand = commandList.findIndex(function(v) {
return v === value;
}) >= 0;
var values = this._currentValue === "" ||
(hasConstructCommand && this.getDialogType() === 'Construct' && this._currentValue !== "=") ? [] : this._currentValue.split(
"|");
var existingIndex = values.indexOf(value);
if (existingIndex >= 0) {
values.splice(existingIndex, 1);
} else {
values.push(value);
}
commandList.forEach((k) => {
var nullIndex = values.indexOf(k);
if (nullIndex >= 0 && values.length > 1) {
values.splice(nullIndex, 1);
}
});
values = this._dropDown.sortValues(values);
this._currentValue = values.join("|");
valueChanged = true;
this._updateEditValue();
}
this._dropDown.setSelectedValues(this._currentValue);
} else {
currentValue = this._currentValue || "";
if (currentValue !== value) {
this._currentValue = value;
this._dropDown.setCurrentValue(value);
this._updateEditValue();
valueChanged = true;
}
if (!fromVM && valueChanged) {
this.emit(context.constants.widgetEvents.change, false);
}
}
} else {
currentValue = this._currentValue || "";
if (currentValue !== value) {
var found = this._dropDown.findByValue(value);
this._currentValue = found && found.value || "";
this._dropDown.setCurrentValue(this._currentValue);
this._editWidget.setValue(found ? found.text : "");
valueChanged = true;
}
}
if (!fromVM && valueChanged) {
this.emit(context.constants.widgetEvents.change, false);
}
},
setFocus: function(fromMouse, stayOnSameWidget) {
$super.setFocus.call(this, fromMouse);
if (this._editWidget) {
var inputElement = this._editWidget.getInputElement();
inputElement.domFocus();
if (!stayOnSameWidget && inputElement.selectionStart !== inputElement.selectionEnd) {
inputElement.selectionStart = inputElement.selectionEnd = inputElement.value.length;
}
} else {
this._element.domFocus();
}
if (!stayOnSameWidget) {
if (this._allowMultipleValues) {
this._dropDown.clearCurrentIndex();
} else {
var currentValue = this._currentValue || "";
this._dropDown.setCurrentPosition(this._dropDown.indexByValue(currentValue));
}
}
},
setEnabled: function(enabled) {
$super.setEnabled.call(this, enabled);
this._editWidget.setEnabled(enabled);
this._updateEditState();
this._updateEditValue();
this._dropDown.setEnabled(enabled);
},
setQueryEditable: function(isQueryEditable) {
this._isQueryEditable = isQueryEditable;
this._dropDown.setQueryEditable(isQueryEditable);
this._updateEditState();
this._updateTextTransform();
},
setColor: function(color) {
$super.setColor.call(this, color);
this._editWidget.setColor(color);
if (this._dropDown) {
this._dropDown.setColor(color);
}
},
getColorFromStyle: function() {
return this._editWidget.getColorFromStyle();
},
setBackgroundColor: function(color) {
$super.setBackgroundColor.call(this, color);
if (this._dropDown) {
this._dropDown.setBackgroundColor(color);
}
},
setFontWeight: function(weight) {
$super.setFontWeight.call(this, weight);
this._editWidget.setFontWeight(weight);
if (this._dropDown) {
this._dropDown.setFontWeight(weight);
}
},
setFontFamily: function(fontFamily) {
$super.setFontFamily.call(this, fontFamily);
if (this._dropDown) {
this._dropDown.setFontFamily(fontFamily);
}
},
setFontStyle: function(style) {
$super.setFontStyle.call(this, style);
this._editWidget.setFontStyle(style);
if (this._dropDown) {
this._dropDown.setFontStyle(style);
}
},
setTextAlign: function(align) {
$super.setFontAlign.call(this, align);
this._editWidget.setTextAlign(align);
if (this._dropDown) {
this._dropDown.setTextAlign(align);
}
},
removeTextTransform: function() {
$super.removeTextTransform.call(this);
this._editWidget.removeTextTransform();
},
_updateTextTransform: function() {
var wantedTextTransform = this.canInputText() ? this._textTransform : "none";
if (wantedTextTransform !== this._editWidget.getTextTransform()) {
this._editWidget.removeTextTransform();
this._editWidget.setTextTransform(wantedTextTransform);
}
},
setTextDecoration: function(decoration) {
$super.setTextDecoration.call(this, decoration);
this._editWidget.setTextDecoration(decoration);
},
setNotNull: function(notNull) {
$super.setNotNull.call(this, notNull);
this._dropDown.setNotNull(notNull);
},
setPlaceHolder: function(placeholder) {
$super.setPlaceHolder.call(this, placeholder);
this._editWidget.setPlaceHolder(placeholder);
},
setDialogType: function(dialogType) {
$super.setDialogType.call(this, dialogType);
this._dropDown.updateUIList();
}
};
});
cls.WidgetFactory.registerBuilder('ComboBox', cls.ComboBoxWidget);
cls.WidgetFactory.registerBuilder('ComboBoxWidget', cls.ComboBoxWidget);
});