drop_down_box.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /**
  2. * DevExtreme (ui/drop_down_box.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _ui = require("./drop_down_editor/ui.drop_down_editor");
  11. var _ui2 = _interopRequireDefault(_ui);
  12. var _ui3 = require("./editor/ui.data_expression");
  13. var _ui4 = _interopRequireDefault(_ui3);
  14. var _common = require("../core/utils/common");
  15. var _type = require("../core/utils/type");
  16. var _iterator = require("../core/utils/iterator");
  17. var _selectors = require("./widget/selectors");
  18. var _selectors2 = _interopRequireDefault(_selectors);
  19. var _ui5 = require("./widget/ui.keyboard_processor");
  20. var _ui6 = _interopRequireDefault(_ui5);
  21. var _deferred = require("../core/utils/deferred");
  22. var _renderer = require("../core/renderer");
  23. var _renderer2 = _interopRequireDefault(_renderer);
  24. var _events_engine = require("../events/core/events_engine");
  25. var _events_engine2 = _interopRequireDefault(_events_engine);
  26. var _extend = require("../core/utils/extend");
  27. var _utils = require("../ui/overlay/utils");
  28. var _component_registrator = require("../core/component_registrator");
  29. var _component_registrator2 = _interopRequireDefault(_component_registrator);
  30. var _utils2 = require("../events/utils");
  31. var _devices = require("../core/devices");
  32. var _devices2 = _interopRequireDefault(_devices);
  33. var _dom_adapter = require("../core/dom_adapter");
  34. var _dom = require("../core/utils/dom");
  35. function _interopRequireDefault(obj) {
  36. return obj && obj.__esModule ? obj : {
  37. "default": obj
  38. }
  39. }
  40. var DROP_DOWN_BOX_CLASS = "dx-dropdownbox";
  41. var ANONYMOUS_TEMPLATE_NAME = "content";
  42. var realDevice = _devices2.default.real();
  43. var DropDownBox = _ui2.default.inherit({
  44. _supportedKeys: function() {
  45. return (0, _extend.extend)({}, this.callBase(), {
  46. tab: function(e) {
  47. if (!this.option("opened")) {
  48. return
  49. }
  50. var $tabbableElements = this._getTabbableElements();
  51. var $focusableElement = e.shiftKey ? $tabbableElements.last() : $tabbableElements.first();
  52. $focusableElement && _events_engine2.default.trigger($focusableElement, "focus");
  53. e.preventDefault()
  54. }
  55. })
  56. },
  57. _getTabbableElements: function() {
  58. return this._getElements().filter(_selectors2.default.tabbable)
  59. },
  60. _getElements: function() {
  61. return (0, _renderer2.default)(this.content()).find("*")
  62. },
  63. _getAnonymousTemplateName: function() {
  64. return ANONYMOUS_TEMPLATE_NAME
  65. },
  66. _getDefaultOptions: function() {
  67. return (0, _extend.extend)(this.callBase(), {
  68. acceptCustomValue: false,
  69. contentTemplate: ANONYMOUS_TEMPLATE_NAME,
  70. openOnFieldClick: true,
  71. valueFormat: function(value) {
  72. return Array.isArray(value) ? value.join(", ") : value
  73. },
  74. useHiddenSubmitElement: true
  75. })
  76. },
  77. _initMarkup: function() {
  78. this._initDataExpressions();
  79. this.$element().addClass(DROP_DOWN_BOX_CLASS);
  80. this.callBase()
  81. },
  82. _setSubmitValue: function() {
  83. var value = this.option("value");
  84. var submitValue = this._shouldUseDisplayValue(value) ? this._displayGetter(value) : value;
  85. this._getSubmitElement().val(submitValue)
  86. },
  87. _shouldUseDisplayValue: function(value) {
  88. return "this" === this.option("valueExpr") && (0, _type.isObject)(value)
  89. },
  90. _renderInputValue: function() {
  91. var callBase = this.callBase.bind(this);
  92. var values = [];
  93. if (!this._dataSource) {
  94. callBase(values);
  95. return (new _deferred.Deferred).resolve()
  96. }
  97. var currentValue = this._getCurrentValue();
  98. var keys = (0, _common.ensureDefined)(currentValue, []);
  99. keys = Array.isArray(keys) ? keys : [keys];
  100. var itemLoadDeferreds = (0, _iterator.map)(keys, function(key) {
  101. return this._loadItem(key).always(function(item) {
  102. var displayValue = this._displayGetter(item);
  103. values.push((0, _common.ensureDefined)(displayValue, key))
  104. }.bind(this))
  105. }.bind(this));
  106. return _deferred.when.apply(this, itemLoadDeferreds).always(function() {
  107. this.option("displayValue", values);
  108. callBase(values.length && values)
  109. }.bind(this)).fail(callBase)
  110. },
  111. _loadItem: function(value) {
  112. var deferred = new _deferred.Deferred;
  113. var that = this;
  114. var selectedItem = (0, _common.grep)(this.option("items") || [], function(item) {
  115. return this._isValueEquals(this._valueGetter(item), value)
  116. }.bind(this))[0];
  117. if (void 0 !== selectedItem) {
  118. deferred.resolve(selectedItem)
  119. } else {
  120. this._loadValue(value).done(function(item) {
  121. deferred.resolve(item)
  122. }).fail(function(args) {
  123. if (that.option("acceptCustomValue")) {
  124. deferred.resolve(value)
  125. } else {
  126. deferred.reject()
  127. }
  128. })
  129. }
  130. return deferred.promise()
  131. },
  132. _updatePopupWidth: function() {
  133. this._setPopupOption("width", this.$element().outerWidth())
  134. },
  135. _popupElementTabHandler: function(e) {
  136. if ("tab" !== (0, _utils2.normalizeKeyName)(e)) {
  137. return
  138. }
  139. var $firstTabbable = this._getTabbableElements().first().get(0);
  140. var $lastTabbable = this._getTabbableElements().last().get(0);
  141. var $target = e.originalEvent.target;
  142. var moveBackward = !!($target === $firstTabbable && e.shift);
  143. var moveForward = !!($target === $lastTabbable && !e.shift);
  144. if (moveBackward || moveForward) {
  145. this.close();
  146. _events_engine2.default.trigger(this._input(), "focus");
  147. if (moveBackward) {
  148. e.originalEvent.preventDefault()
  149. }
  150. }
  151. },
  152. _renderPopup: function(e) {
  153. this.callBase();
  154. if (this.option("focusStateEnabled")) {
  155. this._popup._keyboardProcessor.push(new _ui6.default({
  156. element: this.content(),
  157. handler: this._popupElementTabHandler,
  158. context: this
  159. }))
  160. }
  161. },
  162. _renderPopupContent: function() {
  163. if (this.option("contentTemplate") === ANONYMOUS_TEMPLATE_NAME) {
  164. return
  165. }
  166. var contentTemplate = this._getTemplateByOption("contentTemplate");
  167. if (!(contentTemplate && this.option("contentTemplate"))) {
  168. return
  169. }
  170. var $popupContent = this._popup.$content();
  171. var templateData = {
  172. value: this._fieldRenderData(),
  173. component: this
  174. };
  175. $popupContent.empty();
  176. contentTemplate.render({
  177. container: (0, _dom.getPublicElement)($popupContent),
  178. model: templateData
  179. })
  180. },
  181. _canShowVirtualKeyboard: function() {
  182. return realDevice.mac
  183. },
  184. _isNestedElementActive: function() {
  185. var activeElement = (0, _dom_adapter.getActiveElement)();
  186. return activeElement && this._popup.$content().get(0).contains(activeElement)
  187. },
  188. _shouldCloseOnTargetScroll: function() {
  189. return "desktop" === realDevice.deviceType && this._canShowVirtualKeyboard() && this._isNestedElementActive()
  190. },
  191. _popupHiddenHandler: function() {
  192. this.callBase();
  193. this._popupPosition = void 0
  194. },
  195. _popupPositionedHandler: function(e) {
  196. this.callBase(e);
  197. this._popupPosition = e.position
  198. },
  199. _popupConfig: function() {
  200. return (0, _extend.extend)(this.callBase(), {
  201. width: function() {
  202. return this.$element().outerWidth()
  203. }.bind(this),
  204. height: "auto",
  205. tabIndex: -1,
  206. dragEnabled: false,
  207. focusStateEnabled: this.option("focusStateEnabled"),
  208. contentTemplate: ANONYMOUS_TEMPLATE_NAME,
  209. closeOnTargetScroll: this._shouldCloseOnTargetScroll.bind(this),
  210. maxHeight: function() {
  211. var _this$_popupPosition;
  212. var popupLocation = null === (_this$_popupPosition = this._popupPosition) || void 0 === _this$_popupPosition ? void 0 : _this$_popupPosition.v.location;
  213. return (0, _utils.getElementMaxHeightByWindow)(this.$element(), popupLocation)
  214. }.bind(this)
  215. })
  216. },
  217. _popupShownHandler: function() {
  218. this.callBase();
  219. var $firstElement = this._getTabbableElements().first();
  220. _events_engine2.default.trigger($firstElement, "focus")
  221. },
  222. _setCollectionWidgetOption: _common.noop,
  223. _optionChanged: function(args) {
  224. this._dataExpressionOptionChanged(args);
  225. switch (args.name) {
  226. case "width":
  227. this.callBase(args);
  228. this._popup && this._popup.repaint();
  229. break;
  230. case "dataSource":
  231. this._renderInputValue();
  232. break;
  233. case "displayValue":
  234. this.option("text", args.value);
  235. break;
  236. case "displayExpr":
  237. this._renderValue();
  238. break;
  239. case "contentTemplate":
  240. this._invalidate();
  241. break;
  242. default:
  243. this.callBase(args)
  244. }
  245. }
  246. }).include(_ui4.default);
  247. (0, _component_registrator2.default)("dxDropDownBox", DropDownBox);
  248. module.exports = DropDownBox;
  249. module.exports.default = module.exports;