Skip to content

Commit

Permalink
TreeView: fix selectByClick selection after changing showCheckboxesMo…
Browse files Browse the repository at this point in the history
…de to 'selectAll' at runtime (T1190412) (#25736)
  • Loading branch information
AlexanderMoiseev authored Oct 4, 2023
1 parent 1a20dd6 commit cf73011
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 21 deletions.
66 changes: 47 additions & 19 deletions js/ui/tree_view/ui.tree_view.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,13 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
},

_checkBoxModeChange: function(value, previousValue) {
const searchEnabled = this.option('searchEnabled');
const previousSelectAllEnabled = this._selectAllEnabled(previousValue);
const previousItemsContainer = this._itemContainer(searchEnabled, previousSelectAllEnabled);

this._detachClickEvent(previousItemsContainer);
this._detachExpandEvent(previousItemsContainer);

if(previousValue === 'none' || value === 'none') {
return;
}
Expand Down Expand Up @@ -307,7 +314,7 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
this.repaint();
break;
case 'expandEvent':
this._initExpandEvent();
this._attachExpandEvent();
break;
case 'deferRendering':
case 'dataStructure':
Expand Down Expand Up @@ -583,7 +590,7 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
}
this._renderItems($nodeContainer, this._dataAdapter.getRootNodes());

this._initExpandEvent();
this._attachExpandEvent();

if(this._selectAllEnabled()) {
this._createSelectAllValueChangedAction();
Expand Down Expand Up @@ -679,8 +686,9 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
return this.option('expandIcon') || this.option('collapseIcon');
},

_selectAllEnabled: function() {
return this.option('showCheckBoxesMode') === 'selectAll' && !this._isSingleSelection();
_selectAllEnabled: function(showCheckBoxesMode) {
const mode = showCheckBoxesMode ?? this.option('showCheckBoxesMode');
return mode === 'selectAll' && !this._isSingleSelection();
},

_renderItems: function($nodeContainer, nodes) {
Expand Down Expand Up @@ -827,13 +835,16 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
}
},

_initExpandEvent: function() {
_attachExpandEvent: function() {
const expandedEventName = this._getEventNameByOption(this.option('expandEvent'));
const $itemsContainer = this._itemContainer();
const itemSelector = this._itemSelector();

eventsEngine.off($itemsContainer, '.' + EXPAND_EVENT_NAMESPACE, itemSelector);
eventsEngine.on($itemsContainer, expandedEventName, itemSelector, this._expandEventHandler.bind(this));
this._detachExpandEvent($itemsContainer);
eventsEngine.on($itemsContainer, expandedEventName, this._itemSelector(), this._expandEventHandler.bind(this));
},

_detachExpandEvent(itemsContainer) {
eventsEngine.off(itemsContainer, `.${EXPAND_EVENT_NAMESPACE}`, this._itemSelector());
},

_getEventNameByOption: function(name) {
Expand Down Expand Up @@ -1415,23 +1426,40 @@ const TreeViewBase = HierarchicalCollectionWidget.inherit({
},

_attachClickEvent: function() {
const clickSelector = '.' + this._itemClass();
const pointerDownSelector = '.' + NODE_CLASS + ', .' + SELECT_ALL_ITEM_CLASS;
const eventName = addNamespace(clickEventName, this.NAME);
const pointerDownEvent = addNamespace(pointerEvents.down, this.NAME);
const $itemContainer = this._itemContainer();
this._detachClickEvent($itemContainer);

const that = this;
eventsEngine.off($itemContainer, eventName, clickSelector);
eventsEngine.off($itemContainer, pointerDownEvent, pointerDownSelector);
eventsEngine.on($itemContainer, eventName, clickSelector, function(e) {
that._itemClickHandler(e, $(this));
const { clickEventNamespace, itemSelector, pointerDownEventNamespace, nodeSelector } = this._getItemClickEventData();

eventsEngine.on($itemContainer, clickEventNamespace, itemSelector, (e) => {
this._itemClickHandler(e, $(e.currentTarget));
});
eventsEngine.on($itemContainer, pointerDownEvent, pointerDownSelector, function(e) {
that._itemPointerDownHandler(e);
eventsEngine.on($itemContainer, pointerDownEventNamespace, nodeSelector, (e) => {
this._itemPointerDownHandler(e);
});
},

_detachClickEvent: function(itemsContainer) {
const { clickEventNamespace, itemSelector, pointerDownEventNamespace, nodeSelector } = this._getItemClickEventData();

eventsEngine.off(itemsContainer, clickEventNamespace, itemSelector);
eventsEngine.off(itemsContainer, pointerDownEventNamespace, nodeSelector);
},

_getItemClickEventData: function() {
const itemSelector = `.${this._itemClass()}`;
const nodeSelector = `.${NODE_CLASS}, .${SELECT_ALL_ITEM_CLASS}`;
const clickEventNamespace = addNamespace(clickEventName, this.NAME);
const pointerDownEventNamespace = addNamespace(pointerEvents.down, this.NAME);

return {
clickEventNamespace,
itemSelector,
pointerDownEventNamespace,
nodeSelector
};
},

_itemClick: function(actionArgs) {
const args = actionArgs.args[0];
const target = args.event.target[0] || args.event.target;
Expand Down
6 changes: 4 additions & 2 deletions js/ui/tree_view/ui.tree_view.search.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ const TreeViewSearch = TreeViewBase.inherit(searchBoxMixin).inherit({
this.$element().empty();
},

_itemContainer: function(isSearchMode) {
if(this._selectAllEnabled()) {
_itemContainer: function(isSearchMode, selectAllEnabled) {
selectAllEnabled ??= this._selectAllEnabled();

if(selectAllEnabled) {
return this._getNodeContainer();
}

Expand Down
28 changes: 28 additions & 0 deletions testing/tests/DevExpress.ui.widgets/treeViewParts/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,34 @@ module('selection single', () => {
treeView.checkSelected([0], items);
});

test('selectByClick selection should work correctly after runtime "showCheckBoxesMode" option change (T1190412)', function(assert) {
const items = [{ text: 'item 1' }, { text: 'item 2' }];
const treeView = createInstance({
items: items,
selectByClick: true,
});

treeView.instance.option('showCheckBoxesMode', 'selectAll');

eventsEngine.trigger(treeView.getItems().eq(0), 'dxclick');

treeView.checkSelected([0], items);
});

QUnit.test('expandEvent should work correctly after runtime "showCheckBoxesMode" option change', function(assert) {
const items = [{ text: 'Item 1', items: [{ text: 'Item 11' }] }];
const treeView = createInstance({
items: items,
expandEvent: 'click'
});

treeView.instance.option('showCheckBoxesMode', 'selectAll');

eventsEngine.trigger(treeView.getItems().eq(0), 'dxclick');

assert.ok(items[0].expanded);
});

test('selectByClick option should unselect item by second click', function(assert) {
const items = [{ text: 'item 1' }, { text: 'item 2' }];
const treeView = createInstance({
Expand Down

0 comments on commit cf73011

Please sign in to comment.