Skip to content

Commit

Permalink
Selection: fix selection cache updating after selection change is can…
Browse files Browse the repository at this point in the history
…celed (#28141)
  • Loading branch information
ksercs authored Oct 7, 2024
1 parent 3cab76c commit cc75a32
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export default class StandardStrategy extends SelectionStrategy {
const { selectedItems, selectedItemKeys, keyHashIndices } = this.options;

this._storedSelectionState = {
keyHashIndices: { ...keyHashIndices },
keyHashIndices: JSON.stringify(keyHashIndices),
selectedItems: [...selectedItems],
selectedItemKeys: [...selectedItemKeys],
};
Expand All @@ -524,7 +524,7 @@ export default class StandardStrategy extends SelectionStrategy {
const { selectedItemKeys, selectedItems, keyHashIndices } = this._storedSelectionState!;
this._setOption('selectedItemKeys', selectedItemKeys);
this._setOption('selectedItems', selectedItems);
this._setOption('keyHashIndices', keyHashIndices);
this._setOption('keyHashIndices', JSON.parse(keyHashIndices));
}

_onePageSelectAll(isDeselect: boolean): DeferredObj<unknown> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,54 @@ QUnit.module('onSelectionChanging', {
assert.strictEqual(selectionChangingHandler.callCount, 2, 'selectionChanging is called once');
});

QUnit.test('isItemSelected should work correctly after selection change is cancelled', function(assert) {
let cancelSelectionChange = false;
const selectionChangingHandler = sinon.spy((args) => {
args.cancel = cancelSelectionChange;
});

const selection = new Selection({
...this.basicSelectionConfig,
onSelectionChanging: selectionChangingHandler
});

this.dataSource.load();

const firstItem = this.data[0];

cancelSelectionChange = false;
selection.select(firstItem);

cancelSelectionChange = true;
selection.deselect(firstItem);

const isFirstItemSelected = selection.isItemSelected(firstItem);
assert.strictEqual(isFirstItemSelected, true, 'item is still selected after canceled deselect');
});

QUnit.test('getSelectAllState should work correctly after selection change is cancelled', function(assert) {
let cancelSelectionChange = false;
const selectionChangingHandler = sinon.spy((args) => {
args.cancel = cancelSelectionChange;
});

const selection = new Selection({
...this.basicSelectionConfig,
onSelectionChanging: selectionChangingHandler
});

this.dataSource.load();

cancelSelectionChange = false;
selection.selectAll(true);

cancelSelectionChange = true;
selection.deselect(true);

const areAllItemsSelected = selection.getSelectAllState(true);
assert.strictEqual(areAllItemsSelected, true, 'items are still selected after canceled deselectAll');
});

QUnit.module('select all by one page', {
beforeEach: function() {
this.dataSource = createDataSource(this.data, {}, { paginate: true, pageSize: 3 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,50 @@ module('onSelectionChanging event', () => {
assert.strictEqual(instance.option('selectedIndex'), 1, 'selectedIndex should be updated');
});

QUnit.test('if e.cancel is false even if previous request was cancelled and dataSource.store.key is used', function(assert) {
let cancelSelectionChange = false;
const selectionChangingHandler = sinon.spy((e) => {
e.cancel = cancelSelectionChange;
});
const selectionChangedHandler = sinon.stub();

const $element = $('#cmp');
const instance = new TestComponent($element, {
dataSource: new DataSource({
store: new ArrayStore({
key: 'id',
data: [{ text: '1', id: 1 }, { text: '2', id: 2 }],
}),
}),
selectionMode: 'multiple',
onSelectionChanging: selectionChangingHandler,
onSelectionChanged: selectionChangedHandler
});

assert.strictEqual(instance.option('selectedIndex'), -1, 'no item is selected initially');

const $items = $(instance.itemElements());
const $firstItem = $items.eq(0);

cancelSelectionChange = false;
$firstItem.trigger('dxclick');
assert.strictEqual(selectionChangingHandler.callCount, 1, 'selectionChanging should be raised once');
assert.strictEqual(selectionChangedHandler.callCount, 1, 'selectionChanged should be raised once');
assert.strictEqual(instance.option('selectedIndex'), 0, 'item is selected');

cancelSelectionChange = true;
$firstItem.trigger('dxclick');
assert.strictEqual(selectionChangingHandler.callCount, 2, 'selectionChanging should be raised once');
assert.strictEqual(selectionChangedHandler.callCount, 1, 'selectionChanged is not raised');
assert.strictEqual(instance.option('selectedIndex'), 0, 'item is still selected');

cancelSelectionChange = false;
$firstItem.trigger('dxclick');
assert.strictEqual(selectionChangingHandler.callCount, 3, 'selectionChanging should be raised once');
assert.strictEqual(selectionChangedHandler.callCount, 2, 'selectionChanged is raised');
assert.strictEqual(instance.option('selectedIndex'), -1, 'item is deselected');
});

QUnit.test('if e.cancel is a promise resolved with false', function(assert) {
const done = assert.async();

Expand Down

0 comments on commit cc75a32

Please sign in to comment.