[FIX] website: searchbar: wrong usage of BS dropdown

Before this commit, we had a crash when a user types something in a
searchbar in the website (on /shop eg) and do keydowns:
"Cannot read properties of undefined (reading 'nextElementSibling')"

BS dropdown doesn't use JQuery anymore and is therefore less permissive
with empty arrays. Also note that the logic is different between BS4
and BS5.

To fix this, we need to make sure that all elements are in the DOM
before BS dropdown instanciation.
It's why we have to render the 'dropdown-menu' before the dropdown
constructor is triggered.

We also had to add the 'data-bs-toggle' attribute to let BS find it
to set '_element' (which must be the previous sibling of the dropdown-menu).
This data attribute was probably not set before because in this case
the BS dropdown is not used on a button or a link as documented;
we use it as an autocomplete functionnality.

closes odoo/odoo#98254

Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
This commit is contained in:
Adrien Dieudonné
2022-08-17 19:48:43 +02:00
parent 3021a676de
commit 358194e99a
@@ -33,6 +33,7 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
*/
start: function () {
this.$input = this.$('.search-query');
this.$searchGroup = this.$('.input-group');
this.searchType = this.$input.data('searchType');
this.order = this.$('.o_search_order_by').val();
@@ -149,7 +150,6 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
}
const $prevMenu = this.$menu;
this.$el.toggleClass('dropdown show', !!res);
if (res && this.limit) {
const results = res['results'];
let template = 'website.s_searchbar.autocomplete';
@@ -166,6 +166,7 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
widget: this,
}));
this.$menu.css('min-width', this.autocompleteMinWidth);
this.$searchGroup[0].dataset['bsToggle'] = 'dropdown';
// Handle the case where the searchbar is in a mega menu by making
// it position:fixed and forcing its size. Note: this could be the
@@ -201,6 +202,7 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
});
}
this.$el.toggleClass('dropdown show', !!res);
if ($prevMenu) {
$prevMenu.remove();
}