Skip to content

Commit

Permalink
List: select next item after deletion (#25949)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexander Bulychev <[email protected]>
  • Loading branch information
iBat and Alexander Bulychev authored Nov 3, 2023
1 parent c436908 commit 0124e71
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 17 deletions.
16 changes: 16 additions & 0 deletions js/ui/list/ui.list.edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,22 @@ const ListEdit = ListBase.inherit({
*/
getItemByIndex(index) {
return this._editStrategy.getItemDataByIndex(index);
},

deleteItem(itemElement) {
const editStrategy = this._editStrategy;
const deletingElementIndex = editStrategy.getNormalizedIndex(itemElement);
const focusedElement = this.option('focusedElement');
const focusedItemIndex = focusedElement ? editStrategy.getNormalizedIndex(focusedElement) : deletingElementIndex;
const isLastIndexFocused = focusedItemIndex === this._getLastItemIndex();
const nextFocusedItem = isLastIndexFocused || deletingElementIndex < focusedItemIndex
? focusedItemIndex - 1
: focusedItemIndex;
const promise = this.callBase(itemElement);

return promise.done(function() {
return this.focusListItem(nextFocusedItem);
});
}
});

Expand Down
63 changes: 62 additions & 1 deletion testing/testcafe/tests/editors/list/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import createWidget from '../../../helpers/createWidget';
fixture`List`
.page(url(__dirname, '../../container.html'));

const createList = (selectionMode) => createWidget('dxList', {
const createList = (selectionMode, allowItemDeleting = false) => createWidget('dxList', {
items: ['item1', 'item2', 'item3'],
showSelectionControls: true,
selectionMode,
allowItemDeleting,
});

test('Should apply styles on selectAll checkbox after tab button press', async (t) => {
Expand Down Expand Up @@ -83,3 +84,63 @@ test('Should apply styles on selectAll checkbox after enter button press on it',
.ok(compareResults.errorMessages());
}).before(async () => createList(selectionMode));
});

test('Should select next item after delete by keyboard', async (t) => {
const list = new List('#container');
const firstItem = list.getItem(0);

await t
.expect(list.getVisibleItems().count).eql(3)
.click(firstItem.element)
.pressKey('delete');

const item = list.getItem(0);

await t.expect(item.isFocused)
.ok();
await t.expect(item.text)
.eql('item2');
await t
.expect(list.getItems().count).eql(2);
}).before(async () => createList('none', true));

test('Should select previous item after delete last item', async (t) => {
const list = new List('#container');
const lastItem = list.getItem(2);

await t
.expect(list.getVisibleItems().count).eql(3)
.click(lastItem.element)
.pressKey('delete');

const item = list.getItem(1);

await t.expect(item.isFocused)
.ok();
await t.expect(item.text)
.eql('item2');
await t
.expect(list.getItems().count).eql(2);
}).before(async () => createList('none', true));

[[2, 0], [1, 2]].forEach(([selectItemIdx, deleteItemIdx]) => {
test(`Should not change selection after delete another (not selected) item (${selectItemIdx}, ${selectItemIdx})`, async (t) => {
const list = new List('#container');
const itemToSelect = list.getItem(selectItemIdx);
const itemToDelete = list.getItem(deleteItemIdx);

await t
.expect(list.getVisibleItems().count).eql(3)
.click(itemToSelect.element)
.click(itemToDelete.element.find('.dx-button'));

const item = list.getItem(deleteItemIdx > selectItemIdx ? selectItemIdx : selectItemIdx - 1);

await t.expect(item.isFocused)
.ok();
await t.expect(item.text)
.eql(`item${selectItemIdx + 1}`);
await t
.expect(list.getItems().count).eql(2);
}).before(async () => createList('none', true));
});
34 changes: 18 additions & 16 deletions testing/tests/DevExpress.ui.widgets/listParts/commonTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1627,22 +1627,6 @@ QUnit.module('options changed', moduleSetup, () => {
assert.deepEqual(list.option('items'), [1, 2, 3, 4], 'item is not deleted');
});

QUnit.test('allowItemDeleting option changed from false to true', function(assert) {
const $list = $('#list').dxList({
items: [1, 2, 3, 4],
allowItemDeleting: false,
focusStateEnabled: true
});
const list = $list.dxList('instance');

list.option('allowItemDeleting', true);
list.focus();
const keyboard = getListKeyboard($list);
keyboard.keyDown('del');

assert.deepEqual(list.option('items'), [2, 3, 4], 'item is deleted');
});

QUnit.test('allowItemDeleting option changed twice', function(assert) {
const $list = $('#list').dxList({
items: [1, 2, 3, 4],
Expand Down Expand Up @@ -3977,6 +3961,24 @@ QUnit.module('keyboard navigation', {
$itemContainer.trigger($.Event('keydown', { key: 'Enter' }));
assert.equal(handler.callCount, 1);
});

QUnit.test('allow delete item using keyboard after set allowItemDeleting option from false to true', function(assert) {
const $list = $('#list').dxList({
items: [1, 2, 3, 4],
allowItemDeleting: false,
focusStateEnabled: true
});
const list = $list.dxList('instance');

list.option('allowItemDeleting', true);
list.focus();

const $itemContainer = $list.find(`.${LIST_ITEM_CLASS}`).eq(0).parent();

$itemContainer.trigger($.Event('keydown', { key: 'Delete' }));

assert.deepEqual(list.option('items'), [2, 3, 4], 'item is deleted');
});
});

QUnit.module('Search', () => {
Expand Down

0 comments on commit 0124e71

Please sign in to comment.