summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2018-03-14 16:21:14 +0100
committerqsm-odoo <qsm@odoo.com>2018-07-27 12:36:54 +0200
commit1c1c0897e8eca607c7f1b96b68a06c026c543e6a (patch)
tree1f667224be28146cbcbe602892094046052ea93b /addons/web
parent220e49f9d66f2e2ea875143c2da0c20919ec0b3e (diff)
[REF] *: BS4, adapt dropdowns and carets
- The dropdown structure was simplified, allowing to get rid of the 3-levels structure induced by <ul/> elements and dropdowns can now contain anything. The class 'dropdown-item' is now mandatory for each dropdown clickable element. The class 'dropdown-item-text' can be used to add same padding and style but without making the element have a clickable look. - Dividers now use the class 'dropdown-divider' - The way dropdowns are opened and hidden also changed (before the 'open' class was added on the `.dropdown-menu` parent, now the 'show' class is added on both the `.dropdown-menu` parent and the `.dropdown-menu` itself). - JS-wise, no click event handlers can be put on `.dropdown-toggle` elements anymore (instead, use handlers for dropdown events). - Carets are automatically put on `.dropdown-toggle` elements, so this commit replaces the `.caret` elements with this. This feature was possible to disable but would prevent us from adding a caret with scss. Also, this simplifies the DOM. The 'o-no-caret' class was also introduced to allow using the 'dropdown-toggle' class on non-caret elements. - Also adapt the scss to use $caret-width instead of $caret-width-base
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/static/src/js/chrome/sidebar.js9
-rw-r--r--addons/web/static/src/js/chrome/user_menu.js2
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js18
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js6
-rw-r--r--addons/web/static/src/js/views/graph/graph_controller.js8
-rw-r--r--addons/web/static/src/js/views/pivot/pivot_controller.js13
-rw-r--r--addons/web/static/src/js/views/search/favorites_menu.js25
-rw-r--r--addons/web/static/src/js/views/search/filters_menu.js4
-rw-r--r--addons/web/static/src/js/views/search/groupby_menu.js6
-rw-r--r--addons/web/static/src/js/views/search/search_inputs.js8
-rw-r--r--addons/web/static/src/js/widgets/data_export.js20
-rw-r--r--addons/web/static/src/js/widgets/debug_manager.js8
-rw-r--r--addons/web/static/src/js/widgets/domain_selector.js2
-rw-r--r--addons/web/static/src/js/widgets/dropdown_menu.js14
-rw-r--r--addons/web/static/src/js/widgets/switch_company_menu.js6
-rw-r--r--addons/web/static/src/scss/dropdown.scss15
-rw-r--r--addons/web/static/src/scss/dropdown_menu.scss29
-rw-r--r--addons/web/static/src/scss/form_view.scss2
-rw-r--r--addons/web/static/src/scss/kanban_view.scss6
-rw-r--r--addons/web/static/src/scss/navbar.scss34
-rw-r--r--addons/web/static/src/scss/search_groupby_menu.scss16
-rw-r--r--addons/web/static/src/scss/search_view.scss17
-rw-r--r--addons/web/static/src/scss/ui.scss6
-rw-r--r--addons/web/static/src/scss/utils.scss37
-rw-r--r--addons/web/static/src/xml/base.xml276
-rw-r--r--addons/web/static/src/xml/kanban.xml16
-rw-r--r--addons/web/static/tests/fields/basic_fields_tests.js52
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js2
-rw-r--r--addons/web/static/tests/views/form_tests.js4
-rw-r--r--addons/web/static/tests/views/graph_tests.js12
-rw-r--r--addons/web/static/tests/views/kanban_tests.js6
-rw-r--r--addons/web/static/tests/views/list_tests.js4
-rw-r--r--addons/web/static/tests/views/pivot_tests.js47
-rw-r--r--addons/web/static/tests/views/search_filters_menu_tests.js38
-rw-r--r--addons/web/static/tests/views/search_groupby_menu_tests.js18
-rw-r--r--addons/web/static/tests/views/search_view_tests.js42
-rw-r--r--addons/web/static/tests/widgets/dropdown_menu_tests.js38
-rw-r--r--addons/web/views/webclient_templates.xml5
38 files changed, 416 insertions, 455 deletions
diff --git a/addons/web/static/src/js/chrome/sidebar.js b/addons/web/static/src/js/chrome/sidebar.js
index 47d598aaeb8..d02c936f470 100644
--- a/addons/web/static/src/js/chrome/sidebar.js
+++ b/addons/web/static/src/js/chrome/sidebar.js
@@ -11,7 +11,7 @@ var _t = core._t;
var Sidebar = Widget.extend({
events: {
- "click .dropdown-menu li a": "_onDropdownClicked"
+ "click .dropdown-item": "_onDropdownClicked"
},
/**
* @override
@@ -177,9 +177,10 @@ var Sidebar = Widget.extend({
this.$el.html(QWeb.render('Sidebar', {widget: this}));
// Hides Sidebar sections when item list is empty
- this.$('.o_dropdown').each(function () {
- if (!$(this).find('li').length) {
- $(this).hide();
+ _.each(this.$('.o_dropdown'), function (el) {
+ var $dropdown = $(el);
+ if (!$dropdown.find('.dropdown-item').length) {
+ $dropdown.hide();
}
});
this.$("[title]").tooltip({
diff --git a/addons/web/static/src/js/chrome/user_menu.js b/addons/web/static/src/js/chrome/user_menu.js
index 84c16b51f82..1251c9b6b5b 100644
--- a/addons/web/static/src/js/chrome/user_menu.js
+++ b/addons/web/static/src/js/chrome/user_menu.js
@@ -23,7 +23,7 @@ var UserMenu = Widget.extend({
start: function () {
var self = this;
var session = this.getSession();
- this.$el.on('click', 'li a[data-menu]', function (ev) {
+ this.$el.on('click', '[data-menu]', function (ev) {
ev.preventDefault();
var menu = $(this).data('menu');
self['_onMenu' + menu.charAt(0).toUpperCase() + menu.slice(1)]();
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index 51816220c9f..00092073d6a 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -1612,10 +1612,7 @@ var AttachmentImage = AbstractField.extend({
var StateSelectionWidget = AbstractField.extend({
template: 'FormSelection',
events: {
- 'click a': function (e) {
- e.preventDefault();
- },
- 'click li': '_setSelection'
+ 'click .dropdown-item': '_setSelection',
},
supportedFieldTypes: ['selection'],
@@ -1696,13 +1693,12 @@ var StateSelectionWidget = AbstractField.extend({
* @param {MouseEvent} ev
*/
_setSelection: function (ev) {
- var li = $(ev.target).closest('li');
- if (li.length) {
- var value = String(li.data('value'));
- this._setValue(value);
- if (this.mode === 'edit') {
- this._render();
- }
+ ev.preventDefault();
+ var $item = $(ev.currentTarget);
+ var value = String($item.data('value'));
+ this._setValue(value);
+ if (this.mode === 'edit') {
+ this._render();
}
},
});
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 5d4e2ad4cb5..a0bb82d569f 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -363,11 +363,11 @@ var FormRenderer = BasicRenderer.extend({
text: _t("More"),
}));
- var $ul = $("<ul>", {'class': "dropdown-menu o_dropdown_more", role: "menu"});
+ var $dropdown = $("<div>", {'class': "dropdown-menu o_dropdown_more", role: "menu"});
_.each(folded_buttons, function ($button) {
- $('<li>').appendTo($ul).append($button);
+ $button.addClass('dropdown-item').appendTo($dropdown);
});
- $ul.appendTo($result);
+ $dropdown.appendTo($result);
}
this._handleAttributes($result, node);
diff --git a/addons/web/static/src/js/views/graph/graph_controller.js b/addons/web/static/src/js/views/graph/graph_controller.js
index 36a05af7653..b6a1c121f0f 100644
--- a/addons/web/static/src/js/views/graph/graph_controller.js
+++ b/addons/web/static/src/js/views/graph/graph_controller.js
@@ -161,8 +161,9 @@ var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{
this.$buttons
.find('.o_graph_button[data-mode="' + state.mode + '"]')
.addClass('active');
- this.$measureList.find('li').each(function (index, li) {
- $(li).toggleClass('selected', $(li).data('field') === state.measure);
+ _.each(this.$measureList.find('.dropdown-item'), function (item) {
+ var $item = $(item);
+ $item.toggleClass('selected', $item.data('field') === state.measure);
});
},
@@ -185,8 +186,7 @@ var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{
} else if ($target.parents('.o_graph_measures_list').length) {
event.preventDefault();
event.stopPropagation();
- parent = $target.parent();
- field = parent.data('field');
+ field = $target.data('field');
this._setMeasure(field);
}
},
diff --git a/addons/web/static/src/js/views/pivot/pivot_controller.js b/addons/web/static/src/js/views/pivot/pivot_controller.js
index f0976c9a8b4..945cc132b03 100644
--- a/addons/web/static/src/js/views/pivot/pivot_controller.js
+++ b/addons/web/static/src/js/views/pivot/pivot_controller.js
@@ -164,9 +164,9 @@ var PivotController = AbstractController.extend({
fields: fields
}));
- this.$fieldSelection.find('ul').first()
+ this.$fieldSelection.find('.dropdown-menu').first()
.css({top: top, left: left})
- .show();
+ .addClass('show');
},
/**
* @private
@@ -186,7 +186,7 @@ var PivotController = AbstractController.extend({
var state = this.model.get({raw: true});
_.each(this.measures, function (measure, name) {
var isSelected = _.contains(state.measures, name);
- self.$buttons.find('li[data-field="' + name + '"]')
+ self.$buttons.find('.dropdown-item[data-field="' + name + '"]')
.toggleClass('selected', isSelected);
});
},
@@ -215,8 +215,7 @@ var PivotController = AbstractController.extend({
.then(this.update.bind(this, {}, {reload: false}));
}
if ($target.parents('.o_pivot_measures_list').length) {
- var parent = $target.parent();
- var field = parent.data('field');
+ var field = $target.data('field');
event.preventDefault();
event.stopPropagation();
this.model
@@ -298,11 +297,11 @@ var PivotController = AbstractController.extend({
_onFieldMenuSelection: function (event) {
event.preventDefault();
var $target = $(event.target);
- if ($target.parent().hasClass('disabled')) {
+ if ($target.hasClass('disabled')) {
event.stopPropagation();
return;
}
- var field = $target.parent().data('field');
+ var field = $target.data('field');
var interval = $target.data('interval');
var header = this.model.getHeader(this.lastHeaderSelected);
if (interval) {
diff --git a/addons/web/static/src/js/views/search/favorites_menu.js b/addons/web/static/src/js/views/search/favorites_menu.js
index 1e62ffb5ce3..47e99aec573 100644
--- a/addons/web/static/src/js/views/search/favorites_menu.js
+++ b/addons/web/static/src/js/views/search/favorites_menu.js
@@ -14,14 +14,11 @@ var _t = core._t;
return Widget.extend({
template: 'SearchView.FavoriteMenu',
events: {
- 'click li': function (event) {
- event.stopImmediatePropagation();
+ 'click .dropdown-item': function (ev) {
+ ev.preventDefault();
},
- 'click li a': function (event) {
- event.preventDefault();
- },
- 'click .o_save_search a': function (event) {
- event.preventDefault();
+ 'click .o_save_search': function (ev) {
+ ev.preventDefault();
this.toggle_save_menu();
},
'click .o_save_name button': 'save_favorite',
@@ -49,8 +46,8 @@ return Widget.extend({
this.$save_search = this.$('.o_save_search');
this.$save_name = this.$('.o_save_name');
this.$inputs = this.$save_name.find('input');
- this.$user_divider = this.$('.divider.user_filter');
- this.$shared_divider = this.$('.divider.shared_filter');
+ this.$user_divider = this.$('.dropdown-divider.user_filter');
+ this.$shared_divider = this.$('.dropdown-divider.shared_filter');
this.$inputs.eq(0).val(this.searchview.get_title());
var $shared_filter = this.$inputs.eq(1),
$default_filter = this.$inputs.eq(2);
@@ -207,7 +204,7 @@ return Widget.extend({
};
},
clear_selection: function () {
- this.$('li.selected').removeClass('selected');
+ this.$('.selected').removeClass('selected');
},
/**
* Adds a filter description to the filters dict
@@ -230,10 +227,10 @@ return Widget.extend({
this.$shared_divider.show();
}
if (!(key in this.$filters)) {
- var $filter = $('<li>')
+ var $filter = $('<div>', {class: 'position-relative'})
.addClass(filter.user_id ? 'o-searchview-custom-private'
: 'o-searchview-custom-public')
- .append($('<a>', {'href': '#'}).text(filter.name))
+ .append($('<a>', {href: '#', class: 'dropdown-item'}).text(filter.name))
.append($('<span>', {
class: 'fa fa-trash-o o-remove-filter',
on: {
@@ -256,7 +253,7 @@ return Widget.extend({
});
if (current) {
this.query.remove(current);
- this.$filters[this.key_for(filter)].removeClass('selected');
+ this.$filters[this.key_for(filter)].find('.dropdown-item').removeClass('selected');
return;
}
this.query.reset([this.facet_for(filter)], {
@@ -268,7 +265,7 @@ return Widget.extend({
this.searchview.dataset.set_sort(sort_items);
}
- this.$filters[this.key_for(filter)].addClass('selected');
+ this.$filters[this.key_for(filter)].find('.dropdown-item').addClass('selected');
},
remove_filter: function (filter, $filter, key) {
var self = this;
diff --git a/addons/web/static/src/js/views/search/filters_menu.js b/addons/web/static/src/js/views/search/filters_menu.js
index 221f98faa97..cf79bec2640 100644
--- a/addons/web/static/src/js/views/search/filters_menu.js
+++ b/addons/web/static/src/js/views/search/filters_menu.js
@@ -76,7 +76,7 @@ var FiltersMenu = DropdownMenu.extend({
category: 'filterCategory',
title: 'Filters',
icon: 'fa fa-filter',
- symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'
+ symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : false,
};
this._super(parent, dropdownHeader, filters, this.fields);
},
@@ -88,7 +88,7 @@ var FiltersMenu = DropdownMenu.extend({
* @private
*/
start: function () {
- this.$menu = this.$('ul.o_dropdown_menu');
+ this.$menu = this.$('.o_dropdown_menu');
this.$menu.addClass('o_filters_menu');
var generatorMenu = QWeb.render('FiltersMenuGenerator', {widget: this});
this.$menu.append(generatorMenu);
diff --git a/addons/web/static/src/js/views/search/groupby_menu.js b/addons/web/static/src/js/views/search/groupby_menu.js
index 7be61ae6606..8540e702589 100644
--- a/addons/web/static/src/js/views/search/groupby_menu.js
+++ b/addons/web/static/src/js/views/search/groupby_menu.js
@@ -14,7 +14,7 @@ var DEFAULT_INTERVAL = 'month';
var GroupByMenu = DropdownMenu.extend({
events: _.extend({}, DropdownMenu.prototype.events,
{
- 'click .o_add_custom_group a': '_onAddCustomGroupClick',
+ 'click .o_add_custom_group': '_onAddCustomGroupClick',
'click button.o_apply_group': '_onButtonApplyClick',
'click .o_group_selector': '_onGroupSelectorClick',
}),
@@ -85,7 +85,7 @@ var GroupByMenu = DropdownMenu.extend({
category: 'groupByCategory',
title: 'Group By',
icon: 'fa fa-bars',
- symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret',
+ symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : false,
style: style,
};
this._super(parent, dropdownHeader, groupbys, options);
@@ -98,7 +98,7 @@ var GroupByMenu = DropdownMenu.extend({
* @private
*/
start: function () {
- this.$menu = this.$('ul.o_dropdown_menu');
+ this.$menu = this.$('.o_dropdown_menu');
this.$menu.addClass('o_group_by_menu');
var $generatorMenu = QWeb.render('GroupbyMenuGenerator', {widget: this});
this.$menu.append($generatorMenu);
diff --git a/addons/web/static/src/js/views/search/search_inputs.js b/addons/web/static/src/js/views/search/search_inputs.js
index ee179d7da74..81f53ee4053 100644
--- a/addons/web/static/src/js/views/search/search_inputs.js
+++ b/addons/web/static/src/js/views/search/search_inputs.js
@@ -503,8 +503,13 @@ var ManyToOneField = CharField.extend({
var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{
template: 'SearchView.filters',
+ events: {
+ click: 'toggle_filter',
+ },
+
icon: "fa-filter",
completion_label: _lt("Filter on: %s"),
+
/**
* Inclusive group of filters, creates a continuous "button" with clickable
* sections (the normal display for filters is to be a self-contained button)
@@ -536,7 +541,6 @@ var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{
this.searchview.query.on('add remove change reset', this.proxy('search_change'));
},
start: function () {
- this.$el.on('click', 'a', this.proxy('toggle_filter'));
return $.when(null);
},
/**
@@ -684,7 +688,7 @@ var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{
toggle_filter: function (e) {
e.preventDefault();
e.stopPropagation();
- this.toggle(this.filters[Number($(e.target).parent().data('index'))]);
+ this.toggle(this.filters[Number($(e.currentTarget).data('index'))]);
},
toggle: function (filter, options) {
this.searchview.query.toggle(this.make_facet([this.make_value(filter)]), options);
diff --git a/addons/web/static/src/js/widgets/data_export.js b/addons/web/static/src/js/widgets/data_export.js
index 30e17604077..d05bf2d33fc 100644
--- a/addons/web/static/src/js/widgets/data_export.js
+++ b/addons/web/static/src/js/widgets/data_export.js
@@ -49,7 +49,7 @@ var DataExport = Dialog.extend({
function process_children() {
var $this = $(this);
- if($this.hasClass('open')) {
+ if($this.hasClass('show')) {
$this.children('.o_export_tree_item')
.addClass('o_selected')
.each(process_children);
@@ -77,19 +77,19 @@ var DataExport = Dialog.extend({
switch(e.keyCode || e.which) {
case $.ui.keyCode.LEFT:
- if ($elem.hasClass('open')) {
+ if ($elem.hasClass('show')) {
this.on_expand_action(record);
}
break;
case $.ui.keyCode.RIGHT:
- if (!$elem.hasClass('open')) {
+ if (!$elem.hasClass('show')) {
this.on_expand_action(record);
}
break;
case $.ui.keyCode.UP:
var $prev = $elem.prev('.o_export_tree_item');
if($prev.length === 1) {
- while($prev.hasClass('open')) {
+ while($prev.hasClass('show')) {
$prev = $prev.children('.o_export_tree_item').last();
}
} else {
@@ -104,7 +104,7 @@ var DataExport = Dialog.extend({
break;
case $.ui.keyCode.DOWN:
var $next;
- if($elem.hasClass('open')) {
+ if($elem.hasClass('show')) {
$next = $elem.children('.o_export_tree_item').first();
} else {
$next = $elem.next('.o_export_tree_item');
@@ -408,7 +408,7 @@ var DataExport = Dialog.extend({
var self = this;
if(expansion) {
this.$('.o_export_tree_item[data-id="' + expansion + '"]')
- .addClass('open')
+ .addClass('show')
.find('.o_expand_parent')
.toggleClass('fa-chevron-right fa-chevron-down')
.next()
@@ -429,8 +429,8 @@ var DataExport = Dialog.extend({
},
show_content: function(id) {
var $this = this.$('.o_export_tree_item[data-id="' + id + '"]');
- $this.toggleClass('open');
- var is_open = $this.hasClass('open');
+ $this.toggleClass('show');
+ var is_open = $this.hasClass('show');
$this.children('.o_expand_parent').toggleClass('fa-chevron-down', !!is_open).toggleClass('fa-chevron-right', !is_open);
@@ -441,8 +441,8 @@ var DataExport = Dialog.extend({
if(!is_open) {
$child.hide();
} else if(child_len === $child_field.eq(i).data('id').split("/").length) {
- if ($child.hasClass('open')) {
- $child.removeClass('open');
+ if ($child.hasClass('show')) {
+ $child.removeClass('show');
$child.children('.o_expand_parent').removeClass('fa-chevron-down').addClass('fa-chevron-right');
}
$child.show();
diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js
index 4eee9266594..d553387f153 100644
--- a/addons/web/static/src/js/widgets/debug_manager.js
+++ b/addons/web/static/src/js/widgets/debug_manager.js
@@ -23,12 +23,12 @@ var DebugManager = Widget.extend({
template: "WebClient.DebugManager",
events: {
"click a[data-action]": "perform_callback",
- "mouseover .o_debug_dropdowns > li:not(.open)": function(e) {
+ "mouseover .o_debug_dropdowns > li:not(.show)": function(e) {
// Open other dropdowns on mouseover
- var $opened = this.$('.o_debug_dropdowns > li.open');
+ var $opened = this.$('.o_debug_dropdowns > li.show');
if($opened.length) {
- $opened.removeClass('open');
- $(e.currentTarget).addClass('open').find('> a').focus();
+ $opened.removeClass('show');
+ $(e.currentTarget).addClass('show').find('> a').focus();
}
},
},
diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js
index c5a561b1b77..dab0c97108b 100644
--- a/addons/web/static/src/js/widgets/domain_selector.js
+++ b/addons/web/static/src/js/widgets/domain_selector.js
@@ -161,7 +161,7 @@ var DomainNode = Widget.extend({
var DomainTree = DomainNode.extend({
template: "DomainTree",
events: _.extend({}, DomainNode.prototype.events, {
- "click .o_domain_tree_operator_selector > ul > li > a": "_onOperatorChange",
+ "click .o_domain_tree_operator_selector .dropdown-item": "_onOperatorChange",
}),
custom_events: {
// If a domain child sends a request to add a child or remove one, call
diff --git a/addons/web/static/src/js/widgets/dropdown_menu.js b/addons/web/static/src/js/widgets/dropdown_menu.js
index 410d915dc9a..6f8f78a13d5 100644
--- a/addons/web/static/src/js/widgets/dropdown_menu.js
+++ b/addons/web/static/src/js/widgets/dropdown_menu.js
@@ -11,8 +11,8 @@ var QWeb = core.qweb;
var DropdownMenu = Widget.extend({
template: 'web.DropdownMenu',
events: {
- 'click li.o_menu_item': '_onItemClick',
- 'click li.o_item_option': '_onOptionClick',
+ 'click .o_menu_item': '_onItemClick',
+ 'click .o_item_option': '_onOptionClick',
'click span.o_trash_button': '_onTrashClick',
'hidden.bs.dropdown': '_onBootstrapClose',
},
@@ -44,12 +44,12 @@ var DropdownMenu = Widget.extend({
this.dropdownCategory = dropdownHeader.category;
this.dropdownTitle = dropdownHeader.title;
this.dropdownIcon = dropdownHeader.icon;
- this.dropdownSymbol = dropdownHeader.symbol || 'caret';
+ this.dropdownSymbol = dropdownHeader.symbol || false;
// this parameter fixes the menu style. By default,
// the style used is the one used in the search view
this.dropdownStyle = dropdownHeader.style || {
el: {class: 'btn-group o_dropdown', attrs: {}},
- mainButton: {class: 'o_dropdown_toggler_btn btn btn-secondary dropdown-toggle'},
+ mainButton: {class: 'o_dropdown_toggler_btn btn btn-secondary dropdown-toggle' + (this.dropdownSymbol ? ' o-no-caret' : '')},
};
this.items = items;
_.each(this.items, this._prepareItem.bind(this));
@@ -105,8 +105,8 @@ var DropdownMenu = Widget.extend({
*/
_renderMenuItems: function () {
var newMenuItems = QWeb.render('DropdownMenu.MenuItems', {widget: this});
- this.$el.find('.o_menu_item,.divider[data-removable="1"]').remove();
- this.$('ul.o_dropdown_menu').prepend($(newMenuItems));
+ this.$el.find('.o_menu_item, .dropdown-divider[data-removable="1"]').remove();
+ this.$('.o_dropdown_menu').prepend($(newMenuItems));
},
/**
* this function computes some default values for some of the item keys
@@ -189,7 +189,7 @@ var DropdownMenu = Widget.extend({
* @param {jQueryEvent} event
*/
_onBootstrapClose: function () {
- _.each(this.items, function(item) {
+ _.each(this.items, function (item) {
item.isOpen = false;
});
this._renderMenuItems();
diff --git a/addons/web/static/src/js/widgets/switch_company_menu.js b/addons/web/static/src/js/widgets/switch_company_menu.js
index 01c224370d2..c9498950a04 100644
--- a/addons/web/static/src/js/widgets/switch_company_menu.js
+++ b/addons/web/static/src/js/widgets/switch_company_menu.js
@@ -18,7 +18,7 @@ var _t = core._t;
var SwitchCompanyMenu = Widget.extend({
template: 'SwitchCompanyMenu',
events: {
- 'click .dropdown-menu li a[data-menu]': '_onClick',
+ 'click .dropdown-item[data-menu]': '_onClick',
},
/**
* @override
@@ -53,8 +53,8 @@ var SwitchCompanyMenu = Widget.extend({
} else {
a = '<span style="margin-right: 24px;"/>';
}
- companiesList += '<li><a href="#" data-menu="company" data-company-id="' +
- company[0] + '">' + a + company[1] + '</a></li>';
+ companiesList += '<a href="#" class="dropdown-item" data-menu="company" data-company-id="' +
+ company[0] + '">' + a + company[1] + '</a>';
});
this.$('.dropdown-menu').html(companiesList);
return this._super();
diff --git a/addons/web/static/src/scss/dropdown.scss b/addons/web/static/src/scss/dropdown.scss
index 9a60d78d9d3..8287e098b32 100644
--- a/addons/web/static/src/scss/dropdown.scss
+++ b/addons/web/static/src/scss/dropdown.scss
@@ -5,7 +5,7 @@
.ui-autocomplete { // Copy style of bootstrap dropdown
background-image: none;
background-color: $dropdown-bg;
- border: 1px solid $dropdown-border;
+ border: $dropdown-border-width solid $dropdown-border-color;
font-size: $font-size-base;
padding: 5px 0px;
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.176);
@@ -41,7 +41,7 @@
.o_inline_dropdown {
position: relative;
- &> .dropdown-menu {
+ & > .dropdown-menu {
top: 0;
left: 100%;
}
@@ -52,9 +52,12 @@
}
@mixin dropdown-menu-mixin {
- .open .dropdown-menu > li {
- position: relative; // to allow absolute positionning inside the li
- > a {
+ .show .dropdown-menu {
+ > * {
+ position: relative; // to allow absolute positionning inside the items
+ }
+
+ .dropdown-item {
&:focus, &:active, &:focus:active {
outline: none;
}
@@ -62,7 +65,7 @@
@extend %dropdown-li-a-padding;
}
- &.dropdown-header {
+ .dropdown-header {
@extend %dropdown-li-a-padding;
color: $o-main-text-color;
diff --git a/addons/web/static/src/scss/dropdown_menu.scss b/addons/web/static/src/scss/dropdown_menu.scss
index 8024783d3c2..8f5b0c1f00a 100644
--- a/addons/web/static/src/scss/dropdown_menu.scss
+++ b/addons/web/static/src/scss/dropdown_menu.scss
@@ -1,38 +1,23 @@
.o_dropdown_menu {
- > li.divider:first-child {
+ > .dropdown-divider:first-child {
display: none;
}
- max-height: calc(100vh - 125px);
+ max-height: calc(100vh - 125px); // FIXME
overflow: auto;
- .o_submenu_switcher {
- float:right;
- width: 25px;
- text-align: center;
- }
- .o_trash_button {
- float:right;
- + .o_submenu_switcher {
- margin-right: 6px;
- }
- }
- ul {
- list-style-type: none;
- padding-left: 20px;
- }
- li.o_menu_item {
+ .o_menu_item {
position: relative;
- > a {
+ > .dropdown-item {
color: $o-main-text-color;
- padding-right: 25px;
+
&:hover {
color: darken($o-main-text-color, 10%);
}
}
&.selected {
- > a {
+ > .dropdown-item {
color: darken($o-main-text-color, 10%);
font-weight: bold;
&:before {
@@ -43,7 +28,7 @@
}
}
}
- li.divider:first-child {
+ .dropdown-divider:first-child {
display: none;
}
.o_item_option {
diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss
index f6537e8cd07..51c584c916e 100644
--- a/addons/web/static/src/scss/form_view.scss
+++ b/addons/web/static/src/scss/form_view.scss
@@ -274,7 +274,7 @@
padding: 5px 0 2px 0;
min-width: 100px;
- > li > .btn {
+ .dropdown-item.btn {
min-width: 100%;
margin-bottom: 3px;
}
diff --git a/addons/web/static/src/scss/kanban_view.scss b/addons/web/static/src/scss/kanban_view.scss
index b377a93a0eb..bd595243d84 100644
--- a/addons/web/static/src/scss/kanban_view.scss
+++ b/addons/web/static/src/scss/kanban_view.scss
@@ -150,7 +150,7 @@
@include o-kanban-dropdown;
margin: (-$o-kanban-inside-vgutter - 1px) (-$o-kanban-inside-hgutter - 1px) 0 0;
}
- &.open .dropdown-toggle {
+ &.show .dropdown-toggle {
@include o-kanban-dropdown-open;
}
.dropdown-menu {
@@ -159,7 +159,7 @@
}
}
- &:hover .o_dropdown_kanban, .o_dropdown_kanban.open {
+ &:hover .o_dropdown_kanban, .o_dropdown_kanban.show {
visibility: visible;
}
@@ -342,7 +342,7 @@
margin-left: $o-kanban-inside-hgutter*2;
}
- &:hover .o_kanban_config, .o_kanban_config.open {
+ &:hover .o_kanban_config, .o_kanban_config.show {
visibility: visible;
margin-left: $o-kanban-inside-hgutter;
}
diff --git a/addons/web/static/src/scss/navbar.scss b/addons/web/static/src/scss/navbar.scss
index 9a3f3d9a718..66a080cf1bd 100644
--- a/addons/web/static/src/scss/navbar.scss
+++ b/addons/web/static/src/scss/navbar.scss
@@ -86,7 +86,7 @@
width: $o-navbar-height;
text-align: center;
}
- &.open > ul {
+ &.show > ul {
padding: 0;
> li {
@@ -115,27 +115,23 @@
&.o_menu_systray {
float: right;
- .open .dropdown-menu {
- left: auto;
- right: 0;
- }
}
}
- .open .dropdown-menu {
+ .dropdown-menu.show {
max-height: 90vh; // the dropdown should not overstep the viewport
min-width: 100%;
overflow: auto;
margin-top: 0;
@for $index from 3 through 5 {
- > li.o_menu_header_lvl_#{$index}, > li .o_menu_entry_lvl_#{$index} {
+ .o_menu_header_lvl_#{$index}, .o_menu_entry_lvl_#{$index} {
padding-left: $o-dropdown-hpadding + ($index - 2)*12px;
}
}
}
- .open .dropdown-toggle {
+ .show .dropdown-toggle {
background-color: $o-navbar-inverse-link-hover-bg;
}
.o_user_menu {
@@ -165,7 +161,7 @@
display: none;
}
- &.open .dropdown-menu {
+ .dropdown-menu.show {
max-height: none;
}
}
@@ -173,7 +169,7 @@
&.o_menu_sections {
width: 100%;
- > li.open .dropdown-menu {
+ .dropdown-menu.show {
position: static;
float: none;
background-color: transparent;
@@ -181,7 +177,7 @@
border: none;
overflow: visible;
- > li > a {
+ > .dropdown-item {
background-color: transparent;
color: inherit;
}
@@ -196,7 +192,7 @@
> li {
display: inline-block;
- &.open .dropdown-menu {
+ .dropdown-menu.show {
@include o-position-absolute($o-navbar-height, 0, 0, 0);
position: fixed;
width: auto;
@@ -225,10 +221,10 @@
}
@include media-breakpoint-down(md) {
- .o_switch_company_menu > .dropdown-menu {
- padding-top: 0px;
- li.bg-info {
- padding: 10px;
- }
- }
- }
+ .o_switch_company_menu > .dropdown-menu {
+ padding-top: 0px;
+ .bg-info {
+ padding: 10px;
+ }
+ }
+}
diff --git a/addons/web/static/src/scss/search_groupby_menu.scss b/addons/web/static/src/scss/search_groupby_menu.scss
deleted file mode 100644
index 4092b4b5fb7..00000000000
--- a/addons/web/static/src/scss/search_groupby_menu.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-// Group By
-.o_group_by_menu {
- @include o-selected-li;
-
- max-height: calc(100vh - 125px);
- overflow: auto;
-
- .o_add_group { // add button
- @include o-search-options-dropdown-custom-li;
- }
-
- .o_submenu_switcher {
- position: absolute;
- right: 0px;
- }
-}
diff --git a/addons/web/static/src/scss/search_view.scss b/addons/web/static/src/scss/search_view.scss
index 0ad27f5c391..700c13f7e84 100644
--- a/addons/web/static/src/scss/search_view.scss
+++ b/addons/web/static/src/scss/search_view.scss
@@ -1,5 +1,4 @@
-@mixin o-search-options-dropdown-custom-li {
- margin: 3px 25px;
+@mixin o-search-options-dropdown-custom-item {
width: auto;
max-width: 250px;
}
@@ -116,7 +115,7 @@
color: darken($o-main-text-color, 10%);
}
}
- &.open > a {
+ &.show > a {
font-weight: bold;
color: darken($o-main-text-color, 10%);
}
@@ -130,7 +129,7 @@
a:before {
@include o-caret-right;
@include o-position-absolute($top: 50%, $left: 10px);
- margin-top: (-$caret-width-base);
+ margin-top: (-$caret-width);
}
}
.o_open_menu {
@@ -138,7 +137,7 @@
a:before {
@include o-caret-down;
@include o-position-absolute($top: 50%, $left: 10px);
- margin-top: (-$caret-width-base);
+ margin-top: (-$caret-width);
}
}
@@ -150,7 +149,7 @@
overflow: auto;
.o_filter_condition {
- @include o-search-options-dropdown-custom-li;
+ @include o-search-options-dropdown-custom-item;
margin-bottom: 8px;
.o_or_filter { // or between conditions
display: none; // hidden for the first condition
@@ -177,7 +176,7 @@
}
.o_add_filter_menu { // apply and add buttons
display: none; // Needed by the webclient
- @include o-search-options-dropdown-custom-li;
+ @include o-search-options-dropdown-custom-item;
}
.o_submenu_switcher {
position: absolute;
@@ -196,7 +195,7 @@
max-height: calc(100vh - 125px);
overflow: auto;
- .divider {display: none;} // hide the divider by default (no favorite)
+ .dropdown-divider {display: none;} // hide the divider by default (no favorite)
.o-searchview-custom-private, .o-searchview-custom-public {
.o-remove-filter {
@include o-position-absolute(50%, 12px);
@@ -212,6 +211,6 @@
}
.o_save_name { // save button
display: none; // hidden by default
- @include o-search-options-dropdown-custom-li;
+ @include o-search-options-dropdown-custom-item;
}
}
diff --git a/addons/web/static/src/scss/ui.scss b/addons/web/static/src/scss/ui.scss
index d88f21f83a1..e30a3d59d20 100644
--- a/addons/web/static/src/scss/ui.scss
+++ b/addons/web/static/src/scss/ui.scss
@@ -13,3 +13,9 @@
[aria-hidden="true"], [aria-hidden="1"] {
display: none!important;
}
+
+.dropdown-toggle.o-no-caret {
+ &::before, &::after {
+ content: normal;
+ }
+}
diff --git a/addons/web/static/src/scss/utils.scss b/addons/web/static/src/scss/utils.scss
index 4b76f10b1d2..a01ba14f5a4 100644
--- a/addons/web/static/src/scss/utils.scss
+++ b/addons/web/static/src/scss/utils.scss
@@ -72,7 +72,7 @@
// ------------------------------------------------------------------
// Caret
// ------------------------------------------------------------------
-@mixin o-caret-down($caret-width: $caret-width-base) {
+@mixin o-caret-down($caret-width: $caret-width) {
@include utils-caret-boilerplate;
border-bottom: 0;
border-left: $caret-width solid transparent;
@@ -80,7 +80,7 @@
border-top: $caret-width solid;
-moz-transform: scale(0.9999); // Smooth the caret on firefox
}
-@mixin o-caret-up($caret-width: $caret-width-base) {
+@mixin o-caret-up($caret-width: $caret-width) {
@include utils-caret-boilerplate;
border-bottom: $caret-width solid;
border-left: $caret-width solid transparent;
@@ -88,7 +88,7 @@
border-top: 0;
-moz-transform: scale(0.9999); // Smooth the caret on firefox
}
-@mixin o-caret-left($caret-width: $caret-width-base) {
+@mixin o-caret-left($caret-width: $caret-width) {
@include utils-caret-boilerplate;
border-bottom: $caret-width solid transparent;
border-left: 0;
@@ -96,7 +96,7 @@
border-top: $caret-width solid transparent;
-moz-transform: scale(0.9999); // Smooth the caret on firefox
}
-@mixin o-caret-right($caret-width: $caret-width-base) {
+@mixin o-caret-right($caret-width: $caret-width) {
@include utils-caret-boilerplate;
border-bottom: $caret-width solid transparent;
border-left: $caret-width solid;
@@ -108,25 +108,22 @@
// ------------------------------------------------------------------
// Dropdowns
// ------------------------------------------------------------------
-@mixin o-selected-li {
- li {
+@mixin o-selected-li { // FIXME use active ?
+ .dropdown-item {
position: relative;
- > a {
- color: $o-main-text-color;
- &:hover {
- color: darken($o-main-text-color, 10%);
- }
+ color: $o-main-text-color;
+ &:hover {
+ color: darken($o-main-text-color, 10%);
}
+
&.selected {
- > a {
- color: darken($o-main-text-color, 10%);
- font-weight: bold;
- &:before {
- font-family: FontAwesome;
- position: absolute;
- left: 6px;
- content: "\f00c";
- }
+ color: darken($o-main-text-color, 10%);
+ font-weight: bold;
+ &:before {
+ font-family: FontAwesome;
+ position: absolute;
+ left: 6px;
+ content: "\f00c";
}
}
}
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 376aeb58e41..1eaa2e59b84 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -231,31 +231,31 @@
<a href="#" title="Open Developer Tools" aria-label="Open Developer Tools" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1">
<span class="fa fa-bug"/>
</a>
- <ul class="dropdown-menu o_debug_dropdown" role="menu"/>
+ <div class="dropdown-menu dropdown-menu-right o_debug_dropdown" role="menu"/>
</li>
</t>
<t t-name="WebClient.DebugManager.Global">
- <li><a role="menuitem" href="#" data-action="perform_js_tests">Run JS Tests</a></li>
- <li><a role="menuitem" href="#" data-action="perform_js_mobile_tests">Run JS Mobile Tests</a></li>
- <li><a role="menuitem" href="#" data-action="select_view">Open View</a></li>
+ <a role="menuitem" href="#" data-action="perform_js_tests" class="dropdown-item">Run JS Tests</a>
+ <a role="menuitem" href="#" data-action="perform_js_mobile_tests" class="dropdown-item">Run JS Mobile Tests</a>
+ <a role="menuitem" href="#" data-action="select_view" class="dropdown-item">Open View</a>
<t t-if="manager._events">
- <li class="divider" role="separator"/>
- <li><a role="menuitem" href="#" data-action="show_timelines">Toggle Timelines</a></li>
- <li><a role="menuitem" href="#" data-action="requests_clear">Clear Events</a></li>
+ <div class="dropdown-divider" role="separator"/>
+ <a role="menuitem" href="#" data-action="show_timelines" class="dropdown-item">Toggle Timelines</a>
+ <a role="menuitem" href="#" data-action="requests_clear" class="dropdown-item">Clear Events</a>
</t>
- <li class="divider o_debug_leave_section" role="separator"/>
- <li><a role="menuitem" href="#" data-action="split_assets">Activate Assets Debugging</a></li>
- <li><a role="menuitem" href="#" data-action="regenerateAssets">Regenerate Assets Bundles</a></li>
- <li><a role="menuitem" href="#" data-action="leave_debug_mode">Leave the Developer Tools</a></li>
+ <div class="dropdown-divider o_debug_leave_section" role="separator"/>
+ <a role="menuitem" href="#" data-action="split_assets" class="dropdown-item">Activate Assets Debugging</a>
+ <a role="menuitem" href="#" data-action="regenerateAssets" class="dropdown-item">Regenerate Assets Bundles</a>
+ <a role="menuitem" href="#" data-action="leave_debug_mode" class="dropdown-item">Leave the Developer Tools</a>
</t>
<t t-name="WebClient.DebugManager.Action">
<t t-if="action">
- <li class="divider" role="separator"/>
- <li><a role="menuitem" href="#" data-action="edit" t-att-data-model="action.type" t-att-data-id="action.id">Edit Action</a></li>
+ <div class="dropdown-divider" role="separator"/>
+ <a role="menuitem" href="#" data-action="edit" t-att-data-model="action.type" t-att-data-id="action.id" class="dropdown-item">Edit Action</a>
<t t-if="action.res_model">
- <li><a role="menuitem" href="#" data-action="get_view_fields">View Fields</a></li>
- <li><a role="menuitem" href="#" data-action="manage_filters">Manage Filters</a></li>
- <li><a role="menuitem" href="#" data-action="translate">Technical Translation</a></li>
+ <a role="menuitem" href="#" data-action="get_view_fields" class="dropdown-item">View Fields</a>
+ <a role="menuitem" href="#" data-action="manage_filters" class="dropdown-item">Manage Filters</a>
+ <a role="menuitem" href="#" data-action="translate" class="dropdown-item">Technical Translation</a>
</t>
</t>
</t>
@@ -272,21 +272,19 @@
</t>
<t t-name="WebClient.DebugManager.View">
<t t-if="view">
- <li role="separator" class="divider"/>
+ <div role="separator" class="dropdown-divider"/>
<t t-if="view.type === 'form'">
- <li><a role="menuitem" href="#" data-action="set_defaults">Set Defaults</a></li>
+ <a role="menuitem" href="#" data-action="set_defaults" class="dropdown-item">Set Defaults</a>
<t t-if="controller.getSelectedIds().length === 1">
- <li><a role="menuitem" href="#" data-action="get_metadata">View Metadata</a></li>
+ <a role="menuitem" href="#" data-action="get_metadata" class="dropdown-item">View Metadata</a>
</t>
</t>
- <li><a role="menuitem" href="#" data-action="fvg">Fields View Get</a></li>
+ <a role="menuitem" href="#" data-action="fvg" class="dropdown-item">Fields View Get</a>
<t t-if="can_edit">
- <li>
- <a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fieldsView.view_id">
+ <a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fieldsView.view_id" class="dropdown-item">
Edit View: <t t-esc="_.str.capitalize(view.type)"/>
- </a>
- </li>
- <li t-if="searchview and searchview.$el.is(':visible')"><a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="action.searchFieldsView.view_id">Edit SearchView</a></li>
+ </a>
+ <a t-if="searchview and searchview.$el.is(':visible')" role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="action.searchFieldsView.view_id" class="dropdown-item">Edit SearchView</a>
</t>
</t>
</t>
@@ -344,15 +342,15 @@
<div class="btn-group o_dropdown">
<button t-if="section.name != 'buttons'" class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/>
- <t t-esc="section.label"/> <span class="caret"/>
+ <t t-esc="section.label"/>
</button>
<t t-if="section.name == 'buttons'" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
<a t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'" target="_blank">
<t t-raw="item.label"/>
</a>
</t>
- <ul class="dropdown-menu" role="menu">
- <li role="menuitem" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach="widget.items[section.name]" t-as="item">
<t t-if="section.name == 'files'">
<t t-set="item.title">
<b>Attachment : </b><br/>
@@ -369,12 +367,12 @@
<t t-raw="item.write_uid[1]"/> <t t-esc="item.write_date_string"/>
</t>
</t>
- <a t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'">
+ <a t-attf-class="dropdown-item #{item.classname}" role="menuitem" t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'">
<t t-raw="item.label"/>
<span t-if="section.name == 'files' and widget.options.editable and !item.callback" class="fa fa-trash-o o_sidebar_delete_attachment" t-att-data-id="item.id" title="Delete this attachment" role="img" aria-label="Delete this attachment"/>
</a>
- </li>
- <li role="menuitem" t-if="section.name == 'files' and widget.options.editable" class="o_sidebar_add_attachment">
+ </t>
+ <div role="menuitem" t-if="section.name == 'files' and widget.options.editable" class="dropdown-item o_sidebar_add_attachment">
<t t-call="HiddenInputFile">
<t t-set="fileupload_id" t-value="widget.fileuploadId"/>
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
@@ -384,8 +382,8 @@
<input type="hidden" name="session_id" t-att-value="widget.getSession().session_id" t-if="widget.getSession().override_session"/>
<span>Add...</span>
</t>
- </li>
- </ul>
+ </div>
+ </div>
</div>
</t>
</t>
@@ -511,15 +509,15 @@
<t t-name="GraphView.buttons">
<div class="btn-group" role="toolbar" aria-label="Main actions">
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
- Measures <span class="caret"/>
+ Measures
</button>
- <ul class="dropdown-menu o_graph_measures_list" role="menu">
- <li t-foreach="measures" t-as="measure" t-att-data-field="measure[0]">
- <a role="menuitem" href="#"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a>
- </li>
- <li role="separator" class="divider"></li>
- <li data-field="__count__"><a role="menuitem" href="#">Count</a></li>
- </ul>
+ <div class="dropdown-menu o_graph_measures_list" role="menu">
+ <t t-foreach="measures" t-as="measure">
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-field="measure[0]"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a>
+ </t>
+ <div role="separator" class="dropdown-divider"/>
+ <a role="menuitem" href="#" class="dropdown-item" data-field="__count__">Count</a>
+ </div>
</div>
<div class="btn-group" role="toolbar" aria-label="Change graph">
<button class="btn btn-secondary fa fa-bar-chart-o o_graph_button" title="Bar Chart" aria-label="Bar Chart" data-mode="bar"/>
@@ -540,15 +538,15 @@
<t t-name="PivotView.buttons">
<div class="btn-group" role="toolbar" aria-label="Main actions">
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
- Measures <span class="caret"/>
+ Measures
</button>
- <ul class="dropdown-menu o_pivot_measures_list" role="menu">
- <li t-foreach="measures" t-as="measure" t-att-data-field="measure[0]">
- <a role="menuitem" href="#"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a>
- </li>
- <li role="separator" class="divider"></li>
- <li data-field="__count"><a role="menuitem" href="#">Count</a></li>
- </ul>
+ <div class="dropdown-menu o_pivot_measures_list" role="menu">
+ <t t-foreach="measures" t-as="measure">
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-field="measure[0]"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a>
+ </t>
+ <div role="separator" class="dropdown-divider"/>
+ <a role="menuitem" href="#" class="dropdown-item" data-field="__count">Count</a>
+ </div>
</div>
<div class="btn-group" role="toolbar" aria-label="Pivot settings">
<button class="btn btn-secondary fa fa-expand o_pivot_flip_button" title="Flip axis" aria-label="Flip axis"/>
@@ -557,29 +555,27 @@
</div>
</t>
<t t-name="PivotView.FieldSelection">
- <ul class="dropdown-menu o_pivot_field_menu" role="menu">
+ <div class="dropdown-menu o_pivot_field_menu" role="menu">
<t t-foreach="fields" t-as="field">
<t t-if="(field[1].type === 'date') || (field[1].type === 'datetime')">
- <li role="menuitem" aria-haspopup="true" t-att-data-field="field[0]" t-attf-class="o_inline_dropdown#{field[2] ? ' disabled' : ''}">
- <a href="#" class="o_pivot_field_selection">
+ <div role="menuitem" aria-haspopup="true" class="o_inline_dropdown">
+ <a href="#" t-att-data-field="field[0]" t-attf-class="dropdown-item o_pivot_field_selection#{field[2] ? ' disabled' : ''}">
<t t-esc="field[1].string"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'day'">Day</a></li>
- <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'week'">Week</a></li>
- <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'month'">Month</a></li>
- <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'quarter'">Quarter</a></li>
- <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'year'">Year</a></li>
- </ul>
- </li>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'day'" t-att-data-field="field[0]">Day</a>
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'week'" t-att-data-field="field[0]">Week</a>
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'month'" t-att-data-field="field[0]">Month</a>
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'quarter'" t-att-data-field="field[0]">Quarter</a>
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'year'" t-att-data-field="field[0]">Year</a>
+ </div>
+ </div>
</t>
<t t-else="">
- <li t-att-data-field="field[0]" t-att-class="(field[2] ? 'disabled' : '')">
- <a role="menuitem" href="#"><t t-esc="field[1].string"/></a>
- </li>
+ <a href="#" role="menuitem" t-att-data-field="field[0]" t-attf-class="dropdown-item#{field[2] ? ' disabled' : ''}"><t t-esc="field[1].string"/></a>
</t>
</t>
- </ul>
+ </div>
</t>
<div t-name="PivotView.nodata">
<div class="o_view_nocontent" role="alert">
@@ -597,17 +593,16 @@
<t t-name="FormSelection">
<div class="btn-group o_selection" aria-atomic="true">
<a href="#" data-toggle="dropdown" aria-label="Dropdown menu" title="Dropdown menu"><span class="o_status"/></a>
- <ul class="dropdown-menu state" role="menu">
- </ul>
+ <div class="dropdown-menu state" role="menu"/>
</div>
</t>
<t t-name="FormSelection.items">
- <li t-foreach="states" t-as="rec" t-att-data-value="rec.name">
- <a role="menuitem" href="#">
+ <t t-foreach="states" t-as="rec">
+ <a role="menuitem" href="#" class="dropdown-item" t-att-data-value="rec.name">
<span t-att-class="'o_status ' + (rec.state_class &amp;&amp; rec.state_class || '')"/>
<t t-raw="rec.state_name"/>
</a>
- </li>
+ </t>
</t>
<t t-name="FieldDomain.content">
<div t-if="hasModel" class="o_field_domain_panel">
@@ -636,10 +631,10 @@
<t t-if="widget.operator === '|'">Any</t>
<t t-if="widget.operator === '!'">None</t>
</button>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" href="#" data-operator="&amp;">All</a></li>
- <li><a role="menuitem" href="#" data-operator="|">Any</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item" data-operator="&amp;">All</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-operator="|">Any</a>
+ </div>
</div>
<strong t-else="">
<t t-if="widget.operator === '&amp;'">ALL</t>
@@ -901,12 +896,12 @@
</t>
<t t-name="FieldStatus.content">
<t t-if="selection_folded.length">
- <button type="button" class="btn o_arrow_button btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">More <span class="caret"/></button>
- <ul class="dropdown-menu o-status-more" role="menu">
- <li t-foreach="selection_folded" t-as="i">
+ <button type="button" class="btn o_arrow_button btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">More</button>
+ <div class="dropdown-menu o-status-more" role="menu">
+ <t t-foreach="selection_folded" t-as="i">
<t t-call="FieldStatus.content.button"/>
- </li>
- </ul>
+ </t>
+ </div>
</t>
<t t-foreach="selection_unfolded.reverse()" t-as="i">
<t t-call="FieldStatus.content.button"/>
@@ -1069,71 +1064,67 @@
<t t-if="widget.items.length !== 0">
<t t-set="group" t-value="0"/>
<t t-foreach="widget.items" t-as="item">
- <li t-if="group !== item.groupId" class="divider" data-removable="1"/>
- <li t-att-class="'o_menu_item ' + (item.isActive ? 'selected ' : '')"
+ <div t-if="group !== item.groupId" class="dropdown-divider" data-removable="1"/>
+ <div t-attf-class="o_menu_item#{item.isActive ? ' selected ' : ''}"
t-att-data-id="item.itemId">
- <a href="#">
+ <a href="#" class="dropdown-item">
<t t-esc="item.description"/>
<span t-if="item.isRemovable" t-att-data-id="item.itemId" class="o_trash_button" > <span class="fa fa-trash-o"></span> </span>
<span t-if="item.hasOptions" t-att-data-id="item.itemId" class="o_submenu_switcher">
<span t-att-class="item.isOpen ? 'fa fa-caret-down' : 'fa fa-caret-right'"></span>
</span>
</a>
- <ul t-if="item.hasOptions &amp;&amp; item.isOpen">
+ <ul t-if="item.hasOptions &amp;&amp; item.isOpen" class="list-unstyled">
<t t-set="subgroup" t-value="0"/>
<t t-foreach="_.values(item.options)" t-as="option">
- <li t-if="subgroup !== option.groupId" class="divider" data-removable="1"/>
- <li t-att-class="'o_item_option ' + (item.currentOptionId === option.optionId ? 'selected': '')"
+ <li t-if="subgroup !== option.groupId" class="dropdown-divider" data-removable="1"/>
+ <li t-attf-class="o_item_option#{item.currentOptionId === option.optionId ? ' selected': ''}"
t-att-data-item_id="item.itemId" t-att-data-option_id="option.optionId">
- <a href="#"><t t-esc="option.description"/></a>
+ <a href="#" class="dropdown-item pl-5"><t t-esc="option.description"/></a>
</li>
<t t-set="subgroup" t-value="option.groupId"/>
</t>
</ul>
- </li>
+ </div>
<t t-set="group" t-value="item.groupId"/>
</t>
</t>
</t>
-<div t-name="web.DropdownMenu" t-att-class="widget.dropdownStyle.el.class" t-att="widget.dropdownStyle.el.attrs" >
+<div t-name="web.DropdownMenu" t-att-class="widget.dropdownStyle.el.class" t-att="widget.dropdownStyle.el.attrs">
<button t-att-class="widget.dropdownStyle.mainButton.class" data-toggle="dropdown" aria-expanded="false" tabindex="-1">
- <span t-att-class="widget.dropdownIcon"/> <t t-esc="widget.dropdownTitle"/> <span t-att-class="widget.dropdownSymbol"/>
+ <span t-att-class="widget.dropdownIcon"/> <t t-esc="widget.dropdownTitle"/> <span t-if="widget.dropdownSymbol" t-att-class="widget.dropdownSymbol"/>
</button>
- <ul class="dropdown-menu o_dropdown_menu" role="menu">
+ <div class="dropdown-menu o_dropdown_menu" role="menu">
<t t-call="DropdownMenu.MenuItems"/>
- </ul>
+ </div>
</div>
<t t-name="GroupbyMenuGenerator">
- <li t-if="Object.keys(widget.presentedFields).length !== 0 &amp;&amp; widget.items.length !== 0" class="o_generator_menu divider"/>
- <li t-if="Object.keys(widget.presentedFields).length !== 0" class="o_generator_menu o_add_custom_group ">
- <a href="#">Add Custom Group</a>
- </li>
- <li t-if="widget.generatorMenuIsOpen" class="o_generator_menu">
- <select class="o_input o_group_selector o_add_group">
+ <div t-if="Object.keys(widget.presentedFields).length !== 0 &amp;&amp; widget.items.length !== 0" class="dropdown-divider o_generator_menu"/>
+ <button t-if="Object.keys(widget.presentedFields).length !== 0" type="button" class="dropdown-item o_generator_menu o_add_custom_group">Add Custom Group</button>
+ <div t-if="widget.generatorMenuIsOpen" class="dropdown-item-text o_generator_menu">
+ <select class="w-auto o_input o_group_selector o_add_group">
<t t-foreach="widget.presentedFields" t-as="field">
<option t-att-value="field.name"><t t-esc="field.string"/></option>
</t>
</select>
- </li>
- <li t-if="widget.generatorMenuIsOpen" class="o_generator_menu">
+ </div>
+ <div t-if="widget.generatorMenuIsOpen" class="dropdown-item-text o_generator_menu">
<button type="button" class="btn btn-primary o_apply_group o_add_group" tabindex="-1">Apply</button>
- </li>
+ </div>
</t>
<t t-name="FiltersMenuGenerator">
- <li class="divider"/>
- <li t-if="Object.keys(widget.fields).length !== 0" class="o_add_custom_filter o_closed_menu">
- <a href="#">Add Custom Filter</a>
- </li>
- <li class="o_add_filter_menu">
+ <div class="dropdown-divider"/>
+ <button t-if="Object.keys(widget.fields).length !== 0" type="button" class="dropdown-item o_add_custom_filter o_closed_menu">Add Custom Filter</button>
+ <div class="dropdown-item-text o_add_filter_menu">
<button class="btn btn-primary o_apply_filter" type="button">Apply</button>
<button class="btn btn-secondary o_add_condition" type="button">
<span class="fa fa-plus-circle"/>
Add a condition
</button>
- </li>
+ </div>
</t>
@@ -1173,15 +1164,20 @@
<t t-esc="widget.model.get('label') + (widget.optionLabel ? (': ' + widget.optionLabel) : '')"/>
</span>
<t t-name="SearchView.autocomplete">
- <ul class="dropdown-menu o_searchview_autocomplete" role="menu"></ul>
+ <div class="dropdown-menu o_searchview_autocomplete" role="menu"/>
</t>
<t t-name="SearchView.filters">
- <li t-foreach="widget.filters" t-as="filter" t-if="!filter.visible || filter.visible()"
- t-att-title="filter.attrs.string ? filter.attrs.help : undefined"
- t-att-data-index="filter_index">
- <a role="menuitem" href="#"><t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/></a>
- </li>
+ <t t-foreach="widget.filters" t-as="filter">
+ <a t-if="!filter.visible || filter.visible()"
+ href="#"
+ class="dropdown-item"
+ t-att-title="filter.attrs.string ? filter.attrs.help : undefined"
+ t-att-data-index="filter_index"
+ role="menuitem">
+ <t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/>
+ </a>
+ </t>
</t>
<t t-name="SearchView.field">
<label t-att-class="'oe_label' + (attrs.help ? '_help' : '')"
@@ -1243,7 +1239,7 @@
</div>
</t>
<t t-name="SearchView.extended_search.proposition">
- <li role="menuitem" class="o_filter_condition">
+ <div role="menuitem" class="dropdown-item-text o_filter_condition">
<span class="o_or_filter">or</span>
<span>
<select class="o_input o_searchview_extended_prop_field">
@@ -1258,7 +1254,7 @@
</span>
<select class="o_input o_searchview_extended_prop_op"/>
<span class="o_searchview_extended_prop_value"/>
- </li>
+ </div>
</t>
<t t-name="SearchView.extended_search.proposition.float">
<input class="o_input"
@@ -1276,28 +1272,26 @@
</t>
<div t-name="SearchView.FavoriteMenu" class="btn-group o_dropdown">
- <button class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1" aria-label="Favorites" title="Favorites">
- <span class="fa fa-star"/> Favorites <span t-attf-class="#{widget.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'}"/>
+ <button t-attf-class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle#{widget.isMobile ? ' o-no-caret' : ''}" data-toggle="dropdown" aria-expanded="false" tabindex="-1" aria-label="Favorites" title="Favorites">
+ <span class="fa fa-star"/> Favorites <span t-if="widget.isMobile" class="fa fa-chevron-right pull-right mt4"/>
</button>
- <ul class="dropdown-menu o_favorites_menu" role="menu">
- <li class="divider user_filter"/>
- <li class="divider shared_filter"/>
- <li class="o_save_search o_closed_menu">
- <a role="menuitem" href="#">Save current search</a>
- </li>
- <li role="menuitem" class="o_save_name">
- <input type="text"></input>
- </li>
- <li role="menuitem" class="o_save_name">
+ <div class="dropdown-menu o_favorites_menu" role="menu">
+ <div class="dropdown-divider user_filter"/>
+ <div class="dropdown-divider shared_filter"/>
+ <a role="menuitem" href="#" class="dropdown-item o_save_search o_closed_menu">Save current search</a>
+ <div role="menuitem" class="dropdown-item-text o_save_name">
+ <input type="text" class="o_input"></input>
+ </div>
+ <div role="menuitem" class="dropdown-item-text o_save_name">
<span><div class="o_checkbox"><input type="checkbox"/><span/></div> Use by default</span>
- </li>
- <li role="menuitem" class="o_save_name">
+ </div>
+ <div role="menuitem" class="dropdown-item-text o_save_name">
<span><div class="o_checkbox"><input type="checkbox"/><span/></div> Share with all users </span><span class="fa fa-users" role="img" aria-label="Users" title="Users"/>
- </li>
- <li class="o_save_name">
+ </div>
+ <div class="dropdown-item-text o_save_name">
<button role="menuitem" type="button" class="btn btn-primary">Save</button>
- </li>
- </ul>
+ </div>
+ </div>
</div>
<div t-name="ExportDialog" class="o_export">
@@ -1460,27 +1454,27 @@
<img class="img-circle oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/user_menu_avatar.png'" alt="Avatar"/>
<span class="oe_topbar_name"/>
</a>
- <ul class="dropdown-menu" role="menu">
+ <div class="dropdown-menu dropdown-menu-right" role="menu">
<t t-call="UserMenu.Actions"/>
- </ul>
+ </div>
</li>
</t>
<t t-name="UserMenu.Actions">
- <li><a role="menuitem" href="#" data-menu="documentation">Documentation</a></li>
- <li><a role="menuitem" href="#" data-menu="support">Support</a></li>
- <li role="separator" class="divider"/>
- <li><a role="menuitem" href="#" data-menu="settings">Preferences</a></li>
- <li><a role="menuitem" href="#" data-menu="account">My Odoo.com account</a></li>
- <li><a role="menuitem" href="#" data-menu="logout">Log out</a></li>
+ <a role="menuitem" href="#" data-menu="documentation" class="dropdown-item">Documentation</a>
+ <a role="menuitem" href="#" data-menu="support" class="dropdown-item">Support</a>
+ <div role="separator" class="dropdown-divider"/>
+ <a role="menuitem" href="#" data-menu="settings" class="dropdown-item">Preferences</a>
+ <a role="menuitem" href="#" data-menu="account" class="dropdown-item">My Odoo.com account</a>
+ <a role="menuitem" href="#" data-menu="logout" class="dropdown-item">Log out</a>
</t>
<t t-name="SwitchCompanyMenu">
<li class="o_switch_company_menu">
<a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#" aria-label="Dropdown menu" title="Dropdown menu">
- <span t-attf-class="#{widget.isMobile ? 'fa fa-building-o' : 'oe_topbar_name'}"/> <span class="caret"/>
+ <span t-attf-class="#{widget.isMobile ? 'fa fa-building-o' : 'oe_topbar_name'}"/>
</a>
- <ul class="dropdown-menu" role="menu"/>
+ <div class="dropdown-menu dropdown-menu-right" role="menu"/>
</li>
</t>
diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml
index a6d5ecc4ff4..4fc71cd6074 100644
--- a/addons/web/static/src/xml/kanban.xml
+++ b/addons/web/static/src/xml/kanban.xml
@@ -16,18 +16,18 @@
<span t-attf-id="#kanban_header_#{widget.id or widget.db_id}" class="o_column_title"><t t-esc="widget.title"/></span>
<span class="o_column_unfold"><i class="fa fa-arrows-h" role="img" aria-label="Unfold" title="Unfold"/></span>
<span class="o_kanban_config dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" class="o_kanban_toggle_fold" href="#">Fold</a></li>
+ <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" class="dropdown-item o_kanban_toggle_fold" href="#">Fold</a>
<t t-if="widget.grouped_by_m2o">
- <li t-if="widget.editable and widget.id"><a role="menuitem" class="o_column_edit" href="#">Edit Stage</a></li>
- <li t-if="widget.deletable and widget.id"><a role="menuitem" class="o_column_delete" href="#">Delete</a></li>
+ <a t-if="widget.editable and widget.id" role="menuitem" class="dropdown-item o_column_edit" href="#">Edit Stage</a>
+ <a t-if="widget.deletable and widget.id" role="menuitem" class="dropdown-item o_column_delete" href="#">Delete</a>
</t>
<t t-if="widget.has_active_field">
- <li><a class="o_column_archive_records" href="#">Archive All</a></li>
- <li><a class="o_column_unarchive_records" href="#">Unarchive All</a></li>
+ <a href="#" class="dropdown-item o_column_archive_records">Archive All</a>
+ <a href="#" class="dropdown-item o_column_unarchive_records">Unarchive All</a>
</t>
- </ul>
+ </div>
</span>
<span t-if="widget.quick_create" class="o_kanban_quick_add"><i class="fa fa-plus" role="img" aria-label="Quick add" title="Quick add"/></span>
</div>
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js
index ffb0f6198d5..a2224193bab 100644
--- a/addons/web/static/tests/fields/basic_fields_tests.js
+++ b/addons/web/static/tests/fields/basic_fields_tests.js
@@ -3698,19 +3698,19 @@ QUnit.module('basic_fields', {
"should have one red status since selection is the second, blocked state");
assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_green').length, 0,
"should not have one green status since selection is the second, blocked state");
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
// Click on the status button to make the dropdown appear
form.$('.o_field_widget.o_selection .o_status').first().click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 1,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 1,
"there should be a dropdown");
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible li').length, 2,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible .dropdown-item').length, 2,
"there should be two options in the dropdown");
// Click on the first option, "Normal"
- form.$('ul.dropdown-menu.state:visible li').first().click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0,
+ form.$('.dropdown-menu.state:visible .dropdown-item').first().click();
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown anymore");
assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0,
"should not have one red status since selection is the first, normal state");
@@ -3721,7 +3721,7 @@ QUnit.module('basic_fields', {
// switch to edit mode and check the result
form.$buttons.find('.o_form_button_edit').click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0,
"there should still not be a dropdown");
assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0,
"should still not have one red status since selection is the first, normal state");
@@ -3732,14 +3732,14 @@ QUnit.module('basic_fields', {
// Click on the status button to make the dropdown appear
form.$('.o_field_widget.o_selection .o_status').first().click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 1,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 1,
"there should be a dropdown");
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible li').length, 2,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible .dropdown-item').length, 2,
"there should be two options in the dropdown");
// Click on the last option, "Done"
- form.$('ul.dropdown-menu.state:visible li').last().click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0,
+ form.$('.dropdown-menu.state:visible .dropdown-item').last().click();
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown anymore");
assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0,
"should not have one red status since selection is the third, done state");
@@ -3748,7 +3748,7 @@ QUnit.module('basic_fields', {
// save
form.$buttons.find('.o_form_button_save').click();
- assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0,
"there should still not be a dropdown anymore");
assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0,
"should still not have one red status since selection is the third, done state");
@@ -3777,7 +3777,7 @@ QUnit.module('basic_fields', {
"should have one red status");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1,
"should have one green status");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
// Click on the status button to make the dropdown appear
@@ -3785,20 +3785,20 @@ QUnit.module('basic_fields', {
list.$('.o_state_selection_cell .o_selection > a span.o_status').first().click();
assert.ok(!$cell.parent().hasClass('o_selected_row'),
'should not be in edit mode since we clicked on the state selection widget');
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1,
"there should be a dropdown");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2,
"there should be two options in the dropdown");
// Click on the first option, "Normal"
- list.$('ul.dropdown-menu.state:visible li').first().click();
+ list.$('.dropdown-menu.state:visible .dropdown-item').first().click();
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status').length, 5,
"should still have five status selection widgets");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_red').length, 0,
"should now have no red status");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1,
"should still have one green status");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
// switch to edit mode and check the result
@@ -3812,21 +3812,21 @@ QUnit.module('basic_fields', {
"should now have no red status");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1,
"should still have one green status");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
// Click on the status button to make the dropdown appear
list.$('.o_state_selection_cell .o_selection > a span.o_status').first().click();
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1,
"there should be a dropdown");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2,
"there should be two options in the dropdown");
// Click on another row
var $firstCell = list.$('tbody td.o_state_selection_cell').first();
var $lastCell = list.$('tbody td.o_state_selection_cell').last();
$lastCell.click();
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown anymore");
assert.ok(!$firstCell.parent().hasClass('o_selected_row'),
'first row should not be in edit mode anymore');
@@ -3835,14 +3835,14 @@ QUnit.module('basic_fields', {
// Click on the last status button to make the dropdown appear
list.$('.o_state_selection_cell .o_selection > a span.o_status').last().click();
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1,
"there should be a dropdown");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2,
"there should be two options in the dropdown");
// Click on the last option, "Done"
- list.$('ul.dropdown-menu.state:visible li').last().click();
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ list.$('.dropdown-menu.state:visible .dropdown-item').last().click();
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown anymore");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status').length, 5,
"should still have five status selection widgets");
@@ -3850,7 +3850,7 @@ QUnit.module('basic_fields', {
"should still have no red status");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 2,
"should now have two green status");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
// save
@@ -3861,7 +3861,7 @@ QUnit.module('basic_fields', {
"should have no red status");
assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 2,
"should have two green status");
- assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0,
+ assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0,
"there should not be a dropdown");
list.destroy();
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index 8c91b0f4d54..17c22617744 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -429,7 +429,7 @@ QUnit.module('relational_fields', {
$('button:contains(Filters)').click();
$('.o_add_custom_filter:visible').click(); // Add a custom filter, datetime field is selected
- assert.strictEqual($('li.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime',
+ assert.strictEqual($('.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime',
"datetime field should be selected");
$('.o_apply_filter').click();
diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js
index 232a6d59f30..dc80d6440b3 100644
--- a/addons/web/static/tests/views/form_tests.js
+++ b/addons/web/static/tests/views/form_tests.js
@@ -5003,8 +5003,8 @@ QUnit.module('Views', {
}
assert.strictEqual($actions.length, 3,
"there should be 3 actions");
- var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu li a')[2];
- assert.strictEqual($customAction.text.trim(), 'Action partner',
+ var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu:last .dropdown-item:nth(2)');
+ assert.strictEqual($customAction.text().trim(), 'Action partner',
"the custom action should have 'Action partner' as name");
testUtils.intercept(form, 'do_action', function (event) {
var context = event.data.action.context.__contexts[1];
diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js
index 60e6680993c..1ed9e799a4a 100644
--- a/addons/web/static/tests/views/graph_tests.js
+++ b/addons/web/static/tests/views/graph_tests.js
@@ -175,9 +175,9 @@ QUnit.module('Views', {
return concurrency.delay(0).then(function () {
assert.ok(graph.$('text.nv-legend-text:contains(Count)').length,
"should have used the correct measure");
- assert.ok(graph.$buttons.find('li[data-field="foo"]').length,
+ assert.ok(graph.$buttons.find('.dropdown-item[data-field="foo"]').length,
"should have foo in the list of measures");
- graph.$buttons.find('li[data-field="foo"] a').click();
+ graph.$buttons.find('.dropdown-item[data-field="foo"]').click();
return concurrency.delay(0);
}).then(function () {
@@ -268,7 +268,7 @@ QUnit.module('Views', {
graph_intervalMapping: {},
}, "context should be correct");
- graph.$buttons.find('li[data-field="foo"] a').click(); // change measure
+ graph.$buttons.find('.dropdown-item[data-field="foo"]').click(); // change measure
return concurrency.delay(0);
}).then(function () {
@@ -552,7 +552,7 @@ QUnit.module('Views', {
return concurrency.delay(0).then(function () {
// need to set the measure this way because it cannot be set in the
// arch.
- graph.$buttons.find('li[data-field="product_id"] a').click();
+ graph.$buttons.find('.dropdown-item[data-field="product_id"]').click();
assert.strictEqual(graph.model.chart.data[0].value, 1,
"should have first datapoint with value 1");
@@ -639,9 +639,9 @@ QUnit.module('Views', {
'</graph>',
})
- assert.strictEqual(graph.$buttons.find('.o_graph_measures_list li:first').data('field'), 'bouh',
+ assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').data('field'), 'bouh',
"Bouh should be the first measure");
- assert.strictEqual(graph.$buttons.find('.o_graph_measures_list li:last').data('field'), '__count__',
+ assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').data('field'), '__count__',
"Count should be the last measure");
graph.destroy();
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index 5d18d03c553..c80e0916d21 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -738,7 +738,7 @@ QUnit.module('Views', {
// Select state in kanban
kanban.$('.o_status').first().click();
- kanban.$('.o_selection ul:first li:first').click();
+ kanban.$('.o_selection .dropdown-item:first').click();
assert.ok(kanban.$('.o_status').first().hasClass('o_status_green'),
"Kanban state should be done (Green)");
kanban.destroy();
@@ -2789,10 +2789,10 @@ QUnit.module('Views', {
'<t t-name="kanban-box">' +
'<div color="color">' +
'<div class="o_dropdown_kanban dropdown">' +
- '<a class="dropdown-toggle btn" data-toggle="dropdown" href="#">' +
+ '<a class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#">' +
'<span class="fa fa-bars fa-lg"/>' +
'</a>' +
- '<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">' +
+ '<ul class="dropdown-menu" role="menu">' +
'<li>' +
'<ul class="oe_kanban_colorpicker"/>' +
'</li>' +
diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js
index 1ea69e9320b..b9732164332 100644
--- a/addons/web/static/tests/views/list_tests.js
+++ b/addons/web/static/tests/views/list_tests.js
@@ -2347,8 +2347,8 @@ QUnit.module('Views', {
var $actions = $('.o_web_client .o_control_panel .btn-group .dropdown-menu')[1].children;
assert.strictEqual($actions.length, 3,
"there should be 3 actions");
- var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu li a')[2];
- assert.strictEqual($customAction.text.trim(), 'Action event',
+ var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-item:nth(2)');
+ assert.strictEqual($customAction.text().trim(), 'Action event',
"the custom action should have 'Action event' as name");
list.destroy();
diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js
index 138b620c4e0..6e034a19a79 100644
--- a/addons/web/static/tests/views/pivot_tests.js
+++ b/addons/web/static/tests/views/pivot_tests.js
@@ -259,7 +259,7 @@ QUnit.module('Views', {
}
});
- var $countMeasure = pivot.$buttons.find('li[data-field=__count]');
+ var $countMeasure = pivot.$buttons.find('.dropdown-item[data-field=__count]:first');
assert.ok($countMeasure.hasClass('selected'), "The count measure should be activated");
pivot.destroy();
});
@@ -344,14 +344,15 @@ QUnit.module('Views', {
// click on closed header to open dropdown
pivot.$('tbody .o_pivot_header_cell_closed').click();
- assert.strictEqual(pivot.$('ul.o_pivot_field_menu > li[data-field="date"]').length, 1,
+ assert.strictEqual(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:first').length, 1,
"should have the date field as proposition");
- assert.strictEqual(pivot.$('.o_field_selection li[data-field="product_id"]').length, 1,
+ assert.strictEqual(pivot.$('.o_field_selection .dropdown-item[data-field="product_id"]:first').length, 1,
"should have the product_id field as proposition");
- assert.strictEqual(pivot.$('.o_field_selection li[data-field="non_stored_m2o"]').length, 0,
+ assert.strictEqual(pivot.$('.o_field_selection .dropdown-item[data-field="non_stored_m2o"]:first').length, 0,
"should not have the non_stored_m2o field as proposition");
- pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a').click();
+
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:first').click();
assert.strictEqual(pivot.$('tbody tr').length, 4,
"should have 4 rows: one for header, 3 for data");
@@ -376,7 +377,7 @@ QUnit.module('Views', {
// open dropdown to zoom into first row
pivot.$('tbody .o_pivot_header_cell_closed').first().click();
// click on date by day
- pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a[data-interval="day"]').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"][data-interval="day"]').click();
// open dropdown to zoom into second row
pivot.$('tbody td.o_pivot_header_cell_closed:eq(1)').first().click();
@@ -437,22 +438,22 @@ QUnit.module('Views', {
assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 3,
"should have 3 cells: 1 for the open header, and 2 for data");
- assert.ok(!pivot.$buttons.find('li[data-field=__count]').hasClass('selected'),
+ assert.ok(!pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'),
"the __count measure should not be selected");
rpcCount = 0;
- pivot.$buttons.find('li[data-field=__count] a').click();
+ pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click();
- assert.ok(pivot.$buttons.find('li[data-field=__count]').hasClass('selected'),
+ assert.ok(pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'),
"the __count measure should be selected");
assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 6,
"should have 6 cells: 2 for the open header, and 4 for data");
assert.strictEqual(rpcCount, 2,
"should have done 2 rpcs to reload data");
- pivot.$buttons.find('li[data-field=__count] a').click();
+ pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click();
- assert.ok(!pivot.$buttons.find('li[data-field=__count]').hasClass('selected'),
+ assert.ok(!pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'),
"the __count measure should not be selected");
assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 3,
"should have 3 cells: 1 for the open header, and 2 for data");
@@ -477,7 +478,7 @@ QUnit.module('Views', {
assert.strictEqual(pivot.$('table').length, 1,
"should have a table in DOM");
- pivot.$buttons.find('li[data-field=__count] a').click();
+ pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click();
assert.strictEqual(pivot.$('.o_view_nocontent').length, 1,
"should have a no_content_helper");
@@ -553,7 +554,7 @@ QUnit.module('Views', {
// tries to open a field selection menu, to make sure it was not
// removed from the dom.
pivot.$('.o_pivot_header_cell_closed').first().click();
- assert.strictEqual(pivot.$('ul.o_pivot_field_menu').length, 1,
+ assert.strictEqual(pivot.$('.o_pivot_field_menu').length, 1,
"the field selector menu exists");
pivot.destroy();
});
@@ -816,7 +817,7 @@ QUnit.module('Views', {
// expand header on field customer
pivot.$('thead .o_pivot_header_cell_closed:nth(1)').click();
- pivot.$('ul.o_pivot_field_menu > li[data-field="customer"] a').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="customer"]:first').click();
assert.deepEqual(pivot.getContext(), {
pivot_column_groupby: ['date:day', 'customer'],
pivot_measures: ['foo'],
@@ -825,7 +826,7 @@ QUnit.module('Views', {
// expand row on field product_id
pivot.$('tbody .o_pivot_header_cell_closed').first().click();
- pivot.$('ul.o_pivot_field_menu > li[data-field="product_id"] a').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first').click();
assert.deepEqual(pivot.getContext(), {
pivot_column_groupby: ['date:day', 'customer'],
pivot_measures: ['foo'],
@@ -982,7 +983,7 @@ QUnit.module('Views', {
},
});
- var $countMeasure = pivot.$buttons.find('li[data-field=__count]');
+ var $countMeasure = pivot.$buttons.find('.dropdown-item[data-field=__count]:first');
assert.ok($countMeasure.hasClass('selected'), "The count measure should be activated");
pivot.destroy();
@@ -1056,7 +1057,7 @@ QUnit.module('Views', {
});
pivot.$('tbody .o_pivot_header_cell_closed').first().click();
// click on date by month
- pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a[data-interval="month"]').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"][data-interval="month"]').click();
assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '2211',
'should have loaded the proper data');
@@ -1078,7 +1079,7 @@ QUnit.module('Views', {
},
});
- pivot.$buttons.find('li[data-field=product_id] a').click();
+ pivot.$buttons.find('.dropdown-item[data-field=product_id]:first').click();
assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '421131',
'should have loaded the proper data');
pivot.destroy();
@@ -1098,7 +1099,7 @@ QUnit.module('Views', {
pivot.$('tbody .o_pivot_header_cell_closed').first().click();
- pivot.$('ul.o_pivot_field_menu > li[data-field="product_id"] a').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first').click();
assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '211',
'should have loaded the proper data');
@@ -1119,11 +1120,11 @@ QUnit.module('Views', {
// Set a column groupby
pivot.$('thead .o_pivot_header_cell_closed').click();
- pivot.$('.o_field_selection li[data-field=customer] a').click();
+ pivot.$('.o_field_selection .dropdown-item[data-field=customer]:first').click();
// Set a Row groupby
pivot.$('tbody .o_pivot_header_cell_closed').click();
- pivot.$('.o_pivot_field_menu li[data-field=product_id] a').click();
+ pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]:first').click();
// Set a domain
pivot.update({domain: [['product_id', '=', 41]]});
@@ -1195,9 +1196,9 @@ QUnit.module('Views', {
'</pivot>',
})
- assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list li:first').data('field'), 'bouh',
+ assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list .dropdown-item:first').data('field'), 'bouh',
"Bouh should be the first measure");
- assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list li:last').data('field'), '__count',
+ assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list .dropdown-item:last').data('field'), '__count',
"Count should be the last measure");
pivot.destroy();
diff --git a/addons/web/static/tests/views/search_filters_menu_tests.js b/addons/web/static/tests/views/search_filters_menu_tests.js
index e6430527de7..70d57c1fd32 100644
--- a/addons/web/static/tests/views/search_filters_menu_tests.js
+++ b/addons/web/static/tests/views/search_filters_menu_tests.js
@@ -37,11 +37,11 @@ QUnit.module('FiltersMenu', {
var filterMenu = createFiltersMenu([], this.fields);
filterMenu.$('span.fa-filter').click();
- assert.strictEqual(filterMenu.$('.divider').length, 1);
- assert.ok(!filterMenu.$('.divider').is(':visible'));
- assert.strictEqual(filterMenu.$('li').length, 3,
- 'should have 3 li: a hidden divider, a add custom filter item, a apply button + add condition button');
- assert.strictEqual(filterMenu.$('li.o_add_custom_filter.o_closed_menu').length, 1);
+ assert.strictEqual(filterMenu.$('.dropdown-divider').length, 1);
+ assert.ok(!filterMenu.$('.dropdown-divider').is(':visible'));
+ assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 3,
+ 'should have 3 elements: a hidden divider, a add custom filter item, a apply button + add condition button');
+ assert.strictEqual(filterMenu.$('.o_add_custom_filter.o_closed_menu').length, 1);
filterMenu.destroy();
});
@@ -49,9 +49,9 @@ QUnit.module('FiltersMenu', {
assert.expect(2);
var filterMenu = createFiltersMenu(this.filters, this.fields);
- assert.strictEqual(filterMenu.$('li').length, 5,
- 'should have 4 li: a hidden, separator, a filter, a separator, a add custom filter item, a apply button + add condition button');
- assert.strictEqual(filterMenu.$('li.o_add_custom_filter.o_closed_menu').length, 1);
+ assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 5,
+ 'should have 4 elements: a hidden, separator, a filter, a separator, a add custom filter item, a apply button + add condition button');
+ assert.strictEqual(filterMenu.$('.o_add_custom_filter.o_closed_menu').length, 1);
filterMenu.destroy();
});
@@ -62,11 +62,11 @@ QUnit.module('FiltersMenu', {
// open menu dropdown
filterMenu.$('span.fa-filter').click();
// open add custom filter submenu
- filterMenu.$('li.o_add_custom_filter').click();
- assert.ok(filterMenu.$('li.o_add_custom_filter').hasClass('o_open_menu'));
- assert.ok(filterMenu.$('li.o_add_filter_menu').is(':visible'));
- assert.strictEqual(filterMenu.$('li').length, 4,
- 'should have 3 li: a hidden divider, a add custom filter item, a proposition, a apply button + add condition button');
+ filterMenu.$('.o_add_custom_filter').click();
+ assert.ok(filterMenu.$('.o_add_custom_filter').hasClass('o_open_menu'));
+ assert.ok(filterMenu.$('.o_add_filter_menu').is(':visible'));
+ assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4,
+ 'should have 3 elements: a hidden divider, a add custom filter item, a proposition, a apply button + add condition button');
filterMenu.destroy();
});
@@ -77,15 +77,15 @@ QUnit.module('FiltersMenu', {
var filterMenu = createFiltersMenu([], this.fields);
// open menu dropdown and custom filter submenu
filterMenu.$('span.fa-filter').click();
- filterMenu.$('li.o_add_custom_filter').click();
+ filterMenu.$('.o_add_custom_filter').click();
// remove the current unique proposition
filterMenu.$('.o_searchview_extended_delete_prop').click();
assert.ok(filterMenu.$('.o_apply_filter').attr('disabled'));
- assert.strictEqual(filterMenu.$('li').length, 3,
- 'should have 3 li: a hidden separator, a add custom filter item, a apply button + add condition button');
+ assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 3,
+ 'should have 3 elements: a hidden separator, a add custom filter item, a apply button + add condition button');
filterMenu.destroy();
});
@@ -97,7 +97,7 @@ QUnit.module('FiltersMenu', {
// open menu dropdown and custom filter submenu, remove existing prop
filterMenu.$('span.fa-filter').click();
- filterMenu.$('li.o_add_custom_filter').click();
+ filterMenu.$('.o_add_custom_filter').click();
filterMenu.$('.o_searchview_extended_delete_prop').click();
// read a proposition
@@ -116,14 +116,14 @@ QUnit.module('FiltersMenu', {
// open menu dropdown and custom filter submenu, remove existing prop
filterMenu.$('span.fa-filter').click();
- filterMenu.$('li.o_add_custom_filter').click();
+ filterMenu.$('.o_add_custom_filter').click();
// click on apply to activate filter
filterMenu.$('.o_apply_filter').click();
assert.ok(filterMenu.$('.o_add_custom_filter').hasClass('o_closed_menu'));
assert.strictEqual(filterMenu.$('.o_filter_condition').length, 0);
- assert.strictEqual(filterMenu.$('.divider:visible').length, 1,
+ assert.strictEqual(filterMenu.$('.dropdown-divider:visible').length, 1,
'there should be a separator between filters and add custom filter menu');
filterMenu.destroy();
diff --git a/addons/web/static/tests/views/search_groupby_menu_tests.js b/addons/web/static/tests/views/search_groupby_menu_tests.js
index 8dff7a581fe..d11b8ed0dbe 100644
--- a/addons/web/static/tests/views/search_groupby_menu_tests.js
+++ b/addons/web/static/tests/views/search_groupby_menu_tests.js
@@ -35,8 +35,8 @@ QUnit.module('GroupByMenu', {
var groupByMenu = createGroupByMenu(this.groupbys, this.fields);
groupByMenu.$('button:first').click();
- assert.strictEqual(groupByMenu.$('li').length, 2, 'should have 2 li');
- assert.strictEqual(groupByMenu.$('li:nth-child(2)').text().trim(), 'some group by',
+ assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 2, 'should have 2 elements');
+ assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').eq(1).text().trim(), 'some group by',
'should have proper filter name');
groupByMenu.destroy();
});
@@ -46,7 +46,7 @@ QUnit.module('GroupByMenu', {
var groupByMenu = createGroupByMenu([], {});
groupByMenu.$('button:first').click();
- assert.strictEqual(groupByMenu.$('li').length, 0, 'should have 0 li');
+ assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 0, 'should have 0 element');
groupByMenu.destroy();
});
@@ -58,7 +58,7 @@ QUnit.module('GroupByMenu', {
{fieldname: {sortable: true, string: 'Super Date', type: 'date', isDate: true}}
);
groupByMenu.$('button:first').click();
- assert.strictEqual(groupByMenu.$('li').length, 1, 'should have 1 li');
+ assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 1, 'should have 1 element');
groupByMenu.destroy();
});
@@ -69,7 +69,7 @@ QUnit.module('GroupByMenu', {
groupByMenu.$('button:first').click();
var selector = groupByMenu.$('select.o_group_selector');
assert.ok(!selector.is(":visible"), 'should be invisible');
- groupByMenu.$('.o_add_custom_group a').click();
+ groupByMenu.$('.o_add_custom_group').click();
selector = groupByMenu.$('select.o_group_selector');
assert.ok(selector.is(":visible"), 'should be visible');
groupByMenu.destroy();
@@ -85,11 +85,11 @@ QUnit.module('GroupByMenu', {
}
);
groupByMenu.$('button:first').click();
- groupByMenu.$('li.o_add_custom_group a').click();
+ groupByMenu.$('.o_add_custom_group').click();
assert.strictEqual(groupByMenu.$('select').val(), 'fieldName',
'the select value should be "fieldName"');
groupByMenu.$('button.o_apply_group').click();
- assert.strictEqual(groupByMenu.$('li.o_menu_item.selected').length, 1, 'there should be a groupby selected');
+ assert.strictEqual(groupByMenu.$('.o_menu_item.selected').length, 1, 'there should be a groupby selected');
groupByMenu.destroy();
});
@@ -107,7 +107,7 @@ QUnit.module('GroupByMenu', {
var groupByMenu = createGroupByMenu(this.groupbys, this.fields, {
intercepts: {
- menu_item_toggled: function(ev) {
+ menu_item_toggled: function (ev) {
assert.strictEqual(ev.data.itemId, 'green');
assert.strictEqual(ev.data.isActive, true);
},
@@ -143,7 +143,7 @@ QUnit.module('GroupByMenu', {
var groupByMenu = createGroupByMenu(this.groupbys,
{fieldname: {sortable: true, string: 'Super Date', type: 'date', isDate: true}}
);
- groupByMenu.$el.click(function(event) {
+ groupByMenu.$el.click(function (event) {
// we do not want a click to get out and change the url, for example
throw new Error('No click should get out of the groupby menu');
});
diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js
index 990686da97a..88c5416398e 100644
--- a/addons/web/static/tests/views/search_view_tests.js
+++ b/addons/web/static/tests/views/search_view_tests.js
@@ -170,7 +170,7 @@ QUnit.module('Search View', {
actionManager.doAction(1);
$('span.fa-bars').prev().click();
- $('li.o_menu_item a').click();
+ $('.o_menu_item a').click();
assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle',
'should have a facet with candle name');
actionManager.destroy();
@@ -187,7 +187,7 @@ QUnit.module('Search View', {
actionManager.doAction(1);
$('span.fa-bars').prev().click();
- $('li.o_menu_item a').click();
+ $('.o_menu_item a').click();
assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle',
'should have a facet with candle name');
$('.o_facet_remove:first').click();
@@ -304,7 +304,7 @@ QUnit.module('Search View', {
// // no groupby is applied
assert.strictEqual($('div.o_facet_values span').length, 0);
// // open 'Add custom Groupby' menu
- $('.o_group_by_menu .o_add_custom_group a').click();
+ $('.o_group_by_menu .o_add_custom_group').click();
// // click on 'Apply' button
$('.o_group_by_menu .o_generator_menu button').click();
// // data should be grouped by the field 'Birthday' using the interval 'month'
@@ -364,7 +364,7 @@ QUnit.module('Search View', {
actionManager.doAction(1);
$('span.fa-filter').click();
- $('li.o_add_custom_filter').click();
+ $('.o_add_custom_filter').click();
$('.o_apply_filter').click();
assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'ID is \"0\"',
'should have a facet with candle name');
@@ -382,9 +382,9 @@ QUnit.module('Search View', {
actionManager.doAction(1);
$('span.fa-filter').click();
- $('li.o_add_custom_filter').click();
+ $('.o_add_custom_filter').click();
$('.o_apply_filter').click();
- $('li.o_menu_item').click();
+ $('.o_menu_item').click();
assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0,
'no facet should be in the search view');
actionManager.destroy();
@@ -455,20 +455,20 @@ QUnit.module('Search View', {
// open menu 'Filter'
$('.o_search_options .fa-filter').click();
// open menu options
- $('li.o_menu_item').click();
- $('li.o_menu_item .o_item_option[data-option_id="today"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="this_week"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="this_month"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="this_quarter"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="this_year"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="yesterday"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_week"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_month"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_quarter"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_year"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_7_days"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_30_days"]').click();
- $('li.o_menu_item .o_item_option[data-option_id="last_365_days"]').click();
+ $('.o_menu_item').click();
+ $('.o_menu_item .o_item_option[data-option_id="today"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="this_week"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="this_month"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="this_quarter"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="this_year"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="yesterday"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_week"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_month"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_quarter"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_year"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_7_days"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_30_days"]').click();
+ $('.o_menu_item .o_item_option[data-option_id="last_365_days"]').click();
actionManager.destroy();
window.Date = RealDate;
@@ -498,7 +498,7 @@ QUnit.module('Search View', {
actionManager.doAction(6);
$('span.fa-filter').click();
- $('.o_filters_menu li.o_menu_item a').click();
+ $('.o_filters_menu .o_menu_item a').click();
$('.o_item_option:first').click();
$('span.fa-star').click();
$('.o_favorites_menu .o_save_search a').click();
diff --git a/addons/web/static/tests/widgets/dropdown_menu_tests.js b/addons/web/static/tests/widgets/dropdown_menu_tests.js
index 0669b92c87f..b378a94ee58 100644
--- a/addons/web/static/tests/widgets/dropdown_menu_tests.js
+++ b/addons/web/static/tests/widgets/dropdown_menu_tests.js
@@ -44,9 +44,9 @@ QUnit.module('Web', {
assert.expect(2);
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items);
- assert.strictEqual(dropdownMenu.$('li').length, 4, 'should have 4 li counting the dividers');
- assert.strictEqual(dropdownMenu.$('li:nth-child(2)').text().trim(), 'Some Item',
- 'first li should have "Some Item" description');
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4, 'should have 4 elements counting the dividers');
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').eq(1).text().trim(), 'Some Item',
+ 'first element should have "Some Item" description');
dropdownMenu.destroy();
});
@@ -57,7 +57,7 @@ QUnit.module('Web', {
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, {
intercepts: {
- menu_item_toggled: function(ev) {
+ menu_item_toggled: function (ev) {
eventNumber++;
assert.strictEqual(ev.data.itemId, 1);
if (eventNumber === 1) {
@@ -86,7 +86,7 @@ QUnit.module('Web', {
assert.expect(0);
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items);
- dropdownMenu.$el.click(function() {
+ dropdownMenu.$el.click(function () {
// we do not want a click to get out and change the url, for example
throw new Error('No click should get out of the dropdown menu');
});
@@ -103,13 +103,13 @@ QUnit.module('Web', {
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items);
// open dropdown
dropdownMenu.$('button:first').click();
- assert.strictEqual(dropdownMenu.$('li').length, 4);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4);
// open options menu
dropdownMenu.$('span.fa-caret-right').click();
- assert.strictEqual(dropdownMenu.$('li').length, 7);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7);
// close options menu
dropdownMenu.$('span.fa-caret-down').click();
- assert.strictEqual(dropdownMenu.$('li').length, 4);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4);
dropdownMenu.destroy();
});
@@ -123,10 +123,10 @@ QUnit.module('Web', {
dropdownMenu.$('button:first').click();
// open options menu
dropdownMenu.$('span.fa-caret-right').click();
- assert.strictEqual(dropdownMenu.$('li').length, 7);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7);
dropdownMenu.$('button:first').click();
dropdownMenu.$('button:first').click();
- assert.strictEqual(dropdownMenu.$('li').length, 4);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4);
dropdownMenu.destroy();
});
@@ -140,7 +140,7 @@ QUnit.module('Web', {
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, {
intercepts: {
- menu_item_toggled: function(ev) {
+ menu_item_toggled: function (ev) {
eventNumber++;
if (eventNumber === 1) {
assert.strictEqual(ev.data.itemId, 1);
@@ -152,7 +152,7 @@ QUnit.module('Web', {
assert.strictEqual(ev.data.optionId, false);
}
},
- item_option_changed: function(ev) {
+ item_option_changed: function (ev) {
if (eventNumber === 1) {
assert.strictEqual(ev.data.itemId, 1);
assert.strictEqual(ev.data.isActive, true);
@@ -165,20 +165,20 @@ QUnit.module('Web', {
dropdownMenu.$('button:first').click();
// open options menu
dropdownMenu.$('span.fa-caret-right').click();
- assert.strictEqual(dropdownMenu.$('li').length, 7);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7);
// Don't forget there is a hidden li.divider element at first place among children
assert.ok(!dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected'));
- dropdownMenu.$('li.o_item_option:first').click();
+ dropdownMenu.$('.o_item_option:first').click();
assert.ok(dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected'));
assert.ok(dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected'));
- dropdownMenu.$('li.o_item_option:nth-child(3)').click();
+ dropdownMenu.$('.o_item_option:nth-child(3)').click();
assert.ok(dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected'));
assert.ok(dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected'));
- dropdownMenu.$('li.o_item_option:nth-child(3)').click();
+ dropdownMenu.$('.o_item_option:nth-child(3)').click();
assert.ok(!dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected'));
assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected'));
@@ -190,15 +190,15 @@ QUnit.module('Web', {
var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, {
intercepts: {
- menu_item_deleted: function(ev) {
+ menu_item_deleted: function (ev) {
assert.strictEqual(ev.data.itemId, 2);
},
},
});
dropdownMenu.$('button:first').click();
- assert.strictEqual(dropdownMenu.$('li').length, 4);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4);
dropdownMenu.$('span.o_trash_button').click();
- assert.strictEqual(dropdownMenu.$('li').length, 2);
+ assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 2);
dropdownMenu.destroy();
});
});
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index b05e7e05bf6..1224accd6cb 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -162,7 +162,6 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/web_calendar.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_mobile.scss"/>
- <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_groupby_menu.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/dropdown_menu.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_extra.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/data_export.scss"/>
@@ -399,8 +398,8 @@
<t t-call="web.menu_link"/>
</li>
<li id="menu_more_container" class="dropdown" style="display: none;">
- <a role="menuitem" aria-haspopup="true" href="#" class="dropdown-toggle" data-toggle="dropdown" id="more_menu_button">More <b class="caret"></b></a>
- <ul id="menu_more" class="dropdown-menu" role="menu"></ul>
+ <a role="menuitem" aria-haspopup="true" href="#" class="dropdown-toggle" data-toggle="dropdown" id="more_menu_button">More</a>
+ <div id="menu_more" class="dropdown-menu" role="menu"/>
</li>
</ul>