From acf994dabbdf9f2e8273f933576cfa2e43e7c67a Mon Sep 17 00:00:00 2001 From: Sergey Novikov <57402891+novsstation@users.noreply.github.com> Date: Fri, 24 Jan 2020 11:29:57 +0300 Subject: [PATCH] TabPanel - Fix active tab switching on focusIn (T852689) (#11583) (#11677) * Fix active tab switching on focusIn (T852689) * Tests for fix T852689 * Small refactoring * Small fix * Tests improvements * Small refactoring * Test refactorings * Tests improvements * fix tests for non jquery enviroment * Small fix * Small test refactoring * Fix test for mobile devices * Fix focusing for mobile devices * Fix focusing logic * Small refactoring * Small fixes * Pull request feedback * Tets fix * Small refactoring * Small fix * Refactoring * Small tests refactoring * Small tests refactoring * Small test refactoring * Tests refactorings --- js/ui/tab_panel.js | 12 +++++- .../DevExpress.ui.widgets/tabPanel.tests.js | 43 ++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/js/ui/tab_panel.js b/js/ui/tab_panel.js index c6b5d53fbd03..a26ccc1d258e 100644 --- a/js/ui/tab_panel.js +++ b/js/ui/tab_panel.js @@ -309,7 +309,17 @@ const TabPanel = MultiView.inherit({ this._tabs.repaint(); break; case 'selectedIndex': - case 'selectedItem': + case 'selectedItem': { + this._setTabsOption(fullName, value); + this.callBase(args); + + if(this.option('focusStateEnabled') === true) { + const selectedIndex = this.option('selectedIndex'); + const selectedTabContent = this._itemElements().eq(selectedIndex); + this.option('focusedElement', getPublicElement(selectedTabContent)); + } + break; + } case 'itemHoldTimeout': case 'focusStateEnabled': case 'hoverStateEnabled': diff --git a/testing/tests/DevExpress.ui.widgets/tabPanel.tests.js b/testing/tests/DevExpress.ui.widgets/tabPanel.tests.js index 4186c938f613..0b5ac479f5a6 100644 --- a/testing/tests/DevExpress.ui.widgets/tabPanel.tests.js +++ b/testing/tests/DevExpress.ui.widgets/tabPanel.tests.js @@ -33,6 +33,7 @@ QUnit.testStart(() => { const TABS_CLASS = 'dx-tabs'; const MULTIVIEW_ITEM_CLASS = 'dx-multiview-item'; const TABS_ITEM_CLASS = 'dx-tab'; +const SELECTED_TAB_CLASS = 'dx-tab-selected'; const SELECTED_ITEM_CLASS = 'dx-item-selected'; const TABPANEL_CONTAINER_CLASS = 'dx-tabpanel-container'; @@ -478,6 +479,46 @@ QUnit.module('focus policy', { $tabPanel.trigger('focusin'); assert.equal(tabNativeFocus.callCount, 0, 'native focus should not be triggered'); }); + + function checkSelectionAndFocus(tabPanel, expectedSelectedIndex) { + const $tabPanel = tabPanel.$element(); + const expectedSelectedItem = tabPanel.option('items')[expectedSelectedIndex]; + + QUnit.assert.equal(tabPanel.option('selectedItem'), expectedSelectedItem, 'tabPanel.option(selectedItem)'); + QUnit.assert.equal($tabPanel.find(`.${MULTIVIEW_ITEM_CLASS}.${SELECTED_ITEM_CLASS}`).get(0).innerText, 'content ' + expectedSelectedIndex, 'tabPanel.SELECTED_ITEM_CLASS'); + + QUnit.assert.equal(tabPanel._tabs.option('selectedItem'), expectedSelectedItem, 'tabPanel._tabs.option(selectedItem)'); + QUnit.assert.equal($tabPanel.find(`.${TABS_ITEM_CLASS}.${SELECTED_TAB_CLASS}`).get(0).innerText, 'tab ' + expectedSelectedIndex, 'tabPanel._tabs.SELECTED_TAB_CLASS'); + + if(tabPanel.option('focusStateEnabled') === true) { + QUnit.assert.equal($(tabPanel.option('focusedElement')).text(), 'content ' + expectedSelectedIndex, 'tabPanel.options(focusedElement)'); + QUnit.assert.equal($(tabPanel._tabs.option('focusedElement')).text(), 'tab ' + expectedSelectedIndex, 'tabPanel._tabs.focusedElement'); + } else { + QUnit.assert.equal(tabPanel.option('focusedElement'), null, 'tabPanel.option(focusedElement)'); + QUnit.assert.equal(tabPanel._tabs.option('focusedElement'), null, 'tabPanel._tabs.options(focusedElement)'); + } + } + + [0, 1].forEach(selectedIndex => { + ['selectedIndex', 'selectedItem'].forEach(optionName => { + QUnit.test(`focus -> setSelectedTab(${selectedIndex}) -> focus`, function(assert) { + const $tabPanel = $('#tabPanel').dxTabPanel({ + items: [{ tabTemplate: 'tab 0', template: 'content 0' }, { tabTemplate: 'tab 1', template: 'content 1' }] + }); + const tabPanel = $tabPanel.dxTabPanel('instance'); + + $tabPanel.focusin(); + if(optionName === 'selectedIndex') { + tabPanel.option('selectedIndex', selectedIndex); + } else { + tabPanel.option('selectedItem', tabPanel.option('items')[selectedIndex]); + } + $tabPanel.focusin(); + + checkSelectionAndFocus(tabPanel, selectedIndex); + }); + }); + }); }); QUnit.module('keyboard navigation', { @@ -532,7 +573,6 @@ QUnit.module('keyboard navigation', { this.clock.tick(); const tabsFocusedIndex = $(this.instance.option('focusedElement')).index(); - assert.equal(isRenderer(this.instance.option('focusedElement')), !!config().useJQuery, 'focusedElement is correct'); assert.equal(tabsFocusedIndex, 1, 'second tabs element has been focused'); assert.equal(tabsFocusedIndex, $(this.instance.option('focusedElement')).index(), 'multiView focused element is equal tabs focused element'); @@ -597,4 +637,3 @@ QUnit.module('dataSource integration', () => { assert.equal(dataSourceLoadCalled, 1, 'dataSource load called once'); }); }); -