From ce9b350403ff7c1004b50b39588891ee652e0a3a Mon Sep 17 00:00:00 2001 From: Benjamin Vray Date: Wed, 20 Sep 2023 10:41:50 +0200 Subject: [PATCH] [FIX] website, web: fix dropdown hidden in mobile menu Steps to reproduce the bug: - Modify the website's menu to include only two items: a link to a page and a dropdown menu. - Switch to mobile preview. - Open the "Hamburger" menu. - Click on the dropdown toggle. - Bug: The dropdown menu is hidden and requires scrolling the navbar to see it. Since commit [1], dynamic positioning of dropdowns within a navbar has been enabled (before that, Bootstrap disabled it) but this change introduced this bug. To fix this, we disable dynamic positioning of the dropdowns when they are inside a "Hamburger" menu. [1]: https://github.com/odoo/odoo/commit/8689241f86e2d4ddb4e4510951f92b80e115b914 opw-3493512 closes odoo/odoo#137165 X-original-commit: 55bc21c9503bf3b319d94e10d73bf672385b455c Signed-off-by: Quentin Smetz (qsm) Signed-off-by: Benjamin Vray (bvr) --- .../static/src/legacy/js/libs/bootstrap.js | 5 ++- addons/website/static/src/js/content/menu.js | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/legacy/js/libs/bootstrap.js b/addons/web/static/src/legacy/js/libs/bootstrap.js index e8adeb1971e..20f28a1f506 100644 --- a/addons/web/static/src/legacy/js/libs/bootstrap.js +++ b/addons/web/static/src/legacy/js/libs/bootstrap.js @@ -153,10 +153,11 @@ ScrollSpy.prototype._activate = function (target) { * Bootstrap disables dynamic dropdown positioning when it is in a navbar. Here * we make this patch to activate this dynamic navbar's dropdown positioning * which is useful to avoid that the elements of the website sub-menus overflow - * the page. + * the page. Note that when the menu is "hamburger" type, we leave dynamic + * positioning disabled. */ Dropdown.prototype._detectNavbar = function () { - return false; + return this._element.closest(".navbar-collapse.show"); }; /* Bootstrap modal scrollbar compensation on non-body */ diff --git a/addons/website/static/src/js/content/menu.js b/addons/website/static/src/js/content/menu.js index fcecdb6d5c4..b4c3b9495f0 100644 --- a/addons/website/static/src/js/content/menu.js +++ b/addons/website/static/src/js/content/menu.js @@ -652,6 +652,51 @@ publicWidget.registry.HeaderMainCollapse = publicWidget.Widget.extend({ }, }); +publicWidget.registry.navbarDropdown = animations.Animation.extend({ + selector: "header .navbar", + disabledInEditableMode: false, + events: { + "shown.bs.collapse": "_onCollapseShown", + "hidden.bs.collapse": "_onCollapseHidden", + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Updates the Dropdowns to trigger the "_detectNavbar" function from the + * Bootstrap Dropdown class. This allows the dropdowns to adapt based on + * whether they are located within a hamburger menu. If they are not inside + * an "hamburger" style menu, automatic dropdown positioning is enabled + * using popper.js. + * + * @private + */ + _updateDropdowns() { + for (const toggleEl of this.el.querySelectorAll(".nav .dropdown-toggle")) { + Dropdown.getOrCreateInstance(toggleEl).update(); + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + */ + _onCollapseShown() { + this._updateDropdowns(); + }, + /** + * @private + */ + _onCollapseHidden() { + this._updateDropdowns(); + }, +}); + export default { extraMenuUpdateCallbacks: extraMenuUpdateCallbacks, };