diff --git a/js/ui/list/ui.list.edit.js b/js/ui/list/ui.list.edit.js index 8b7208dc6365..c6dd537f6aa3 100644 --- a/js/ui/list/ui.list.edit.js +++ b/js/ui/list/ui.list.edit.js @@ -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); + }); } }); diff --git a/testing/testcafe/tests/editors/list/focus.ts b/testing/testcafe/tests/editors/list/focus.ts index c1bfccc1b3c1..c18140373298 100644 --- a/testing/testcafe/tests/editors/list/focus.ts +++ b/testing/testcafe/tests/editors/list/focus.ts @@ -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) => { @@ -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)); +}); diff --git a/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js b/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js index 9124a9855733..4eb85b1c2e06 100644 --- a/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js +++ b/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js @@ -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], @@ -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', () => {