From 50a1a60db1a3f1cef3abc5757ee6034598cfed02 Mon Sep 17 00:00:00 2001 From: Nikki Gonzales <38495263+nikkithelegendarypokemonster@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:34:26 +0800 Subject: [PATCH] MultiView: Fix search traversal of visible items during loop (#28186) --- .../js/__internal/ui/m_multi_view.ts | 3 +- .../DevExpress.ui.widgets/multiView.tests.js | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/devextreme/js/__internal/ui/m_multi_view.ts b/packages/devextreme/js/__internal/ui/m_multi_view.ts index 2134da9b44ac..bbc5676e62c3 100644 --- a/packages/devextreme/js/__internal/ui/m_multi_view.ts +++ b/packages/devextreme/js/__internal/ui/m_multi_view.ts @@ -112,8 +112,9 @@ const MultiView = CollectionWidget.inherit({ const step = direction > 0 ? -1 : 1; const lastNotLoopedIndex = step === -1 ? 0 : count - 1; + while (!this._isItemVisible(index) && (loop || index !== lastNotLoopedIndex)) { - index = (index + step) % count; + index = (index + step + count) % count; } return index; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/multiView.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/multiView.tests.js index cdf0559df0c2..baa3c0ba3d14 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/multiView.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/multiView.tests.js @@ -819,6 +819,56 @@ QUnit.module('loop', { delete this.animationStartAction; } }, () => { + QUnit.test('if first item is invisible and swiped right last item should be selected', function(assert) { + const $multiView = $('#multiView').dxMultiView({ + items: [ + { text: '1', visible: false }, + { text: '2', visible: true }, + { text: '3', visible: true } + ], + loop: true, + selectedIndex: 1 + }); + + const instance = $multiView.dxMultiView('instance'); + const $firstItem = $multiView.find(`.${MULTIVIEW_ITEM_CLASS}`).eq(1); + const $lastItem = $multiView.find(`.${MULTIVIEW_ITEM_CLASS}`).eq(2); + const pointer = pointerMock($multiView); + + this.animationStartAction = function() { + assert.equal(position($firstItem), 0, 'item "2" is positioned correctly as the first visible item.'); + assert.equal(position($lastItem), -800, 'item "3" is positioned correctly as the last visible item.'); + }; + + pointer.start().swipeStart().swipe(0.1).swipeEnd(1); + assert.strictEqual(instance.option('selectedIndex'), 2, 'item "3" is selected'); + }); + + QUnit.test('if last item is invisible and swiped left first item should be selected', function(assert) { + const $multiView = $('#multiView').dxMultiView({ + items: [ + { text: '1', visible: true }, + { text: '2', visible: true }, + { text: '3', visible: false } + ], + loop: true, + selectedIndex: 1 + }); + + const instance = $multiView.dxMultiView('instance'); + const $firstItem = $multiView.find(`.${MULTIVIEW_ITEM_CLASS}`).eq(0); + const $lastItem = $multiView.find(`.${MULTIVIEW_ITEM_CLASS}`).eq(1); + const pointer = pointerMock($multiView); + + this.animationStartAction = function() { + assert.equal(position($firstItem), 800, 'item "1" is positioned correctly as the first visible item.'); + assert.equal(position($lastItem), 0, 'item "2" is positioned correctly as the last visible item.'); + }; + + pointer.start().swipeStart().swipe(-0.1).swipeEnd(-1); + assert.strictEqual(instance.option('selectedIndex'), 0, 'item "1" is selected'); + }); + QUnit.test('when only one item is visible, swipe action does not move the current visible item', function(assert) { const $multiView = $('#multiView').dxMultiView({ items: [