ui.tree_view.base.js 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. /**
  2. * DevExtreme (ui/tree_view/ui.tree_view.base.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 _renderer = require("../../core/renderer");
  11. var _renderer2 = _interopRequireDefault(_renderer);
  12. var _dom_adapter = require("../../core/dom_adapter");
  13. var _events_engine = require("../../events/core/events_engine");
  14. var _message = require("../../localization/message");
  15. var _message2 = _interopRequireDefault(_message);
  16. var _click = require("../../events/click");
  17. var _click2 = _interopRequireDefault(_click);
  18. var _common = require("../../core/utils/common");
  19. var _common2 = _interopRequireDefault(_common);
  20. var _window = require("../../core/utils/window");
  21. var _window2 = _interopRequireDefault(_window);
  22. var _type = require("../../core/utils/type");
  23. var _extend = require("../../core/utils/extend");
  24. var _iterator = require("../../core/utils/iterator");
  25. var _dom = require("../../core/utils/dom");
  26. var _check_box = require("../check_box");
  27. var _check_box2 = _interopRequireDefault(_check_box);
  28. var _ui = require("../hierarchical_collection/ui.hierarchical_collection_widget");
  29. var _ui2 = _interopRequireDefault(_ui);
  30. var _utils = require("../../events/utils");
  31. var _pointer = require("../../events/pointer");
  32. var _double_click = require("../../events/double_click");
  33. var _double_click2 = _interopRequireDefault(_double_click);
  34. var _fx = require("../../animation/fx");
  35. var _fx2 = _interopRequireDefault(_fx);
  36. var _ui3 = require("../scroll_view/ui.scrollable");
  37. var _ui4 = _interopRequireDefault(_ui3);
  38. var _load_indicator = require("../load_indicator");
  39. var _load_indicator2 = _interopRequireDefault(_load_indicator);
  40. var _deferred = require("../../core/utils/deferred");
  41. function _interopRequireDefault(obj) {
  42. return obj && obj.__esModule ? obj : {
  43. "default": obj
  44. }
  45. }
  46. var WIDGET_CLASS = "dx-treeview";
  47. var NODE_CLASS = "".concat(WIDGET_CLASS, "-node");
  48. var NODE_CONTAINER_CLASS = "".concat(NODE_CLASS, "-container");
  49. var NODE_LOAD_INDICATOR_CLASS = "".concat(NODE_CLASS, "-loadindicator");
  50. var OPENED_NODE_CONTAINER_CLASS = "".concat(NODE_CLASS, "-container-opened");
  51. var IS_LEAF = "".concat(NODE_CLASS, "-is-leaf");
  52. var ITEM_CLASS = "".concat(WIDGET_CLASS, "-item");
  53. var ITEM_WITH_CHECKBOX_CLASS = "".concat(ITEM_CLASS, "-with-checkbox");
  54. var ITEM_WITHOUT_CHECKBOX_CLASS = "".concat(ITEM_CLASS, "-without-checkbox");
  55. var ITEM_DATA_KEY = "".concat(ITEM_CLASS, "-data");
  56. var TOGGLE_ITEM_VISIBILITY_CLASS = "".concat(WIDGET_CLASS, "-toggle-item-visibility");
  57. var LOAD_INDICATOR_CLASS = "".concat(WIDGET_CLASS, "-loadindicator");
  58. var LOAD_INDICATOR_WRAPPER_CLASS = "".concat(WIDGET_CLASS, "-loadindicator-wrapper");
  59. var TOGGLE_ITEM_VISIBILITY_OPENED_CLASS = "".concat(WIDGET_CLASS, "-toggle-item-visibility-opened");
  60. var SELECT_ALL_ITEM_CLASS = "".concat(WIDGET_CLASS, "-select-all-item");
  61. var INVISIBLE_STATE_CLASS = "dx-state-invisible";
  62. var DISABLED_STATE_CLASS = "dx-state-disabled";
  63. var SELECTED_ITEM_CLASS = "dx-state-selected";
  64. var EXPAND_EVENT_NAMESPACE = "dxTreeView_expand";
  65. var DATA_ITEM_ID = "data-item-id";
  66. var TreeViewBase = _ui2.default.inherit({
  67. _supportedKeys: function(e) {
  68. var _this = this;
  69. var click = function(e) {
  70. var $itemElement = (0, _renderer2.default)(_this.option("focusedElement"));
  71. if (!$itemElement.length) {
  72. return
  73. }
  74. e.target = $itemElement;
  75. e.currentTarget = $itemElement;
  76. _this._itemClickHandler(e, $itemElement.children("." + ITEM_CLASS));
  77. var expandEventName = _this._getEventNameByOption(_this.option("expandEvent"));
  78. var expandByClick = expandEventName === (0, _utils.addNamespace)(_click2.default.name, EXPAND_EVENT_NAMESPACE);
  79. if (expandByClick) {
  80. _this._expandEventHandler(e)
  81. }
  82. };
  83. var select = function(e) {
  84. e.preventDefault();
  85. _this._changeCheckBoxState((0, _renderer2.default)(_this.option("focusedElement")))
  86. };
  87. var toggleExpandedNestedItems = function(state, e) {
  88. if (!this.option("expandAllEnabled")) {
  89. return
  90. }
  91. e.preventDefault();
  92. var $rootElement = (0, _renderer2.default)(this.option("focusedElement"));
  93. if (!$rootElement.length) {
  94. return
  95. }
  96. var rootItem = this._getItemData($rootElement.find(".".concat(ITEM_CLASS)));
  97. this._toggleExpandedNestedItems([rootItem], state)
  98. };
  99. return (0, _extend.extend)(this.callBase(), {
  100. enter: this._showCheckboxes() ? select : click,
  101. space: this._showCheckboxes() ? select : click,
  102. asterisk: toggleExpandedNestedItems.bind(this, true),
  103. minus: toggleExpandedNestedItems.bind(this, false)
  104. })
  105. },
  106. _changeCheckBoxState: function($element) {
  107. var checkboxInstance = this._getCheckBoxInstance($element);
  108. var currentState = checkboxInstance.option("value");
  109. if (!checkboxInstance.option("disabled")) {
  110. this._updateItemSelection(!currentState, $element.find("." + ITEM_CLASS).get(0), true, $element)
  111. }
  112. },
  113. _toggleExpandedNestedItems: function(items, state) {
  114. if (!items) {
  115. return
  116. }
  117. for (var i = 0, len = items.length; i < len; i++) {
  118. var item = items[i];
  119. var node = this._dataAdapter.getNodeByItem(item);
  120. this._toggleExpandedState(node, state);
  121. this._toggleExpandedNestedItems(item.items, state)
  122. }
  123. },
  124. _getNodeElement: function(node, cache) {
  125. var normalizedKey = _common2.default.normalizeKey(node.internalFields.key);
  126. if (cache) {
  127. if (!cache.$nodeByKey) {
  128. cache.$nodeByKey = {};
  129. this.$element().find(".".concat(NODE_CLASS)).each(function() {
  130. var $node = (0, _renderer2.default)(this);
  131. var key = $node.attr(DATA_ITEM_ID);
  132. cache.$nodeByKey[key] = $node
  133. })
  134. }
  135. return cache.$nodeByKey[normalizedKey] || (0, _renderer2.default)()
  136. }
  137. return this.$element().find("[".concat(DATA_ITEM_ID, "='").concat(normalizedKey, "']"))
  138. },
  139. _activeStateUnit: "." + ITEM_CLASS,
  140. _widgetClass: function() {
  141. return WIDGET_CLASS
  142. },
  143. _getDefaultOptions: function() {
  144. return (0, _extend.extend)(this.callBase(), {
  145. animationEnabled: true,
  146. dataStructure: "tree",
  147. deferRendering: true,
  148. expandAllEnabled: false,
  149. hasItemsExpr: "hasItems",
  150. selectNodesRecursive: true,
  151. expandNodesRecursive: true,
  152. showCheckBoxesMode: "none",
  153. selectAllText: _message2.default.format("dxList-selectAll"),
  154. onItemSelectionChanged: null,
  155. onItemExpanded: null,
  156. onItemCollapsed: null,
  157. scrollDirection: "vertical",
  158. virtualModeEnabled: false,
  159. rootValue: 0,
  160. focusStateEnabled: false,
  161. selectionMode: "multiple",
  162. expandEvent: "dblclick",
  163. selectByClick: false,
  164. createChildren: null,
  165. onSelectAllValueChanged: null
  166. })
  167. },
  168. _initSelectedItems: _common2.default.noop,
  169. _syncSelectionOptions: _common2.default.asyncNoop,
  170. _fireSelectionChanged: function() {
  171. var selectionChangePromise = this._selectionChangePromise;
  172. (0, _deferred.when)(selectionChangePromise).done(function() {
  173. this._createActionByOption("onSelectionChanged", {
  174. excludeValidators: ["disabled", "readOnly"]
  175. })()
  176. }.bind(this))
  177. },
  178. _createSelectAllValueChangedAction: function() {
  179. this._selectAllValueChangedAction = this._createActionByOption("onSelectAllValueChanged", {
  180. excludeValidators: ["disabled", "readOnly"]
  181. })
  182. },
  183. _fireSelectAllValueChanged: function(value) {
  184. this._selectAllValueChangedAction({
  185. value: value
  186. })
  187. },
  188. _checkBoxModeChange: function(value, previousValue) {
  189. if ("none" === previousValue || "none" === value) {
  190. this.repaint();
  191. return
  192. }
  193. var selectAllExists = this._$selectAllItem && this._$selectAllItem.length;
  194. switch (value) {
  195. case "selectAll":
  196. !selectAllExists && this._renderSelectAllItem();
  197. break;
  198. case "normal":
  199. if (selectAllExists) {
  200. this._$selectAllItem.remove();
  201. delete this._$selectAllItem
  202. }
  203. }
  204. },
  205. _removeSelection: function() {
  206. var that = this;
  207. (0, _iterator.each)(this._dataAdapter.getFullData(), function(_, node) {
  208. if (!that._hasChildren(node)) {
  209. return
  210. }
  211. that._dataAdapter.toggleSelection(node.internalFields.key, false, true)
  212. })
  213. },
  214. _optionChanged: function(args) {
  215. var name = args.name,
  216. value = args.value,
  217. previousValue = args.previousValue;
  218. switch (name) {
  219. case "selectAllText":
  220. if (this._$selectAllItem) {
  221. this._$selectAllItem.dxCheckBox("instance").option("text", value)
  222. }
  223. break;
  224. case "showCheckBoxesMode":
  225. this._checkBoxModeChange(value, previousValue);
  226. break;
  227. case "scrollDirection":
  228. this._scrollableContainer.option("direction", value);
  229. break;
  230. case "items":
  231. delete this._$selectAllItem;
  232. this.callBase(args);
  233. break;
  234. case "dataSource":
  235. this.callBase(args);
  236. this._initDataAdapter();
  237. this._filter = {};
  238. break;
  239. case "hasItemsExpr":
  240. this._initAccessors();
  241. this.repaint();
  242. break;
  243. case "expandEvent":
  244. this._initExpandEvent();
  245. break;
  246. case "deferRendering":
  247. case "dataStructure":
  248. case "rootValue":
  249. case "createChildren":
  250. case "expandNodesRecursive":
  251. case "onItemSelectionChanged":
  252. case "onItemExpanded":
  253. case "onItemCollapsed":
  254. case "expandAllEnabled":
  255. case "animationEnabled":
  256. case "virtualModeEnabled":
  257. case "selectByClick":
  258. break;
  259. case "selectionMode":
  260. this._initDataAdapter();
  261. this.callBase(args);
  262. break;
  263. case "onSelectAllValueChanged":
  264. this._createSelectAllValueChangedAction();
  265. break;
  266. case "selectNodesRecursive":
  267. this._dataAdapter.setOption("recursiveSelection", args.value);
  268. this.repaint();
  269. break;
  270. default:
  271. this.callBase(args)
  272. }
  273. },
  274. _initDataSource: function() {
  275. if (this._useCustomChildrenLoader()) {
  276. this._loadChildrenByCustomLoader(null).done(function(newItems) {
  277. if (newItems && newItems.length) {
  278. this.option("items", newItems)
  279. }
  280. }.bind(this))
  281. } else {
  282. this.callBase();
  283. this._isVirtualMode() && this._initVirtualMode()
  284. }
  285. },
  286. _initVirtualMode: function() {
  287. var filter = this._filter;
  288. if (!filter.custom) {
  289. filter.custom = this._dataSource.filter()
  290. }
  291. if (!filter.internal) {
  292. filter.internal = [this.option("parentIdExpr"), this.option("rootValue")]
  293. }
  294. },
  295. _useCustomChildrenLoader: function() {
  296. return (0, _type.isFunction)(this.option("createChildren")) && this._isDataStructurePlain()
  297. },
  298. _loadChildrenByCustomLoader: function(parentNode) {
  299. var invocationResult = this.option("createChildren").call(this, parentNode);
  300. if (Array.isArray(invocationResult)) {
  301. return (new _deferred.Deferred).resolve(invocationResult).promise()
  302. }
  303. if (invocationResult && (0, _type.isFunction)(invocationResult.then)) {
  304. return (0, _deferred.fromPromise)(invocationResult)
  305. }
  306. return (new _deferred.Deferred).resolve([]).promise()
  307. },
  308. _combineFilter: function() {
  309. if (!this._filter.custom || !this._filter.custom.length) {
  310. return this._filter.internal
  311. }
  312. return [this._filter.custom, this._filter.internal]
  313. },
  314. _dataSourceLoadErrorHandler: function() {
  315. this._renderEmptyMessage()
  316. },
  317. _init: function() {
  318. this._filter = {};
  319. this.callBase();
  320. this._initStoreChangeHandlers()
  321. },
  322. _dataSourceChangedHandler: function(newItems) {
  323. var items = this.option("items");
  324. if (this._initialized && this._isVirtualMode() && items.length) {
  325. return
  326. }
  327. this.option("items", newItems)
  328. },
  329. _removeTreeViewLoadIndicator: function() {
  330. if (!this._treeViewLoadIndicator) {
  331. return
  332. }
  333. this._treeViewLoadIndicator.remove();
  334. this._treeViewLoadIndicator = null
  335. },
  336. _createTreeViewLoadIndicator: function() {
  337. this._treeViewLoadIndicator = (0, _renderer2.default)("<div>").addClass(LOAD_INDICATOR_CLASS);
  338. this._createComponent(this._treeViewLoadIndicator, _load_indicator2.default, {});
  339. return this._treeViewLoadIndicator
  340. },
  341. _dataSourceLoadingChangedHandler: function(isLoading) {
  342. var resultFilter;
  343. if (this._isVirtualMode()) {
  344. resultFilter = this._combineFilter();
  345. this._dataSource.filter(resultFilter)
  346. }
  347. if (isLoading && !this._dataSource.isLoaded()) {
  348. this.option("items", []);
  349. var $wrapper = (0, _renderer2.default)("<div>").addClass(LOAD_INDICATOR_WRAPPER_CLASS);
  350. this._createTreeViewLoadIndicator().appendTo($wrapper);
  351. this.itemsContainer().append($wrapper);
  352. if (this._isVirtualMode() && this._dataSource.filter() !== resultFilter) {
  353. this._dataSource.filter([])
  354. }
  355. } else {
  356. this._removeTreeViewLoadIndicator()
  357. }
  358. },
  359. _initStoreChangeHandlers: function() {
  360. var _this2 = this;
  361. if ("plain" !== this.option("dataStructure")) {
  362. return
  363. }
  364. this._dataSource && this._dataSource.store().on("inserted", function(newItem) {
  365. _this2.option().items = _this2.option("items").concat(newItem);
  366. _this2._dataAdapter.addItem(newItem);
  367. if (!_this2._dataAdapter.isFiltered(newItem)) {
  368. return
  369. }
  370. _this2._updateLevel(_this2._parentIdGetter(newItem))
  371. }).on("removed", function(removedKey) {
  372. var node = _this2._dataAdapter.getNodeByKey(removedKey);
  373. _this2.option("items")[_this2._dataAdapter.getIndexByKey(node.internalFields.key)] = 0;
  374. _this2._markChildrenItemsToRemove(node);
  375. _this2._removeItems();
  376. _this2._dataAdapter.removeItem(removedKey);
  377. _this2._updateLevel(_this2._parentIdGetter(node))
  378. })
  379. },
  380. _markChildrenItemsToRemove: function(node) {
  381. var _this3 = this;
  382. var keys = node.internalFields.childrenKeys;
  383. (0, _iterator.each)(keys, function(_, key) {
  384. _this3.option("items")[_this3._dataAdapter.getIndexByKey(key)] = 0;
  385. _this3._markChildrenItemsToRemove(_this3._dataAdapter.getNodeByKey(key))
  386. })
  387. },
  388. _removeItems: function() {
  389. var _this4 = this;
  390. var items = (0, _extend.extend)(true, [], this.option("items"));
  391. var counter = 0;
  392. (0, _iterator.each)(items, function(index, item) {
  393. if (!item) {
  394. _this4.option("items").splice(index - counter, 1);
  395. counter++
  396. }
  397. })
  398. },
  399. _updateLevel: function(parentId) {
  400. var $container = this._getContainerByParentKey(parentId);
  401. this._renderItems($container, this._dataAdapter.getChildrenNodes(parentId))
  402. },
  403. _getOldContainer: function($itemElement) {
  404. if ($itemElement.length) {
  405. return $itemElement.children(".".concat(NODE_CONTAINER_CLASS))
  406. }
  407. if (this._scrollableContainer) {
  408. return this._scrollableContainer.$content().children()
  409. }
  410. return (0, _renderer2.default)()
  411. },
  412. _getContainerByParentKey: function(parentId) {
  413. var node = this._dataAdapter.getNodeByKey(parentId);
  414. var $itemElement = node ? this._getNodeElement(node) : [];
  415. this._getOldContainer($itemElement).remove();
  416. var $container = this._renderNodeContainer($itemElement);
  417. if (this._isRootLevel(parentId)) {
  418. if (!this._scrollableContainer) {
  419. this._renderScrollableContainer()
  420. }
  421. this._scrollableContainer.$content().append($container)
  422. }
  423. return $container
  424. },
  425. _isRootLevel: function(parentId) {
  426. return parentId === this.option("rootValue")
  427. },
  428. _getAccessors: function() {
  429. var accessors = this.callBase();
  430. accessors.push("hasItems");
  431. return accessors
  432. },
  433. _getDataAdapterOptions: function() {
  434. return {
  435. rootValue: this.option("rootValue"),
  436. multipleSelection: !this._isSingleSelection(),
  437. recursiveSelection: this._isRecursiveSelection(),
  438. recursiveExpansion: this.option("expandNodesRecursive"),
  439. selectionRequired: this.option("selectionRequired"),
  440. dataType: this.option("dataStructure"),
  441. sort: this._dataSource && this._dataSource.sort()
  442. }
  443. },
  444. _initMarkup: function() {
  445. this._renderScrollableContainer();
  446. this._renderEmptyMessage(this._dataAdapter.getRootNodes());
  447. this.callBase();
  448. this.setAria("role", "tree")
  449. },
  450. _renderContentImpl: function() {
  451. var $nodeContainer = this._renderNodeContainer();
  452. this._scrollableContainer.$content().append($nodeContainer);
  453. if (!this.option("items") || !this.option("items").length) {
  454. return
  455. }
  456. this._renderItems($nodeContainer, this._dataAdapter.getRootNodes());
  457. this._initExpandEvent();
  458. if (this._selectAllEnabled()) {
  459. this._createSelectAllValueChangedAction();
  460. this._renderSelectAllItem($nodeContainer)
  461. }
  462. },
  463. _isVirtualMode: function() {
  464. return this.option("virtualModeEnabled") && this._isDataStructurePlain() && !!this.option("dataSource")
  465. },
  466. _isDataStructurePlain: function() {
  467. return "plain" === this.option("dataStructure")
  468. },
  469. _fireContentReadyAction: function() {
  470. var dataSource = this.getDataSource();
  471. var skipContentReadyAction = dataSource && !dataSource.isLoaded();
  472. if (!skipContentReadyAction) {
  473. this.callBase()
  474. }
  475. if (this._scrollableContainer && _window2.default.hasWindow()) {
  476. this._scrollableContainer.update()
  477. }
  478. },
  479. _renderScrollableContainer: function() {
  480. this._scrollableContainer = this._createComponent((0, _renderer2.default)("<div>").appendTo(this.$element()), _ui4.default, {
  481. direction: this.option("scrollDirection"),
  482. useKeyboard: false
  483. })
  484. },
  485. _renderNodeContainer: function($parent) {
  486. var $container = (0, _renderer2.default)("<ul>").addClass(NODE_CONTAINER_CLASS);
  487. this.setAria("role", "group", $container);
  488. if ($parent && $parent.length) {
  489. var itemData = this._getItemData($parent.children("." + ITEM_CLASS));
  490. if (this._expandedGetter(itemData)) {
  491. $container.addClass(OPENED_NODE_CONTAINER_CLASS)
  492. }
  493. $container.appendTo($parent)
  494. }
  495. return $container
  496. },
  497. _createDOMElement: function($nodeContainer, node) {
  498. var $node = (0, _renderer2.default)("<li>").addClass(NODE_CLASS).attr(DATA_ITEM_ID, _common2.default.normalizeKey(node.internalFields.key)).prependTo($nodeContainer);
  499. this.setAria({
  500. role: "treeitem",
  501. label: this._displayGetter(node.internalFields.item) || "",
  502. expanded: node.internalFields.expanded || false,
  503. level: this._getLevel($nodeContainer)
  504. }, $node);
  505. return $node
  506. },
  507. _getLevel: function($nodeContainer) {
  508. var parent = $nodeContainer.parent();
  509. return parent.hasClass("dx-scrollable-content") ? 1 : parseInt(parent.attr("aria-level")) + 1
  510. },
  511. _showCheckboxes: function() {
  512. return "none" !== this.option("showCheckBoxesMode")
  513. },
  514. _selectAllEnabled: function() {
  515. return "selectAll" === this.option("showCheckBoxesMode") && !this._isSingleSelection()
  516. },
  517. _renderItems: function($nodeContainer, nodes) {
  518. var length = nodes.length - 1;
  519. for (var i = length; i >= 0; i--) {
  520. this._renderItem(i, nodes[i], $nodeContainer)
  521. }
  522. this._renderedItemsCount += nodes.length
  523. },
  524. _renderItem: function(nodeIndex, node, $nodeContainer) {
  525. var $node = this._createDOMElement($nodeContainer, node);
  526. var nodeData = node.internalFields;
  527. var showCheckBox = this._showCheckboxes();
  528. $node.addClass(showCheckBox ? ITEM_WITH_CHECKBOX_CLASS : ITEM_WITHOUT_CHECKBOX_CLASS);
  529. showCheckBox && this._renderCheckBox($node, node);
  530. this.setAria("selected", nodeData.selected, $node);
  531. this._toggleSelectedClass($node, nodeData.selected);
  532. this.callBase(this._renderedItemsCount + nodeIndex, nodeData.item, $node);
  533. if (false !== nodeData.item.visible) {
  534. this._renderChildren($node, node)
  535. }
  536. },
  537. _setAriaSelected: function() {},
  538. _renderChildren: function($node, node) {
  539. var _this5 = this;
  540. if (!this._hasChildren(node)) {
  541. this._addLeafClass($node);
  542. return
  543. }
  544. this._renderToggleItemVisibilityIcon($node, node);
  545. if (this.option("deferRendering") && !node.internalFields.expanded) {
  546. return
  547. }
  548. this._loadSublevel(node).done(function(childNodes) {
  549. _this5._renderSublevel($node, _this5._getActualNode(node), childNodes)
  550. })
  551. },
  552. _getActualNode: function(cachedNode) {
  553. return this._dataAdapter.getNodeByKey(cachedNode.internalFields.key)
  554. },
  555. _hasChildren: function(node) {
  556. if (this._isVirtualMode() || this._useCustomChildrenLoader()) {
  557. return false !== this._hasItemsGetter(node.internalFields.item)
  558. }
  559. return this.callBase(node)
  560. },
  561. _loadSublevel: function(node) {
  562. var _this6 = this;
  563. var deferred = new _deferred.Deferred;
  564. var childrenNodes = this._getChildNodes(node);
  565. if (childrenNodes.length) {
  566. deferred.resolve(childrenNodes)
  567. } else {
  568. this._loadNestedItems(node).done(function(items) {
  569. deferred.resolve(_this6._dataAdapter.getNodesByItems(items))
  570. })
  571. }
  572. return deferred.promise()
  573. },
  574. _renderSublevel: function($node, node, childNodes) {
  575. var $nestedNodeContainer = this._renderNodeContainer($node, node);
  576. this._renderItems($nestedNodeContainer, childNodes);
  577. if (childNodes.length && !node.internalFields.selected) {
  578. var firstChild = childNodes[0];
  579. this._updateParentsState(firstChild, this._getNodeElement(firstChild))
  580. }
  581. this._normalizeIconState($node, childNodes.length);
  582. if (node.internalFields.expanded) {
  583. $nestedNodeContainer.addClass(OPENED_NODE_CONTAINER_CLASS)
  584. }
  585. },
  586. _executeItemRenderAction: function(itemIndex, itemData, itemElement) {
  587. var node = this._getNode(itemElement);
  588. this._getItemRenderAction()({
  589. itemElement: itemElement,
  590. itemIndex: itemIndex,
  591. itemData: itemData,
  592. node: this._dataAdapter.getPublicNode(node)
  593. })
  594. },
  595. _addLeafClass: function($node) {
  596. $node.addClass(IS_LEAF)
  597. },
  598. _expandEventHandler: function(e) {
  599. var $nodeElement = (0, _renderer2.default)(e.currentTarget.parentNode);
  600. if (!$nodeElement.hasClass(IS_LEAF)) {
  601. this._toggleExpandedState(e.currentTarget, void 0, e)
  602. }
  603. },
  604. _initExpandEvent: function() {
  605. var expandedEventName = this._getEventNameByOption(this.option("expandEvent"));
  606. var $itemsContainer = this._itemContainer();
  607. var itemSelector = this._itemSelector();
  608. (0, _events_engine.off)($itemsContainer, "." + EXPAND_EVENT_NAMESPACE, itemSelector);
  609. (0, _events_engine.on)($itemsContainer, expandedEventName, itemSelector, this._expandEventHandler.bind(this))
  610. },
  611. _getEventNameByOption: function(name) {
  612. var event = "click" === name ? _click2.default : _double_click2.default;
  613. return (0, _utils.addNamespace)(event.name, EXPAND_EVENT_NAMESPACE)
  614. },
  615. _getNode: function(identifier) {
  616. if (!(0, _type.isDefined)(identifier)) {
  617. return null
  618. }
  619. if (identifier.internalFields) {
  620. return identifier
  621. }
  622. if ((0, _type.isPrimitive)(identifier)) {
  623. return this._dataAdapter.getNodeByKey(identifier)
  624. }
  625. var itemElement = (0, _renderer2.default)(identifier).get(0);
  626. if (!itemElement) {
  627. return null
  628. }
  629. if ((0, _dom_adapter.isElementNode)(itemElement)) {
  630. return this._getNodeByElement(itemElement)
  631. }
  632. return this._dataAdapter.getNodeByItem(itemElement)
  633. },
  634. _getNodeByElement: function(itemElement) {
  635. var $node = (0, _renderer2.default)(itemElement).closest("." + NODE_CLASS);
  636. var key = _common2.default.denormalizeKey($node.attr(DATA_ITEM_ID));
  637. return this._dataAdapter.getNodeByKey(key)
  638. },
  639. _toggleExpandedState: function(itemElement, state, e) {
  640. var node = this._getNode(itemElement);
  641. var currentState = node.internalFields.expanded;
  642. if (node.internalFields.disabled || currentState === state) {
  643. return
  644. }
  645. if (this._hasChildren(node)) {
  646. var $node = this._getNodeElement(node);
  647. if ($node.find(".".concat(NODE_LOAD_INDICATOR_CLASS, ":not(.").concat(INVISIBLE_STATE_CLASS, ")")).length) {
  648. return
  649. }
  650. this._createLoadIndicator($node)
  651. }
  652. if (!(0, _type.isDefined)(state)) {
  653. state = !currentState
  654. }
  655. this._dataAdapter.toggleExpansion(node.internalFields.key, state);
  656. this._updateExpandedItemsUI(node, state, e)
  657. },
  658. _createLoadIndicator: function($node) {
  659. var $icon = $node.children("." + TOGGLE_ITEM_VISIBILITY_CLASS);
  660. var $nodeContainer = $node.children(".".concat(NODE_CONTAINER_CLASS));
  661. if ($icon.hasClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS) || $nodeContainer.not(":empty").length) {
  662. return
  663. }
  664. this._createComponent((0, _renderer2.default)("<div>").addClass(NODE_LOAD_INDICATOR_CLASS), _load_indicator2.default, {}).$element().appendTo($node);
  665. $icon.hide()
  666. },
  667. _renderToggleItemVisibilityIcon: function($node, node) {
  668. var $icon = (0, _renderer2.default)("<div>").addClass(TOGGLE_ITEM_VISIBILITY_CLASS).appendTo($node);
  669. if (node.internalFields.expanded) {
  670. $icon.addClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS);
  671. $node.parent().addClass(OPENED_NODE_CONTAINER_CLASS)
  672. }
  673. if (node.internalFields.disabled) {
  674. $icon.addClass(DISABLED_STATE_CLASS)
  675. }
  676. this._renderToggleItemVisibilityIconClick($icon, node)
  677. },
  678. _renderToggleItemVisibilityIconClick: function($icon, node) {
  679. var _this7 = this;
  680. var eventName = (0, _utils.addNamespace)(_click2.default.name, this.NAME);
  681. (0, _events_engine.off)($icon, eventName);
  682. (0, _events_engine.on)($icon, eventName, function(e) {
  683. _this7._toggleExpandedState(node.internalFields.key, void 0, e)
  684. })
  685. },
  686. _updateExpandedItemsUI: function(node, state, e) {
  687. var $node = this._getNodeElement(node);
  688. var isHiddenNode = !$node.length || state && $node.is(":hidden");
  689. if (this.option("expandNodesRecursive") && isHiddenNode) {
  690. var parentNode = this._getNode(node.internalFields.parentKey);
  691. if (parentNode) {
  692. this._updateExpandedItemsUI(parentNode, state, e)
  693. }
  694. }
  695. var $icon = $node.children("." + TOGGLE_ITEM_VISIBILITY_CLASS);
  696. var $nodeContainer = $node.children(".".concat(NODE_CONTAINER_CLASS));
  697. $icon.toggleClass(TOGGLE_ITEM_VISIBILITY_OPENED_CLASS, state);
  698. var nodeContainerExists = $nodeContainer.length > 0;
  699. if (!state || nodeContainerExists && !$nodeContainer.is(":empty")) {
  700. this._updateExpandedItem(node, state, e);
  701. return
  702. }
  703. if (this._isVirtualMode() || this._useCustomChildrenLoader()) {
  704. this._loadNestedItemsWithUpdate(node, state, e);
  705. return
  706. }
  707. this._renderSublevel($node, node, this._getChildNodes(node));
  708. this._fireContentReadyAction();
  709. this._updateExpandedItem(node, state, e)
  710. },
  711. _loadNestedItemsWithUpdate: function(node, state, e) {
  712. var _this8 = this;
  713. var $node = this._getNodeElement(node);
  714. this._loadNestedItems(node).done(function(items) {
  715. var actualNodeData = _this8._getActualNode(node);
  716. _this8._renderSublevel($node, actualNodeData, _this8._dataAdapter.getNodesByItems(items));
  717. if (!items || !items.length) {
  718. return
  719. }
  720. _this8._fireContentReadyAction();
  721. _this8._updateExpandedItem(actualNodeData, state, e)
  722. })
  723. },
  724. _loadNestedItems: function(node) {
  725. var _this9 = this;
  726. if (this._useCustomChildrenLoader()) {
  727. var publicNode = this._dataAdapter.getPublicNode(node);
  728. return this._loadChildrenByCustomLoader(publicNode).done(function(newItems) {
  729. if (!_this9._areNodesExists(newItems)) {
  730. _this9._appendItems(newItems)
  731. }
  732. })
  733. }
  734. if (!this._isVirtualMode()) {
  735. return (new _deferred.Deferred).resolve([]).promise()
  736. }
  737. this._filter.internal = [this.option("parentIdExpr"), node.internalFields.key];
  738. this._dataSource.filter(this._combineFilter());
  739. return this._dataSource.load().done(function(newItems) {
  740. if (!_this9._areNodesExists(newItems)) {
  741. _this9._appendItems(newItems)
  742. }
  743. })
  744. },
  745. _areNodesExists: function(newItems, items) {
  746. var keyOfRootItem = this.keyOf(newItems[0]);
  747. var fullData = this._dataAdapter.getFullData();
  748. return !!this._dataAdapter.getNodeByKey(keyOfRootItem, fullData)
  749. },
  750. _appendItems: function(newItems) {
  751. this.option().items = this.option("items").concat(newItems);
  752. this._initDataAdapter()
  753. },
  754. _updateExpandedItem: function(node, state, e) {
  755. this._animateNodeContainer(node, state, e)
  756. },
  757. _animateNodeContainer: function(node, state, e) {
  758. var $node = this._getNodeElement(node);
  759. var $nodeContainer = $node.children(".".concat(NODE_CONTAINER_CLASS));
  760. $nodeContainer.addClass(OPENED_NODE_CONTAINER_CLASS);
  761. var nodeHeight = $nodeContainer.height();
  762. _fx2.default.stop($nodeContainer, true);
  763. _fx2.default.animate($nodeContainer, {
  764. type: "custom",
  765. duration: this.option("animationEnabled") ? 400 : 0,
  766. from: {
  767. maxHeight: state ? 0 : nodeHeight
  768. },
  769. to: {
  770. maxHeight: state ? nodeHeight : 0
  771. },
  772. complete: function() {
  773. $nodeContainer.css("maxHeight", "none");
  774. $nodeContainer.toggleClass(OPENED_NODE_CONTAINER_CLASS, state);
  775. this.setAria("expanded", state, $node);
  776. this._scrollableContainer.update();
  777. this._fireExpandedStateUpdatedEvent(state, node, e)
  778. }.bind(this)
  779. })
  780. },
  781. _fireExpandedStateUpdatedEvent: function(isExpanded, node, e) {
  782. if (!this._hasChildren(node)) {
  783. return
  784. }
  785. var optionName = isExpanded ? "onItemExpanded" : "onItemCollapsed";
  786. if ((0, _type.isDefined)(e)) {
  787. this._itemDXEventHandler(e, optionName, {
  788. node: this._dataAdapter.getPublicNode(node)
  789. })
  790. } else {
  791. var target = this._getNodeElement(node);
  792. this._itemEventHandler(target, optionName, {
  793. event: e,
  794. node: this._dataAdapter.getPublicNode(node)
  795. })
  796. }
  797. },
  798. _normalizeIconState: function($node, hasNewItems) {
  799. var $loadIndicator = $node.find(".dx-loadindicator");
  800. $loadIndicator.length && _load_indicator2.default.getInstance($loadIndicator).option("visible", false);
  801. if (hasNewItems) {
  802. var $icon = $node.find("." + TOGGLE_ITEM_VISIBILITY_CLASS);
  803. $icon.show();
  804. return
  805. }
  806. $node.find("." + TOGGLE_ITEM_VISIBILITY_CLASS).removeClass(TOGGLE_ITEM_VISIBILITY_CLASS);
  807. $node.addClass(IS_LEAF)
  808. },
  809. _emptyMessageContainer: function() {
  810. return this._scrollableContainer ? this._scrollableContainer.content() : this.callBase()
  811. },
  812. _renderContent: function() {
  813. var items = this.option("items");
  814. if (items && items.length) {
  815. this._contentAlreadyRendered = true
  816. }
  817. this.callBase()
  818. },
  819. _renderSelectAllItem: function($container) {
  820. $container = $container || this.$element().find(".".concat(NODE_CONTAINER_CLASS)).first();
  821. this._$selectAllItem = (0, _renderer2.default)("<div>").addClass(SELECT_ALL_ITEM_CLASS);
  822. var value = this._dataAdapter.isAllSelected();
  823. this._createComponent(this._$selectAllItem, _check_box2.default, {
  824. value: value,
  825. text: this.option("selectAllText"),
  826. onValueChanged: function(args) {
  827. this._toggleSelectAll(args);
  828. this._fireSelectAllValueChanged(args.value)
  829. }.bind(this)
  830. });
  831. this._toggleSelectedClass(this._$selectAllItem, value);
  832. $container.before(this._$selectAllItem)
  833. },
  834. _toggleSelectAll: function(args) {
  835. this._dataAdapter.toggleSelectAll(args.value);
  836. this._updateItemsUI();
  837. this._fireSelectionChanged()
  838. },
  839. _renderCheckBox: function($node, node) {
  840. var $checkbox = (0, _renderer2.default)("<div>").appendTo($node);
  841. this._createComponent($checkbox, _check_box2.default, {
  842. value: node.internalFields.selected,
  843. onValueChanged: this._changeCheckboxValue.bind(this),
  844. focusStateEnabled: false,
  845. disabled: this._disabledGetter(node)
  846. })
  847. },
  848. _toggleSelectedClass: function($node, value) {
  849. $node.toggleClass(SELECTED_ITEM_CLASS, !!value)
  850. },
  851. _toggleNodeDisabledState: function(node, state) {
  852. var $node = this._getNodeElement(node);
  853. var $item = $node.find("." + ITEM_CLASS).eq(0);
  854. this._dataAdapter.toggleNodeDisabledState(node.internalFields.key, state);
  855. $item.toggleClass(DISABLED_STATE_CLASS, !!state);
  856. if (this._showCheckboxes()) {
  857. var checkbox = this._getCheckBoxInstance($node);
  858. checkbox.option("disabled", !!state)
  859. }
  860. },
  861. _itemOptionChanged: function(item, property, value) {
  862. var node = this._dataAdapter.getNodeByItem(item);
  863. if (property === this.option("disabledExpr")) {
  864. this._toggleNodeDisabledState(node, value)
  865. }
  866. },
  867. _changeCheckboxValue: function(e) {
  868. var $node = (0, _renderer2.default)(e.element).parent("." + NODE_CLASS);
  869. var $item = $node.children("." + ITEM_CLASS);
  870. var item = this._getItemData($item);
  871. var node = this._getNodeByElement($item);
  872. var value = e.value;
  873. if (node && node.internalFields.selected === value) {
  874. return
  875. }
  876. this._updateItemSelection(value, item, e.event)
  877. },
  878. _isSingleSelection: function() {
  879. return "single" === this.option("selectionMode")
  880. },
  881. _isRecursiveSelection: function() {
  882. return this.option("selectNodesRecursive") && "single" !== this.option("selectionMode")
  883. },
  884. _isLastSelectedBranch: function(publicNode, selectedNodesKeys, deep) {
  885. var keyIndex = selectedNodesKeys.indexOf(publicNode.key);
  886. if (keyIndex >= 0) {
  887. selectedNodesKeys.splice(keyIndex, 1)
  888. }
  889. if (deep) {
  890. (0, _iterator.each)(publicNode.children, function(_, childNode) {
  891. this._isLastSelectedBranch(childNode, selectedNodesKeys, true)
  892. }.bind(this))
  893. }
  894. if (publicNode.parent) {
  895. this._isLastSelectedBranch(publicNode.parent, selectedNodesKeys)
  896. }
  897. return 0 === selectedNodesKeys.length
  898. },
  899. _isLastRequired: function(node) {
  900. var selectionRequired = this.option("selectionRequired");
  901. var isSingleMode = this._isSingleSelection();
  902. var selectedNodesKeys = this.getSelectedNodesKeys();
  903. if (!selectionRequired) {
  904. return
  905. }
  906. if (isSingleMode) {
  907. return 1 === selectedNodesKeys.length
  908. } else {
  909. return this._isLastSelectedBranch(node.internalFields.publicNode, selectedNodesKeys.slice(), true)
  910. }
  911. },
  912. _updateItemSelection: function(value, itemElement, dxEvent) {
  913. var _this10 = this;
  914. var node = this._getNode(itemElement);
  915. if (!node || node.internalFields.selected === value) {
  916. return
  917. }
  918. if (!value && this._isLastRequired(node)) {
  919. if (this._showCheckboxes()) {
  920. var $node = this._getNodeElement(node);
  921. var checkbox = this._getCheckBoxInstance($node);
  922. checkbox && checkbox.option("value", true)
  923. }
  924. return
  925. }
  926. var selectedNodesKeys = this.getSelectedNodesKeys();
  927. if (this._isSingleSelection() && value) {
  928. (0, _iterator.each)(selectedNodesKeys, function(index, nodeKey) {
  929. _this10.unselectItem(nodeKey)
  930. })
  931. }
  932. this._dataAdapter.toggleSelection(node.internalFields.key, value);
  933. this._updateItemsUI();
  934. var initiator = dxEvent || this._findItemElementByItem(node.internalFields.item);
  935. var handler = dxEvent ? this._itemDXEventHandler : this._itemEventHandler;
  936. handler.call(this, initiator, "onItemSelectionChanged", {
  937. node: this._dataAdapter.getPublicNode(node),
  938. itemData: node.internalFields.item
  939. });
  940. this._fireSelectionChanged()
  941. },
  942. _getCheckBoxInstance: function($node) {
  943. return $node.children(".dx-checkbox").dxCheckBox("instance")
  944. },
  945. _updateItemsUI: function() {
  946. var _this11 = this;
  947. var cache = {};
  948. (0, _iterator.each)(this._dataAdapter.getData(), function(_, node) {
  949. var $node = _this11._getNodeElement(node, cache);
  950. var nodeSelection = node.internalFields.selected;
  951. if (!$node.length) {
  952. return
  953. }
  954. _this11._toggleSelectedClass($node, nodeSelection);
  955. _this11.setAria("selected", nodeSelection, $node);
  956. if (_this11._showCheckboxes()) {
  957. var checkbox = _this11._getCheckBoxInstance($node);
  958. checkbox.option("value", nodeSelection)
  959. }
  960. });
  961. if (this._selectAllEnabled()) {
  962. this._$selectAllItem.dxCheckBox("instance").option("value", this._dataAdapter.isAllSelected())
  963. }
  964. },
  965. _updateParentsState: function(node, $node) {
  966. if (!$node) {
  967. return
  968. }
  969. var parentNode = this._dataAdapter.getNodeByKey(node.internalFields.parentKey);
  970. var $parentNode = (0, _renderer2.default)($node.parents("." + NODE_CLASS)[0]);
  971. if (this._showCheckboxes()) {
  972. var parentValue = parentNode.internalFields.selected;
  973. this._getCheckBoxInstance($parentNode).option("value", parentValue);
  974. this._toggleSelectedClass($parentNode, parentValue)
  975. }
  976. if (parentNode.internalFields.parentKey !== this.option("rootValue")) {
  977. this._updateParentsState(parentNode, $parentNode)
  978. }
  979. },
  980. _itemEventHandlerImpl: function(initiator, action, actionArgs) {
  981. var $itemElement = (0, _renderer2.default)(initiator).closest("." + NODE_CLASS).children("." + ITEM_CLASS);
  982. return action((0, _extend.extend)(this._extendActionArgs($itemElement), actionArgs))
  983. },
  984. _itemContextMenuHandler: function(e) {
  985. this._createEventHandler("onItemContextMenu", e)
  986. },
  987. _itemHoldHandler: function(e) {
  988. this._createEventHandler("onItemHold", e)
  989. },
  990. _createEventHandler: function(eventName, e) {
  991. var node = this._getNodeByElement(e.currentTarget);
  992. this._itemDXEventHandler(e, eventName, {
  993. node: this._dataAdapter.getPublicNode(node)
  994. })
  995. },
  996. _itemClass: function() {
  997. return ITEM_CLASS
  998. },
  999. _itemDataKey: function() {
  1000. return ITEM_DATA_KEY
  1001. },
  1002. _attachClickEvent: function() {
  1003. var clickSelector = "." + this._itemClass();
  1004. var pointerDownSelector = "." + NODE_CLASS + ", ." + SELECT_ALL_ITEM_CLASS;
  1005. var eventName = (0, _utils.addNamespace)(_click2.default.name, this.NAME);
  1006. var pointerDownEvent = (0, _utils.addNamespace)(_pointer.down, this.NAME);
  1007. var $itemContainer = this._itemContainer();
  1008. var that = this;
  1009. (0, _events_engine.off)($itemContainer, eventName, clickSelector);
  1010. (0, _events_engine.off)($itemContainer, pointerDownEvent, pointerDownSelector);
  1011. (0, _events_engine.on)($itemContainer, eventName, clickSelector, function(e) {
  1012. that._itemClickHandler(e, (0, _renderer2.default)(this))
  1013. });
  1014. (0, _events_engine.on)($itemContainer, pointerDownEvent, pointerDownSelector, function(e) {
  1015. that._itemPointerDownHandler(e)
  1016. })
  1017. },
  1018. _itemClickHandler: function(e, $item) {
  1019. var itemData = this._getItemData($item);
  1020. var node = this._getNodeByElement($item);
  1021. this._itemDXEventHandler(e, "onItemClick", {
  1022. node: this._dataAdapter.getPublicNode(node)
  1023. });
  1024. if (this.option("selectByClick") && !e.isDefaultPrevented()) {
  1025. this._updateItemSelection(!node.internalFields.selected, itemData, e)
  1026. }
  1027. },
  1028. _updateSelectionToFirstItem: function($items, startIndex) {
  1029. var itemIndex = startIndex;
  1030. while (itemIndex >= 0) {
  1031. var $item = (0, _renderer2.default)($items[itemIndex]);
  1032. this._updateItemSelection(true, $item.find("." + ITEM_CLASS).get(0));
  1033. itemIndex--
  1034. }
  1035. },
  1036. _updateSelectionToLastItem: function($items, startIndex) {
  1037. var length = $items.length;
  1038. var itemIndex = startIndex;
  1039. while (itemIndex < length) {
  1040. var $item = (0, _renderer2.default)($items[itemIndex]);
  1041. this._updateItemSelection(true, $item.find("." + ITEM_CLASS).get(0));
  1042. itemIndex++
  1043. }
  1044. },
  1045. _focusInHandler: function(e) {
  1046. var _this12 = this;
  1047. this._updateFocusState(e, true);
  1048. if (this.option("focusedElement")) {
  1049. clearTimeout(this._setFocusedItemTimeout);
  1050. this._setFocusedItemTimeout = setTimeout(function() {
  1051. _this12._setFocusedItem((0, _renderer2.default)(_this12.option("focusedElement")))
  1052. });
  1053. return
  1054. }
  1055. var $activeItem = this._getActiveItem();
  1056. this.option("focusedElement", (0, _dom.getPublicElement)($activeItem.closest("." + NODE_CLASS)))
  1057. },
  1058. _setFocusedItem: function($target) {
  1059. if (!$target || !$target.length) {
  1060. return
  1061. }
  1062. if (!$target.children().hasClass(DISABLED_STATE_CLASS)) {
  1063. this.callBase($target)
  1064. }
  1065. this._scrollableContainer.scrollToElement($target.find("." + ITEM_CLASS).first())
  1066. },
  1067. _itemPointerDownHandler: function(e) {
  1068. if (!this.option("focusStateEnabled")) {
  1069. return
  1070. }
  1071. var $target = (0, _renderer2.default)(e.target).closest("." + NODE_CLASS + ", ." + SELECT_ALL_ITEM_CLASS);
  1072. if (!$target.length) {
  1073. return
  1074. }
  1075. var itemElement = $target.hasClass(DISABLED_STATE_CLASS) ? null : $target;
  1076. this.option("focusedElement", (0, _dom.getPublicElement)(itemElement))
  1077. },
  1078. _findNonDisabledNodes: function($nodes) {
  1079. return $nodes.not(function() {
  1080. return (0, _renderer2.default)(this).children("." + ITEM_CLASS).hasClass(DISABLED_STATE_CLASS)
  1081. })
  1082. },
  1083. _moveFocus: function(location, e) {
  1084. var FOCUS_UP = "up";
  1085. var FOCUS_DOWN = "down";
  1086. var FOCUS_FIRST = "first";
  1087. var FOCUS_LAST = "last";
  1088. var FOCUS_LEFT = this.option("rtlEnabled") ? "right" : "left";
  1089. var FOCUS_RIGHT = this.option("rtlEnabled") ? "left" : "right";
  1090. this.$element().find(".".concat(NODE_CONTAINER_CLASS)).each(function() {
  1091. _fx2.default.stop(this, true)
  1092. });
  1093. var $items = this._findNonDisabledNodes(this._nodeElements());
  1094. if (!$items || !$items.length) {
  1095. return
  1096. }
  1097. switch (location) {
  1098. case FOCUS_UP:
  1099. var $prevItem = this._prevItem($items);
  1100. this.option("focusedElement", (0, _dom.getPublicElement)($prevItem));
  1101. if (e.shiftKey && this._showCheckboxes()) {
  1102. this._updateItemSelection(true, $prevItem.find("." + ITEM_CLASS).get(0))
  1103. }
  1104. break;
  1105. case FOCUS_DOWN:
  1106. var $nextItem = this._nextItem($items);
  1107. this.option("focusedElement", (0, _dom.getPublicElement)($nextItem));
  1108. if (e.shiftKey && this._showCheckboxes()) {
  1109. this._updateItemSelection(true, $nextItem.find("." + ITEM_CLASS).get(0))
  1110. }
  1111. break;
  1112. case FOCUS_FIRST:
  1113. var $firstItem = $items.first();
  1114. if (e.shiftKey && this._showCheckboxes()) {
  1115. this._updateSelectionToFirstItem($items, $items.index(this._prevItem($items)))
  1116. }
  1117. this.option("focusedElement", (0, _dom.getPublicElement)($firstItem));
  1118. break;
  1119. case FOCUS_LAST:
  1120. var $lastItem = $items.last();
  1121. if (e.shiftKey && this._showCheckboxes()) {
  1122. this._updateSelectionToLastItem($items, $items.index(this._nextItem($items)))
  1123. }
  1124. this.option("focusedElement", (0, _dom.getPublicElement)($lastItem));
  1125. break;
  1126. case FOCUS_RIGHT:
  1127. this._expandFocusedContainer();
  1128. break;
  1129. case FOCUS_LEFT:
  1130. this._collapseFocusedContainer();
  1131. break;
  1132. default:
  1133. this.callBase.apply(this, arguments);
  1134. return
  1135. }
  1136. },
  1137. _nodeElements: function() {
  1138. return this.$element().find("." + NODE_CLASS).not(":hidden")
  1139. },
  1140. _expandFocusedContainer: function() {
  1141. var $focusedNode = (0, _renderer2.default)(this.option("focusedElement"));
  1142. if (!$focusedNode.length || $focusedNode.hasClass(IS_LEAF)) {
  1143. return
  1144. }
  1145. var $node = $focusedNode.find(".".concat(NODE_CONTAINER_CLASS)).eq(0);
  1146. if ($node.hasClass(OPENED_NODE_CONTAINER_CLASS)) {
  1147. var $nextItem = this._nextItem(this._findNonDisabledNodes(this._nodeElements()));
  1148. this.option("focusedElement", (0, _dom.getPublicElement)($nextItem));
  1149. return
  1150. }
  1151. var node = this._getNodeByElement($focusedNode.children("." + ITEM_CLASS));
  1152. this._toggleExpandedState(node, true)
  1153. },
  1154. _getClosestNonDisabledNode: function($node) {
  1155. do {
  1156. $node = $node.parent().closest("." + NODE_CLASS)
  1157. } while ($node.children(".dx-treeview-item.dx-state-disabled").length);
  1158. return $node
  1159. },
  1160. _collapseFocusedContainer: function() {
  1161. var $focusedNode = (0, _renderer2.default)(this.option("focusedElement"));
  1162. if (!$focusedNode.length) {
  1163. return
  1164. }
  1165. var nodeElement = $focusedNode.find(".".concat(NODE_CONTAINER_CLASS)).eq(0);
  1166. if (!$focusedNode.hasClass(IS_LEAF) && nodeElement.hasClass(OPENED_NODE_CONTAINER_CLASS)) {
  1167. var node = this._getNodeByElement($focusedNode.children("." + ITEM_CLASS));
  1168. this._toggleExpandedState(node, false)
  1169. } else {
  1170. var collapsedNode = this._getClosestNonDisabledNode($focusedNode);
  1171. collapsedNode.length && this.option("focusedElement", (0, _dom.getPublicElement)(collapsedNode))
  1172. }
  1173. },
  1174. updateDimensions: function() {
  1175. var _this13 = this;
  1176. var deferred = new _deferred.Deferred;
  1177. if (this._scrollableContainer) {
  1178. this._scrollableContainer.update().done(function() {
  1179. deferred.resolveWith(_this13)
  1180. })
  1181. } else {
  1182. deferred.resolveWith(this)
  1183. }
  1184. return deferred.promise()
  1185. },
  1186. selectItem: function(itemElement) {
  1187. this._updateItemSelection(true, itemElement)
  1188. },
  1189. unselectItem: function(itemElement) {
  1190. this._updateItemSelection(false, itemElement)
  1191. },
  1192. expandItem: function(itemElement) {
  1193. this._toggleExpandedState(itemElement, true)
  1194. },
  1195. collapseItem: function(itemElement) {
  1196. this._toggleExpandedState(itemElement, false)
  1197. },
  1198. getNodes: function() {
  1199. return this._dataAdapter.getTreeNodes()
  1200. },
  1201. getSelectedNodesKeys: function() {
  1202. return this._dataAdapter.getSelectedNodesKeys()
  1203. },
  1204. selectAll: function() {
  1205. if (this._selectAllEnabled()) {
  1206. this._$selectAllItem.dxCheckBox("instance").option("value", true)
  1207. } else {
  1208. this._toggleSelectAll({
  1209. value: true
  1210. })
  1211. }
  1212. },
  1213. unselectAll: function() {
  1214. if (this._selectAllEnabled()) {
  1215. this._$selectAllItem.dxCheckBox("instance").option("value", false)
  1216. } else {
  1217. this._toggleSelectAll({
  1218. value: false
  1219. })
  1220. }
  1221. },
  1222. expandAll: function() {
  1223. var dataAdapter = this._dataAdapter;
  1224. (0, _iterator.each)(dataAdapter.getData(), function(_, node) {
  1225. return dataAdapter.toggleExpansion(node.internalFields.key, true)
  1226. });
  1227. this.repaint()
  1228. },
  1229. collapseAll: function() {
  1230. (0, _iterator.each)(this._dataAdapter.getExpandedNodesKeys(), function(_, key) {
  1231. this._toggleExpandedState(key, false)
  1232. }.bind(this))
  1233. }
  1234. });
  1235. module.exports = TreeViewBase;