diff options
| author | Mohammed Shekha <msh@odoo.com> | 2020-04-07 12:32:43 +0000 |
|---|---|---|
| committer | Lucas Perais (lpe) <lpe@odoo.com> | 2020-08-20 12:37:36 +0000 |
| commit | ce69db55f80777b95015c23dc4b3fa1a6db5daad (patch) | |
| tree | 66675d808acc37302397eb6b28df6bed20c50479 /addons/web/static/src | |
| parent | 538b7f22cfdd39ce3dea66b36b46ced2de7ceaed (diff) | |
[IMP] web: set focus to first visible page when active page invisible
Before this commit: if there are modifiers based on field which hides
one page and show another and if active page get invisible then instead
of first page second page gets focus, consider following example,
`<form>
<field name="boolean"/>
<page name="page1" attrs='{"invisible": [["bar", "=", false]]}'></page>
<page name="page2" attrs='{"invisible": [["bar", "=", true]]}'></page>
<page name="page3"></page>
</form>`
Consider the initial boolean value to be true; initially the first page
will be visible. But when "bar" is unchecked then page1 will be hidden
and page3 will get the focus as page2 is still not visible: it will be
after the computaion/application of all modifiers, which is currently
done after the rendering of a tab page.
Now: the first visible tab is focused on rendering (same as before) but
also after all modifiers have been updated.
closes odoo/odoo#56209
X-original-commit: 10365572aa3629e9b19d2b29726b351275de9f52
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
Co-authored-by: Ipsita Borisagar <ibo@odoo.com>
Co-authored-by: Julien Mougenot <jum@odoo.com>
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/js/views/form/form_renderer.js | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 2b91c5820ee..97e3cbd8cb0 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -303,6 +303,28 @@ var FormRenderer = BasicRenderer.extend({ //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- + + /** + * Activates the first visible tab from a given list of tab objects. The + * first tab having an "autofocus" attribute set will be focused in + * priority. + * + * @private + * @param {Object[]} tabs + */ + _activateFirstVisibleTab(tabs) { + const visibleTabs = tabs.filter( + (tab) => !tab.$header.hasClass("o_invisible_modifier") + ); + const autofocusTab = visibleTabs.findIndex( + (tab) => tab.node.attrs.autofocus === "autofocus" + ); + const tabToFocus = visibleTabs[Math.max(0, autofocusTab)]; + if (tabToFocus) { + tabToFocus.$header.find('.nav-link').addClass('active'); + tabToFocus.$page.addClass('active'); + } + }, /** * @override */ @@ -932,7 +954,6 @@ var FormRenderer = BasicRenderer.extend({ var self = this; var $headers = $('<ul class="nav nav-tabs">'); var $pages = $('<div class="tab-content">'); - var autofocusTab = -1; // renderedTabs is used to aggregate the generated $headers and $pages // alongside their node, so that their modifiers can be registered once // all tabs have been rendered, to ensure that the first visible tab @@ -941,9 +962,6 @@ var FormRenderer = BasicRenderer.extend({ var pageID = _.uniqueId('notebook_page_'); var $header = self._renderTabHeader(child, pageID); var $page = self._renderTabPage(child, pageID); - if (autofocusTab === -1 && child.attrs.autofocus === 'autofocus') { - autofocusTab = index; - } self._handleAttributes($header, child); $headers.append($header); $pages.append($page); @@ -953,11 +971,6 @@ var FormRenderer = BasicRenderer.extend({ node: child, }; }); - if (renderedTabs.length) { - var tabToFocus = renderedTabs[Math.max(0, autofocusTab)]; - tabToFocus.$header.find('.nav-link').addClass('active'); - tabToFocus.$page.addClass('active'); - } // register the modifiers for each tab _.each(renderedTabs, function (tab) { self._registerModifiers(tab.node, self.state, tab.$header, { @@ -967,13 +980,12 @@ var FormRenderer = BasicRenderer.extend({ if (modifiers.invisible && $link.hasClass('active')) { $link.removeClass('active'); tab.$page.removeClass('active'); - var $firstVisibleTab = $headers.find('li:not(.o_invisible_modifier):first() > a'); - $firstVisibleTab.addClass('active'); - $pages.find($firstVisibleTab.attr('href')).addClass('active'); + self.inactiveNotebooks.push(renderedTabs); } }, }); }); + this._activateFirstVisibleTab(renderedTabs); var $notebookHeaders = $('<div class="o_notebook_headers">').append($headers); var $notebook = $('<div class="o_notebook">').append($notebookHeaders, $pages); $notebook[0].dataset.name = node.attrs.name || '_default_'; @@ -1028,6 +1040,7 @@ var FormRenderer = BasicRenderer.extend({ // render the form and evaluate the modifiers var defs = []; this.defs = defs; + this.inactiveNotebooks = []; var $form = this._renderNode(this.arch).addClass(this.className); delete this.defs; @@ -1051,6 +1064,20 @@ var FormRenderer = BasicRenderer.extend({ }); }, /** + * This method is overridden to activate the first notebook page if the + * current active page is invisible due to modifiers. This is done after + * all modifiers are applied on all page elements. + * + * @override + */ + async _updateAllModifiers() { + await this._super(...arguments); + for (const tabs of this.inactiveNotebooks) { + this._activateFirstVisibleTab(tabs); + } + this.inactiveNotebooks = []; + }, + /** * Updates the form's $el with new content. * * @private |
