devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
1,336 lines (1,157 loc) • 43.7 kB
JavaScript
"use strict";
var $ = require("../core/renderer"),
eventsEngine = require("../events/core/events_engine"),
window = require("../core/utils/window").getWindow(),
support = require("../core/utils/support"),
commonUtils = require("../core/utils/common"),
domUtils = require("../core/utils/dom"),
each = require("../core/utils/iterator").each,
extend = require("../core/utils/extend").extend,
inkRipple = require("./widget/utils.ink_ripple"),
messageLocalization = require("../localization/message"),
devices = require("../core/devices"),
registerComponent = require("../core/component_registrator"),
eventUtils = require("../events/utils"),
DropDownList = require("./drop_down_editor/ui.drop_down_list"),
themes = require("./themes"),
clickEvent = require("../events/click"),
Popover = require("./popover"),
TextBox = require("./text_box"),
ChildDefaultTemplate = require("./widget/child_default_template"),
translator = require("../animation/translator");
var LOOKUP_CLASS = "dx-lookup",
LOOKUP_SEARCH_CLASS = "dx-lookup-search",
LOOKUP_SEARCH_WRAPPER_CLASS = "dx-lookup-search-wrapper",
LOOKUP_FIELD_CLASS = "dx-lookup-field",
LOOKUP_ARROW_CLASS = "dx-lookup-arrow",
LOOKUP_FIELD_WRAPPER_CLASS = "dx-lookup-field-wrapper",
LOOKUP_POPUP_CLASS = "dx-lookup-popup",
LOOKUP_POPUP_WRAPPER_CLASS = "dx-lookup-popup-wrapper",
LOOKUP_POPUP_SEARCH_CLASS = "dx-lookup-popup-search",
LOOKUP_POPOVER_MODE = "dx-lookup-popover-mode",
LOOKUP_EMPTY_CLASS = "dx-lookup-empty",
LOOKUP_POPUP_VALIDATION_MESSAGE = "dx-lookup-validation-message",
LOOKUP_POPUP_INVALID_CLASS = "dx-lookup-invalid";
var POPUP_OPTION_MAP = {
"popupWidth": "width",
"popupHeight": "height"
};
var LIST_ITEM_SELECTED_CLASS = "dx-list-item-selected";
var MATERIAL_LOOKUP_LIST_ITEMS_COUNT = 4;
var MATERIAL_LOOKUP_LIST_PADDING = 8;
/**
* @name dxlookup
* @isEditor
* @publicName dxLookup
* @inherits dxDropDownList
* @module ui/lookup
* @export default
*/
var Lookup = DropDownList.inherit({
_supportedKeys: function _supportedKeys() {
return extend(this.callBase(), {
space: function space(e) {
e.preventDefault();
this._validatedOpening();
},
enter: function enter() {
this._validatedOpening();
}
});
},
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), {
/**
* @name dxLookupOptions.title
* @publicName title
* @type string
* @default ""
*/
title: "",
/**
* @name dxLookupOptions.titleTemplate
* @publicName titleTemplate
* @type template|function
* @default "title"
* @type_function_param1 titleElement:dxElement
* @type_function_return string|Node|jQuery
*/
titleTemplate: "title",
/**
* @name dxLookupOptions.onTitleRendered
* @publicName onTitleRendered
* @extends Action
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field4 titleElement:dxElement
* @action
*/
onTitleRendered: null,
/**
* @name dxLookupOptions.placeholder
* @publicName placeholder
* @type string
* @default "Select"
*/
placeholder: messageLocalization.format("Select"),
/**
* @name dxLookupOptions.searchPlaceholder
* @publicName searchPlaceholder
* @type string
* @default "Search"
*/
searchPlaceholder: messageLocalization.format("Search"),
/**
* @name dxLookupOptions.searchEnabled
* @publicName searchEnabled
* @type boolean
* @default true
*/
searchEnabled: true,
/**
* @name dxLookupOptions.cleanSearchOnOpening
* @publicName cleanSearchOnOpening
* @type boolean
* @default true
*/
cleanSearchOnOpening: true,
/**
* @name dxLookupOptions.fullScreen
* @publicName fullScreen
* @type boolean
* @default false
*/
fullScreen: false,
/**
* @name dxLookupOptions.showCancelButton
* @publicName showCancelButton
* @type boolean
* @default true
*/
showCancelButton: true,
/**
* @name dxLookupOptions.cancelButtonText
* @publicName cancelButtonText
* @type string
* @default "Cancel"
*/
/**
* @name dxLookupOptions.showClearButton
* @publicName showClearButton
* @type boolean
* @default false
*/
showClearButton: false,
/**
* @name dxLookupOptions.clearButtonText
* @publicName clearButtonText
* @type string
* @default "Clear"
*/
clearButtonText: messageLocalization.format("Clear"),
/**
* @name dxLookupOptions.applyButtonText
* @publicName applyButtonText
* @type string
* @default "Done"
*/
applyButtonText: messageLocalization.format("Done"),
/**
* @name dxLookupOptions.popupWidth
* @publicName popupWidth
* @type number|string|function
* @default function() {return $(window).width() * 0.8 }
* @type_function_return number|string
*/
popupWidth: function popupWidth() {
return $(window).width() * 0.8;
},
/**
* @name dxLookupOptions.popupHeight
* @publicName popupHeight
* @type number|string|function
* @default function() { return $(window).height() * 0.8 }
* @type_function_return number|string
*/
popupHeight: function popupHeight() {
return $(window).height() * 0.8;
},
/**
* @name dxLookupOptions.shading
* @publicName shading
* @type boolean
* @default true
*/
shading: true,
/**
* @name dxLookupOptions.closeOnOutsideClick
* @publicName closeOnOutsideClick
* @type boolean|function
* @default false
* @type_function_return boolean
*/
closeOnOutsideClick: false,
/**
* @name dxLookupOptions.position
* @publicName position
* @type positionConfig
* @default undefined
*/
position: undefined,
/**
* @name dxLookupOptions.animation
* @publicName animation
* @type object
* @default undefined
*/
animation: {
/**
* @name dxLookupOptions.animation.show
* @publicName show
* @type animationConfig
* @default undefined
*/
/**
* @name dxLookupOptions.animation.hide
* @publicName hide
* @type animationConfig
* @default undefined
*/
},
/**
* @name dxLookupOptions.pullRefreshEnabled
* @publicName pullRefreshEnabled
* @type boolean
* @default false
*/
pullRefreshEnabled: false,
/**
* @name dxLookupOptions.useNativeScrolling
* @publicName useNativeScrolling
* @type boolean
* @default true
*/
useNativeScrolling: true,
/**
* @name dxLookupOptions.pullingDownText
* @publicName pullingDownText
* @type string
* @default "Pull down to refresh..."
*/
pullingDownText: messageLocalization.format("dxList-pullingDownText"),
/**
* @name dxLookupOptions.pulledDownText
* @publicName pulledDownText
* @type string
* @default "Release to refresh..."
*/
pulledDownText: messageLocalization.format("dxList-pulledDownText"),
/**
* @name dxLookupOptions.refreshingText
* @publicName refreshingText
* @type string
* @default "Refreshing..."
*/
refreshingText: messageLocalization.format("dxList-refreshingText"),
/**
* @name dxLookupOptions.pageLoadingText
* @publicName pageLoadingText
* @type string
* @default "Loading..."
*/
pageLoadingText: messageLocalization.format("dxList-pageLoadingText"),
/**
* @name dxLookupOptions.onScroll
* @publicName onScroll
* @extends Action
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field4 jQueryEvent:jQuery.Event:deprecated(event)
* @type_function_param1_field5 event:event
* @type_function_param1_field6 scrollOffset:object
* @type_function_param1_field7 reachedLeft:boolean
* @type_function_param1_field8 reachedRight:boolean
* @type_function_param1_field9 reachedTop:boolean
* @type_function_param1_field10 reachedBottom:boolean
* @action
*/
onScroll: null,
/**
* @name dxLookupOptions.onPullRefresh
* @publicName onPullRefresh
* @extends Action
* @action
*/
onPullRefresh: null,
/**
* @name dxLookupOptions.onPageLoading
* @publicName onPageLoading
* @extends Action
* @action
*/
onPageLoading: null,
/**
* @name dxLookupOptions.pageLoadMode
* @publicName pageLoadMode
* @type Enums.ListPageLoadMode
* @default "scrollBottom"
*/
pageLoadMode: "scrollBottom",
/**
* @name dxLookupOptions.nextButtonText
* @publicName nextButtonText
* @type string
* @default "More"
*/
nextButtonText: messageLocalization.format("dxList-nextButtonText"),
/**
* @name dxLookupOptions.grouped
* @publicName grouped
* @type boolean
* @default false
*/
grouped: false,
/**
* @name dxLookupOptions.groupTemplate
* @publicName groupTemplate
* @type template|function
* @default "group"
* @type_function_param1 itemData:object
* @type_function_param2 itemIndex:number
* @type_function_param3 itemElement:dxElement
* @type_function_return string|Node|jQuery
*/
groupTemplate: "group",
/**
* @name dxLookupOptions.usePopover
* @publicName usePopover
* @type boolean
* @default false
*/
usePopover: false,
showDropDownButton: false,
/**
* @name dxLookupOptions.showPopupTitle
* @publicName showPopupTitle
* @type boolean
* @default true
*/
showPopupTitle: true,
/**
* @name dxLookupOptions.focusStateEnabled
* @publicName focusStateEnabled
* @type boolean
* @default false
* @inheritdoc
*/
focusStateEnabled: false,
/**
* @name dxLookupOptions.onValueChanged
* @publicName onValueChanged
* @extends Action
* @type function(e)
* @type_function_param1 e:object
* @type_function_param1_field4 value:object
* @type_function_param1_field5 previousValue:object
* @type_function_param1_field6 jQueryEvent:jQuery.Event:deprecated(event)
* @type_function_param1_field7 event:event
* @action
*/
/**
* @name dxLookupOptions.fieldTemplate
* @publicName fieldTemplate
* @type template|function
* @default null
* @type_function_param1 selectedItem:object
* @type_function_param2 fieldElement:dxElement
* @type_function_return string|Node|jQuery
*/
/**
* @name dxLookupOptions.acceptCustomValue
* @publicName acceptCustomValue
* @hidden
* @inheritdoc
*/
/**
* @name dxLookupOptions.readOnly
* @publicName readOnly
* @hidden
* @inheritdoc
*/
/**
* @name dxLookupOptions.onFocusIn
* @publicName onFocusIn
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onFocusOut
* @publicName onFocusOut
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onKeyDown
* @publicName onKeyDown
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onKeyPress
* @publicName onKeyPress
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onKeyUp
* @publicName onKeyUp
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onChange
* @publicName onChange
* @action
* @hidden
* @inheritdoc
*/
/**
* @name dxLookupOptions.onInput
* @publicName onInput
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onCut
* @publicName onCut
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onCopy
* @publicName onCopy
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onPaste
* @publicName onPaste
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.onEnterKey
* @publicName onEnterKey
* @hidden
* @action
* @inheritdoc
*/
/**
* @name dxLookupOptions.maxlength
* @publicName maxLength
* @hidden
* @inheritdoc
*/
/**
* @name dxLookupOptions.spellcheck
* @publicName spellcheck
* @hidden
* @inheritdoc
*/
/**
* @name dxLookupOptions.applyValueMode
* @publicName applyValueMode
* @type Enums.EditorApplyValueMode
* @hidden false
* @inheritdoc
*/
_scrollToSelectedItemEnabled: false
});
},
_defaultOptionsRules: function _defaultOptionsRules() {
return this.callBase().concat([{
device: function device() {
return !support.nativeScrolling;
},
options: {
/**
* @name dxLookupOptions.useNativeScrolling
* @publicName useNativeScrolling
* @default false @for desktop
* @default true @for Mac
*/
useNativeScrolling: false
}
}, {
device: function device(_device) {
return !devices.isSimulator() && devices.real().platform === "generic" && _device.platform === "generic";
},
options: {
/**
* @name dxLookupOptions.usePopover
* @publicName usePopover
* @default true @for desktop|iOS
*/
usePopover: true,
/**
* @name dxLookupOptions.popupHeight
* @publicName popupHeight
* @default 'auto' @for desktop|iPad
*/
popupHeight: "auto"
}
}, {
device: function device(_device2) {
return _device2.platform === "win" && _device2.phone && _device2.version && _device2.version[0] === 8;
},
options: {
/**
* @name dxLookupOptions.showCancelButton
* @publicName showCancelButton
*/
showCancelButton: false,
/**
* @name dxLookupOptions.fullScreen
* @publicName fullScreen
*/
fullScreen: true
}
}, {
device: function device(_device3) {
return _device3.platform === "win" && !_device3.phone && _device3.version && _device3.version[0] === 8;
},
options: {
popupWidth: function popupWidth() {
return $(window).width();
}
}
}, {
device: { platform: "ios", phone: true },
options: {
/**
* @name dxLookupOptions.fullScreen
* @publicName fullScreen
* @default true @for iPhone
*/
fullScreen: true
}
}, {
device: { platform: "ios", tablet: true },
options: {
/**
* @name dxLookupOptions.popupWidth
* @publicName popupWidth
* @default function() { return Math.min($(window).width(), $(window).height()) * 0.4; } @for iPad
*/
popupWidth: function popupWidth() {
return Math.min($(window).width(), $(window).height()) * 0.4;
},
popupHeight: "auto",
usePopover: true,
useInkRipple: false
}
}, {
device: function device() {
return devices.real().deviceType === "desktop" && !devices.isSimulator();
},
options: {
/**
* @name dxLookupOptions.focusStateEnabled
* @publicName focusStateEnabled
* @type boolean
* @default true @for desktop
* @inheritdoc
*/
focusStateEnabled: true
}
}, {
device: function device() {
return (/android5/.test(themes.current())
);
},
options: {
useInkRipple: true
}
}, {
device: function device() {
return themes.isMaterial();
},
options: {
/**
* @name dxLookupOptions.usePopover
* @publicName usePopover
* @type boolean
* @default false @for Material
*/
usePopover: false,
/**
* @name dxLookupOptions.closeOnOutsideClick
* @publicName closeOnOutsideClick
* @type boolean|function
* @default true @for Material
* @type_function_return boolean
*/
closeOnOutsideClick: true,
popupWidth: function () {
return $(this.element()).outerWidth();
}.bind(this),
popupHeight: function () {
return this._getPopupHeight(MATERIAL_LOOKUP_LIST_ITEMS_COUNT);
}.bind(this),
/**
* @name dxLookupOptions.searchEnabled
* @publicName searchEnabled
* @type boolean
* @default false @for Material
*/
searchEnabled: false,
/**
* @name dxLookupOptions.showCancelButton
* @publicName showCancelButton
* @type boolean
* @default false @for Material
*/
showCancelButton: false,
/**
* @name dxLookupOptions.showPopupTitle
* @publicName showPopupTitle
* @type boolean
* @default false @for Material
*/
showPopupTitle: false,
/**
* @name dxLookupOptions.position
* @publicName position
* @type positionConfig
* @default { my: 'left top', at: 'left top', of: lookupContainer } @for Material
*/
position: {
my: "left top",
at: "left top",
of: this.element()
},
_scrollToSelectedItemEnabled: true
}
}]);
},
_initTemplates: function _initTemplates() {
this.callBase();
this._defaultTemplates["group"] = new ChildDefaultTemplate("group", this);
this._defaultTemplates["title"] = new ChildDefaultTemplate("title", this);
},
_initMarkup: function _initMarkup() {
this.$element().addClass(LOOKUP_CLASS).toggleClass(LOOKUP_POPOVER_MODE, this.option("usePopover"));
this._renderSubmitElement();
this.callBase();
},
_inputWrapper: function _inputWrapper() {
return this.$element().find("." + LOOKUP_FIELD_WRAPPER_CLASS);
},
_renderSubmitElement: function _renderSubmitElement() {
this._$submitElement = $("<input>").attr("type", "hidden").appendTo(this.$element());
},
_dataSourceOptions: function _dataSourceOptions() {
return extend(this.callBase(), {
paginate: true
});
},
_getSubmitElement: function _getSubmitElement() {
return this._$submitElement;
},
_fireContentReadyAction: commonUtils.noop, // TODO: why not symmetric to other dropdowns?
_popupWrapperClass: function _popupWrapperClass() {
return "";
},
_renderInput: function _renderInput() {
var fieldClickAction = this._createAction(function () {
this._toggleOpenState();
}.bind(this));
this._$field = $("<div>").addClass(LOOKUP_FIELD_CLASS);
eventsEngine.on(this._$field, eventUtils.addNamespace(clickEvent.name, this.NAME), function (e) {
fieldClickAction({ event: e });
});
var $arrow = $("<div>").addClass(LOOKUP_ARROW_CLASS);
this._$fieldWrapper = $("<div>").addClass(LOOKUP_FIELD_WRAPPER_CLASS).append(this._$field).append($arrow).appendTo(this.$element());
this.option("useInkRipple") && this._renderInkRipple();
},
_renderInkRipple: function _renderInkRipple() {
this._inkRipple = inkRipple.render();
},
_toggleOpenState: function _toggleOpenState() {
this.callBase();
if (this.option("_scrollToSelectedItemEnabled")) {
this._setPopupPosition();
}
},
_toggleActiveState: function _toggleActiveState($element, value, e) {
this.callBase.apply(this, arguments);
if (!this._inkRipple) {
return;
}
var config = {
element: this._inputWrapper(),
event: e
};
if (value) {
this._inkRipple.showWave(config);
} else {
this._inkRipple.hideWave(config);
}
},
_renderField: function _renderField() {
var fieldTemplate = this._getTemplateByOption("fieldTemplate");
if (fieldTemplate && this.option("fieldTemplate")) {
this._renderFieldTemplate(fieldTemplate);
return;
}
this._$field.text(this.option("displayValue") || this.option("placeholder"));
this.$element().toggleClass(LOOKUP_EMPTY_CLASS, !this.option("selectedItem"));
},
_renderFieldTemplate: function _renderFieldTemplate(template) {
this._$field.empty();
var data = this._fieldRenderData();
template.render({
model: data,
container: domUtils.getPublicElement(this._$field)
});
},
_fieldRenderData: function _fieldRenderData() {
return this.option("selectedItem");
},
_popupShowingHandler: function _popupShowingHandler() {
var validationError;
if (this._$popupValidationMessage) {
validationError = this.option("validationError");
if (validationError && validationError.message) {
this._$popupValidationMessage.text(validationError.message);
this._popup.$content().addClass(LOOKUP_POPUP_INVALID_CLASS);
} else {
this._popup.$content().removeClass(LOOKUP_POPUP_INVALID_CLASS);
}
}
this.callBase.apply(this, arguments);
if (this.option("cleanSearchOnOpening")) {
if (this.option("searchEnabled") && this._searchBox.option("value")) {
this._searchBox.option("value", "");
this._searchCanceled();
}
this._list && this._list.option("focusedElement", null);
}
},
_scrollToSelectedItem: function _scrollToSelectedItem() {
var selectedIndex = this._list.option("selectedIndex"),
listItems = this._list.option("items"),
itemsCount = listItems.length;
if (itemsCount !== 0) {
if (this._list.option("grouped")) {
this._list.scrollToItem({ group: itemsCount - 1, item: listItems[itemsCount - 1].items.length - 1 });
} else {
this._list.scrollToItem(itemsCount - 1);
}
this._list.scrollToItem(selectedIndex);
}
},
_setPopupPosition: function _setPopupPosition() {
var selectedIndex = this._list.option("selectedIndex");
if (selectedIndex === -1) return;
var selectedListItem = $(this._list.element()).find("." + LIST_ITEM_SELECTED_CLASS),
differenceOfHeights = (selectedListItem.height() - $(this.element()).height()) / 2,
popupContentParent = $(this._popup.content()).parent(),
differenceOfOffsets = selectedListItem.offset().top - popupContentParent.offset().top,
lookupTop = $(this.element()).offset().top,
popupOffsetY = differenceOfHeights;
if (lookupTop > differenceOfOffsets) {
popupOffsetY += differenceOfOffsets;
} else {
this._scrollToSelectedItem();
}
var position = translator.locate(popupContentParent);
translator.move(popupContentParent, {
left: 0,
top: position.top - popupOffsetY
});
},
_getPopupHeight: function _getPopupHeight(listItemsCount) {
return this._list && this._list.itemElements() ? this._list.itemElements().height() * listItemsCount + MATERIAL_LOOKUP_LIST_PADDING * 2 : "auto";
},
_renderPopup: function _renderPopup() {
if (this.option("usePopover") && !this.option("fullScreen")) {
this._renderPopover();
} else {
this.callBase();
}
this._$popup.addClass(LOOKUP_POPUP_CLASS);
this._popup._wrapper().addClass(LOOKUP_POPUP_WRAPPER_CLASS);
},
_popupOptionMap: function _popupOptionMap(optionName) {
return POPUP_OPTION_MAP[optionName] || optionName;
},
_renderPopover: function _renderPopover() {
this._popup = this._createComponent(this._$popup, Popover, extend(this._popupConfig(), {
showEvent: null,
hideEvent: null,
target: this.$element(),
fullScreen: false,
shading: false,
closeOnTargetScroll: true,
width: this._isInitialOptionValue("popupWidth") ? function () {
return this.$element().outerWidth();
}.bind(this) : this._popupConfig().width
}));
this._popup.on({
"showing": this._popupShowingHandler.bind(this),
"shown": this._popupShownHandler.bind(this),
"hiding": this._popupHidingHandler.bind(this),
"hidden": this._popupHiddenHandler.bind(this)
});
this._popup.option("onContentReady", this._contentReadyHandler.bind(this));
this._contentReadyHandler();
},
_popupHidingHandler: function _popupHidingHandler() {
this.callBase();
this.option("focusStateEnabled") && this.focus();
},
_popupHiddenHandler: function _popupHiddenHandler() {
this.callBase();
if (this.option("_scrollToSelectedItemEnabled")) {
translator.resetPosition($(this._popup.content()).parent());
}
},
_preventFocusOnPopup: commonUtils.noop,
_popupConfig: function _popupConfig() {
var result = extend(this.callBase(), {
showTitle: this.option("showPopupTitle"),
title: this.option("title"),
titleTemplate: this._getTemplateByOption("titleTemplate"),
onTitleRendered: this.option("onTitleRendered"),
toolbarItems: this._getPopupToolbarItems(),
fullScreen: this.option("fullScreen"),
shading: this.option("shading"),
closeOnTargetScroll: false,
closeOnOutsideClick: this.option("closeOnOutsideClick"),
onPositioned: null
});
delete result.animation;
delete result.position;
result.maxHeight = function () {
return $(window).height();
};
each(["position", "animation", "popupWidth", "popupHeight"], function (_, optionName) {
if (this.option(optionName) !== undefined) {
result[this._popupOptionMap(optionName)] = this.option(optionName);
}
}.bind(this));
return result;
},
_getPopupToolbarItems: function _getPopupToolbarItems() {
var buttonsConfig = this.option("applyValueMode") === "useButtons" ? this._popupToolbarItemsConfig() : [];
var cancelButton = this._getCancelButtonConfig();
if (cancelButton) {
buttonsConfig.push(cancelButton);
}
var clearButton = this._getClearButtonConfig();
if (clearButton) {
buttonsConfig.push(clearButton);
}
return this._applyButtonsLocation(buttonsConfig);
},
_popupToolbarItemsConfig: function _popupToolbarItemsConfig() {
return [{
shortcut: "done",
options: {
onClick: this._applyButtonHandler.bind(this),
text: this.option("applyButtonText")
}
}];
},
_getCancelButtonConfig: function _getCancelButtonConfig() {
return this.option("showCancelButton") ? {
shortcut: "cancel",
onClick: this._cancelButtonHandler.bind(this),
options: { text: this.option("cancelButtonText") }
} : null;
},
_getClearButtonConfig: function _getClearButtonConfig() {
return this.option("showClearButton") ? {
shortcut: "clear",
onClick: this._resetValue.bind(this),
options: { text: this.option("clearButtonText") }
} : null;
},
_applyButtonHandler: function _applyButtonHandler() {
this.option("value", this._valueGetter(this._currentSelectedItem()));
this.callBase();
},
_cancelButtonHandler: function _cancelButtonHandler() {
this._refreshSelected();
this.callBase();
},
_refreshPopupVisibility: function _refreshPopupVisibility() {
if (this.option("opened")) {
this._updatePopupHeight();
}
},
_dimensionChanged: function _dimensionChanged() {
if (this.option("usePopover") && !this.option("popupWidth")) {
this.option("popupWidth", this.$element().width());
}
this.callBase();
},
_updatePopupDimensions: function _updatePopupDimensions() {
this._updatePopupHeight();
},
_input: function _input() {
return this._$searchBox || this.callBase();
},
_renderPopupContent: function _renderPopupContent() {
if (this._popup.NAME === "dxPopup") {
this._$popupValidationMessage = $("<div>").addClass(LOOKUP_POPUP_VALIDATION_MESSAGE).appendTo(this._popup.$content());
}
this.callBase();
this._renderSearch();
this._attachSearchChildProcessor();
},
_attachSearchChildProcessor: function _attachSearchChildProcessor() {
if (this.option("searchEnabled") && this._searchBox) {
this._listKeyboardProcessor = this._searchBox._keyboardProcessor.attachChildProcessor();
this._setListOption("_keyboardProcessor", this._listKeyboardProcessor);
} else {
this._setListOption("_keyboardProcessor", undefined);
}
},
_renderSearch: function _renderSearch() {
this._$searchWrapper && this._$searchWrapper.remove();
delete this._$searchWrapper;
this._$searchBox && this._$searchBox.remove();
delete this._$searchBox;
delete this._searchBox;
if (this.option("searchEnabled")) {
var $searchWrapper = this._$searchWrapper = $("<div>").addClass(LOOKUP_SEARCH_WRAPPER_CLASS);
var $searchBox = this._$searchBox = $("<div>").addClass(LOOKUP_SEARCH_CLASS).appendTo($searchWrapper);
var currentDevice = devices.current(),
searchMode = currentDevice.android && currentDevice.version[0] >= 5 ? "text" : "search";
this._searchBox = this._createComponent($searchBox, TextBox, {
mode: searchMode,
showClearButton: true,
valueChangeEvent: this.option("valueChangeEvent"),
onValueChanged: this._searchHandler.bind(this)
});
this._registerSearchKeyHandlers();
$searchWrapper.insertBefore(this._$list);
}
this._renderSearchVisibility();
this._setSearchPlaceholder();
},
_selectListItemHandler: function _selectListItemHandler(e) {
var $itemElement = $(this._list.option("focusedElement"));
if (!$itemElement.length) {
return;
}
e.preventDefault();
this._selectListItem(e.itemData, $itemElement);
},
_registerSearchKeyHandlers: function _registerSearchKeyHandlers() {
this._searchBox.registerKeyHandler("escape", this.close.bind(this));
this._searchBox.registerKeyHandler("enter", this._selectListItemHandler.bind(this));
this._searchBox.registerKeyHandler("space", this._selectListItemHandler.bind(this));
this._searchBox.registerKeyHandler("end", commonUtils.noop);
this._searchBox.registerKeyHandler("home", commonUtils.noop);
},
_renderSearchVisibility: function _renderSearchVisibility() {
if (this._popup) {
this._popup._wrapper().toggleClass(LOOKUP_POPUP_SEARCH_CLASS, this.option("searchEnabled"));
}
},
_setSearchPlaceholder: function _setSearchPlaceholder() {
if (!this._$searchBox) {
return;
}
var minSearchLength = this.option("minSearchLength");
var placeholder = this.option("searchPlaceholder");
if (minSearchLength && placeholder === messageLocalization.format("Search")) {
placeholder = messageLocalization.getFormatter("dxLookup-searchPlaceholder")(minSearchLength);
}
this._searchBox.option("placeholder", placeholder);
},
_setAriaTargetForList: commonUtils.noop,
_renderList: function _renderList() {
this.callBase();
this._list.registerKeyHandler("escape", function () {
this.close();
}.bind(this));
},
_listConfig: function _listConfig() {
return extend(this.callBase(), {
tabIndex: 0,
grouped: this.option("grouped"),
groupTemplate: this._getTemplateByOption("groupTemplate"),
pullRefreshEnabled: this.option("pullRefreshEnabled"),
useNativeScrolling: this.option("useNativeScrolling"),
pullingDownText: this.option("pullingDownText"),
pulledDownText: this.option("pulledDownText"),
refreshingText: this.option("refreshingText"),
pageLoadingText: this.option("pageLoadingText"),
onScroll: this.option("onScroll"),
onPullRefresh: this.option("onPullRefresh"),
onPageLoading: this.option("onPageLoading"),
pageLoadMode: this.option("pageLoadMode"),
nextButtonText: this.option("nextButtonText"),
_keyboardProcessor: this._listKeyboardProcessor,
onFocusIn: this._onFocusInHandler.bind(this),
onSelectionChanged: this._getSelectionChangedHandler()
});
},
_getSelectionChangedHandler: function _getSelectionChangedHandler() {
return this.option("showSelectionControls") ? this._selectionChangeHandler.bind(this) : commonUtils.noop;
},
_onFocusInHandler: function _onFocusInHandler() {
this._setListOption("_keyboardProcessor", undefined);
},
_listContentReadyHandler: function _listContentReadyHandler() {
this.callBase.apply(this, arguments);
this._refreshSelected();
},
_setFocusPolicy: function _setFocusPolicy() {
if (!this.option("focusStateEnabled")) {
return;
}
if (this.option("searchEnabled")) {
this._searchBox.focus();
} else {
eventsEngine.trigger(this._$list, "focus");
}
},
_attachChildKeyboardEvents: commonUtils.noop,
_focusTarget: function _focusTarget() {
return this._$field;
},
_keyboardEventBindingTarget: function _keyboardEventBindingTarget() {
return this._$field;
},
_listItemClickHandler: function _listItemClickHandler(e) {
this._selectListItem(e.itemData, e.event.currentTarget);
},
_selectListItem: function _selectListItem(itemData, target) {
this._list.selectItem(target);
if (this.option("applyValueMode") === "instantly") {
this._applyButtonHandler();
}
},
_currentSelectedItem: function _currentSelectedItem() {
return this.option("grouped") ? this._list.option("selectedItems[0]").items[0] : this._list.option("selectedItems[0]");
},
_resetValue: function _resetValue() {
this.option("value", null);
this.option("opened", false);
},
_searchValue: function _searchValue() {
return this.option("searchEnabled") && this._searchBox ? this._searchBox.option("value") : "";
},
_renderInputValue: function _renderInputValue() {
return this.callBase().always(function () {
this._renderField();
this._refreshSelected();
this._setSubmitValue();
}.bind(this));
},
_setSubmitValue: function _setSubmitValue() {
var value = this.option("value"),
submitValue = this.option("valueExpr") === "this" ? this._displayGetter(value) : value;
this._$submitElement.val(submitValue);
},
_renderPlaceholder: function _renderPlaceholder() {
if (this.$element().find("input").length === 0) {
return;
}
this.callBase();
},
_clean: function _clean() {
this._$fieldWrapper.remove();
this._$searchBox = null;
this.callBase();
},
_optionChanged: function _optionChanged(args) {
var name = args.name;
var value = args.value;
switch (name) {
case "searchEnabled":
this._popup && this._renderSearch();
this._attachSearchChildProcessor();
break;
case "searchPlaceholder":
this._setSearchPlaceholder();
break;
case "minSearchLength":
this._setSearchPlaceholder();
this.callBase.apply(this, arguments);
break;
case "title":
case "titleTemplate":
case "onTitleRendered":
case "shading":
case "animation":
case "position":
case "closeOnOutsideClick":
this._setPopupOption(name);
break;
case "fullScreen":
case "usePopover":
case "placeholder":
this._invalidate();
break;
case "clearButtonText":
case "showClearButton":
case "showCancelButton":
this._setPopupOption("toolbarItems", this._getPopupToolbarItems());
break;
case "applyValueMode":
this.callBase.apply(this, arguments);
break;
case "popupWidth":
this._setPopupOption("popupWidth", value === "auto" ? this.initialOption("popupWidth") : value);
break;
case "popupHeight":
this._setPopupOption("popupHeight", value === "auto" ? this.initialOption("popupHeight") : value);
break;
case "pullRefreshEnabled":
case "useNativeScrolling":
case "pullingDownText":
case "pulledDownText":
case "refreshingText":
case "pageLoadingText":
case "onScroll":
case "onPullRefresh":
case "onPageLoading":
case "nextButtonText":
case "grouped":
case "groupTemplate":
this._setListOption(name);
break;
case "pageLoadMode":
this._setListOption("pageLoadMode", this.option("pageLoadMode"));
break;
case "cleanSearchOnOpening":
case "_scrollToSelectedItemEnabled":
break;
default:
this.callBase.apply(this, arguments);
}
},
focus: function focus() {
this.option("opened") ? this._setFocusPolicy() : eventsEngine.trigger(this._focusTarget(), "focus");
},
field: function field() {
return this._$field;
}
});
registerComponent("dxLookup", Lookup);
module.exports = Lookup;