summaryrefslogtreecommitdiff
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
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
-rw-r--r--addons/account/static/src/xml/account_reconciliation.xml12
-rw-r--r--addons/board/static/src/scss/dashboard.scss2
-rw-r--r--addons/board/static/src/xml/board.xml14
-rw-r--r--addons/crm/views/crm_lead_views.xml16
-rw-r--r--addons/event/views/event_views.xml12
-rw-r--r--addons/google_drive/static/tests/gdrive_test.js8
-rw-r--r--addons/hr_contract/views/hr_contract_views.xml10
-rw-r--r--addons/hr_recruitment/views/hr_recruitment_views.xml16
-rw-r--r--addons/im_support/static/src/xml/systray.xml4
-rw-r--r--addons/mail/static/src/js/activity.js12
-rw-r--r--addons/mail/static/src/js/composers/mention_manager.js9
-rw-r--r--addons/mail/static/src/js/followers.js14
-rw-r--r--addons/mail/static/src/scss/abstract_thread_window.scss2
-rw-r--r--addons/mail/static/src/scss/composer.scss2
-rw-r--r--addons/mail/static/src/scss/discuss.scss2
-rw-r--r--addons/mail/static/src/scss/systray.scss2
-rw-r--r--addons/mail/static/src/xml/composer.xml18
-rw-r--r--addons/mail/static/src/xml/followers.xml18
-rw-r--r--addons/mail/static/src/xml/systray.xml32
-rw-r--r--addons/mail/static/src/xml/web_kanban_activity.xml23
-rw-r--r--addons/mail/static/tests/chatter_tests.js6
-rw-r--r--addons/mail/static/tests/discuss_tests.js2
-rw-r--r--addons/mail/static/tests/systray/systray_activity_menu_tests.js4
-rw-r--r--addons/mail/static/tests/systray/systray_messaging_menu_tests.js2
-rw-r--r--addons/maintenance/views/maintenance_views.xml28
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_editor.js12
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.ui.scss75
-rw-r--r--addons/mass_mailing/static/src/xml/mass_mailing.xml12
-rw-r--r--addons/mass_mailing/views/mass_mailing_views.xml40
-rw-r--r--addons/mass_mailing/views/snippets_themes_options.xml4
-rw-r--r--addons/note/views/note_views.xml10
-rw-r--r--addons/point_of_sale/views/pos_templates.xml34
-rw-r--r--addons/portal/static/src/js/portal.js10
-rw-r--r--addons/portal/views/portal_templates.xml68
-rw-r--r--addons/project/static/tests/project_tests.js10
-rw-r--r--addons/project/views/project_views.xml20
-rw-r--r--addons/survey/views/survey_views.xml16
-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
-rw-r--r--addons/web_editor/static/src/js/editor/rte.summernote.js2
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.editor.js14
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js74
-rw-r--r--addons/web_editor/static/src/js/editor/summernote.js6
-rw-r--r--addons/web_editor/static/src/js/tours/rte.js2
-rw-r--r--addons/web_editor/static/src/scss/web_editor.ui.scss144
-rw-r--r--addons/web_editor/static/src/xml/ace.xml8
-rw-r--r--addons/web_editor/static/src/xml/editor.xml9
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml8
-rw-r--r--addons/web_tour/static/src/xml/debug_manager.xml10
-rw-r--r--addons/website/static/src/js/content/menu.js2
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js22
-rw-r--r--addons/website/static/src/js/menu/customize.js40
-rw-r--r--addons/website/static/src/js/menu/navbar.js8
-rw-r--r--addons/website/static/src/scss/website.scss2
-rw-r--r--addons/website/views/snippets.xml271
-rw-r--r--addons/website/views/website_navbar_templates.xml69
-rw-r--r--addons/website/views/website_templates.xml46
-rw-r--r--addons/website_blog/views/snippets.xml44
-rw-r--r--addons/website_blog/views/website_blog_templates.xml8
-rw-r--r--addons/website_event_track/views/event_track_views.xml14
-rw-r--r--addons/website_forum/views/website_forum.xml83
-rw-r--r--addons/website_forum_doc/views/doc.xml12
-rw-r--r--addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml28
-rw-r--r--addons/website_links/views/website_links_template.xml10
-rw-r--r--addons/website_sale/static/src/js/website_sale_tour_shop.js2
-rw-r--r--addons/website_sale/static/src/js/website_sale_tracking.js2
-rw-r--r--addons/website_sale/views/snippets.xml24
-rw-r--r--addons/website_sale/views/templates.xml22
-rw-r--r--addons/website_sale_digital/views/website_sale_digital.xml8
-rw-r--r--addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml12
-rw-r--r--addons/website_theme_install/static/src/scss/website_theme_install.scss2
-rw-r--r--doc/howtos/themes.rst10
-rw-r--r--odoo/addons/base/tests/test_translate.py2
-rw-r--r--odoo/addons/test_new_api/static/tests/x2many.js8
110 files changed, 1191 insertions, 1289 deletions
diff --git a/addons/account/static/src/xml/account_reconciliation.xml b/addons/account/static/src/xml/account_reconciliation.xml
index 1c0d535e5bc..44986549a92 100644
--- a/addons/account/static/src/xml/account_reconciliation.xml
+++ b/addons/account/static/src/xml/account_reconciliation.xml
@@ -164,10 +164,10 @@
</div>
<div class="dropdown pull-right">
<a data-toggle="dropdown" href="#"><span class="fa fa-cog" role="img" aria-label="Settings"/></a>
- <ul class="dropdown-menu dropdown-menu-right" role="menu" aria-label="Presets config">
- <li><a role="menuitem" class="reconcile_model_create" href="#">Create model</a></li>
- <li><a role="menuitem" class="reconcile_model_edit" href="#">Modify models</a></li>
- </ul>
+ <div class="dropdown-menu dropdown-menu-right" role="menu" aria-label="Presets config">
+ <a role="menuitem" class="dropdown-item reconcile_model_create" href="#">Create model</a>
+ <a role="menuitem" class="dropdown-item reconcile_model_edit" href="#">Modify models</a>
+ </div>
</div>
</div>
<table class="pull-left">
@@ -218,8 +218,8 @@
<td class="cell_label">
<t t-if="line.partner_id &amp;&amp; line.partner_id !== state.st_line.partner_id">
<t t-if="line.partner_name.length">
- <t t-esc="line.partner_name"/>:
- </t>
+ <t t-esc="line.partner_name"/>:
+ </t>
</t>
<t t-esc="line.label || line.name"/>
<t t-if="line.ref &amp;&amp; line.ref.length"> : </t>
diff --git a/addons/board/static/src/scss/dashboard.scss b/addons/board/static/src/scss/dashboard.scss
index 67f3d818b76..683bdf52eaf 100644
--- a/addons/board/static/src/scss/dashboard.scss
+++ b/addons/board/static/src/scss/dashboard.scss
@@ -148,5 +148,5 @@
// Favorites menu in control panel
.o_add_to_dashboard {
display: none; // hidden by default
- @include o-search-options-dropdown-custom-li;
+ @include o-search-options-dropdown-custom-item;
}
diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml
index 00e94d73162..cb907290fd1 100644
--- a/addons/board/static/src/xml/board.xml
+++ b/addons/board/static/src/xml/board.xml
@@ -75,14 +75,12 @@
</t>
<t t-name="SearchView.addtodashboard">
- <li class="o_add_to_dashboard_link o_closed_menu">
- <a href="#">Add to my Dashboard</a>
- </li>
- <li class="o_add_to_dashboard">
- <input class="o_add_to_dashboard_input" type="text"/>
- </li>
- <li class="o_add_to_dashboard">
+ <a href="#" class="dropdown-item o_add_to_dashboard_link o_closed_menu">Add to my Dashboard</a>
+ <div class="dropdown-item-text o_add_to_dashboard">
+ <input class="o_input o_add_to_dashboard_input" type="text"/>
+ </div>
+ <div class="dropdown-item-text o_add_to_dashboard">
<button type="button" class="btn btn-primary o_add_to_dashboard_button">Add</button>
- </li>
+ </div>
</t>
</template>
diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml
index dbf50c5d896..d72c2fd29c8 100644
--- a/addons/crm/views/crm_lead_views.xml
+++ b/addons/crm/views/crm_lead_views.xml
@@ -324,16 +324,16 @@
<div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown">
- <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit</a></li></t>
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- <li t-if="! record.active.value"><a role="menuitem" name="action_set_active" type="object">Restore</a></li>
- <li t-if="record.active.value"><a role="menuitem" name="action_set_unactive" type="object">Archive</a></li>
- <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" data-field="color" role="menu"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit</a></t>
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ <a t-if="! record.active.value" role="menuitem" name="action_set_active" type="object" class="dropdown-item">Restore</a>
+ <a t-if="record.active.value" role="menuitem" name="action_set_unactive" type="object" class="dropdown-item">Archive</a>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content">
<div>
diff --git a/addons/event/views/event_views.xml b/addons/event/views/event_views.xml
index 87c51f7f92f..ebdc52397c5 100644
--- a/addons/event/views/event_views.xml
+++ b/addons/event/views/event_views.xml
@@ -238,7 +238,7 @@
<div>
<field name="seats_availability" widget='radio'/>
<span attrs="{'invisible': [('seats_availability', '=', 'unlimited')]}" class="oe_read_only">
- to
+ to
</span>
<field name="seats_max" attrs="{'invisible': [('seats_availability', '=', 'unlimited')], 'required': [('seats_availability', '=', 'limited')]}"/>
</div>
@@ -305,15 +305,15 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown">
- <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
+ <div class="dropdown-menu" role="menu">
<t t-if="widget.deletable">
- <li><a role="menuitem" type="delete">Delete</a></li>
+ <a role="menuitem" type="delete" class="dropdown-item">Delete</a>
</t>
- <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" data-field="color" role="menu"/></li>
- </ul>
+ <ul class="oe_kanban_colorpicker" data-field="color" role="menu"/>
+ </div>
</div>
<div class="o_event_left">
<div class="o_day"><t t-esc="record.date_begin.raw_value.getDate()"/></div>
diff --git a/addons/google_drive/static/tests/gdrive_test.js b/addons/google_drive/static/tests/gdrive_test.js
index edf6a0c4ca2..78fac5f39b6 100644
--- a/addons/google_drive/static/tests/gdrive_test.js
+++ b/addons/google_drive/static/tests/gdrive_test.js
@@ -94,16 +94,16 @@ QUnit.module('gdrive_integration', {
return $.when();
}
return this._super.apply(this, arguments);
- }
+ },
});
- var google_action = form.sidebar.$('.oe_share_gdoc');
+ var $googleAction = form.sidebar.$('.oe_share_gdoc');
- assert.strictEqual(google_action.length, 1,
+ assert.strictEqual($googleAction.length, 1,
'The button to the google action should be present');
// Trigger opening of the dynamic link
- google_action.find('a:first').click();
+ $googleAction.click();
form.destroy();
});
diff --git a/addons/hr_contract/views/hr_contract_views.xml b/addons/hr_contract/views/hr_contract_views.xml
index ef1cfad0f33..9e5b234c956 100644
--- a/addons/hr_contract/views/hr_contract_views.xml
+++ b/addons/hr_contract/views/hr_contract_views.xml
@@ -175,13 +175,13 @@
<t t-name="kanban-box">
<div class="oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown" groups="base.group_user">
- <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit Contract</a></li></t>
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit Contract</a></t>
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ </div>
</div>
<div class="oe_kanban_content">
<div>
diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml
index 2569e5a59a4..10b4ddd7b33 100644
--- a/addons/hr_recruitment/views/hr_recruitment_views.xml
+++ b/addons/hr_recruitment/views/hr_recruitment_views.xml
@@ -290,14 +290,14 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_applicant_kanban oe_semantic_html_override">
<div class="o_dropdown_kanban dropdown">
- <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- <li><a role="menuitem" name="action_makeMeeting" type="object">Schedule Interview</a></li>
- <li role="menuitem" aira-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ <a role="menuitem" name="action_makeMeeting" type="object" class="dropdown-item">Schedule Interview</a>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content">
<div class="o_kanban_record_top">
@@ -340,7 +340,7 @@
</div>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="30" height="30" class="oe_kanban_avatar"/>
</div>
-
+
</div>
</div>
<div class="oe_clear"></div>
@@ -971,7 +971,7 @@
(0, 0, {'view_mode': 'graph', 'view_id': ref('hr_applicant_view_graph')})]"/>
<field name="context">{}</field> <!-- force empty -->
</record>
- <menuitem name="Reports" id="report_hr_recruitment" parent="menu_hr_recruitment_root"
+ <menuitem name="Reports" id="report_hr_recruitment" parent="menu_hr_recruitment_root"
sequence="99" action="hr_applicant_action_analysis"/>
<record id="action_hr_recruitment_report_filtered_department" model="ir.actions.act_window">
<field name="name">Recruitment Analysis</field>
diff --git a/addons/im_support/static/src/xml/systray.xml b/addons/im_support/static/src/xml/systray.xml
index eb182a04ff4..1cb14637b36 100644
--- a/addons/im_support/static/src/xml/systray.xml
+++ b/addons/im_support/static/src/xml/systray.xml
@@ -3,10 +3,10 @@
<t t-extend="mail.systray.MessagingMenu">
<t t-jquery=".o_mail_systray_dropdown" t-operation="append">
- <li t-if="widget.supportChannel" class="o_mail_systray_dropdown_bottom">
+ <div t-if="widget.supportChannel" class="o_mail_systray_dropdown_bottom">
<t t-set="preview" t-value="widget.supportChannel"/>
<t t-call="mail.Preview"/>
- </li>
+ </div>
</t>
</t>
diff --git a/addons/mail/static/src/js/activity.js b/addons/mail/static/src/js/activity.js
index 3a63b1fbd60..c8a3b8dddde 100644
--- a/addons/mail/static/src/js/activity.js
+++ b/addons/mail/static/src/js/activity.js
@@ -371,7 +371,7 @@ var Activity = AbstractActivityField.extend({
var KanbanActivity = AbstractActivityField.extend({
template: 'mail.KanbanActivity',
events: {
- 'click .o_activity_btn': '_onButtonClicked',
+ 'show.bs.dropdown': '_onDropdownShow',
'click .o_schedule_activity': '_onScheduleActivity',
'click .o_mark_as_done': '_onMarkActivityDone',
},
@@ -411,7 +411,7 @@ var KanbanActivity = AbstractActivityField.extend({
}).join(' ');
});
$span.addClass('o_activity_color_' + (this.activityState || 'default'));
- if (this.$el.hasClass('open')) {
+ if (this.$el.hasClass('show')) {
// note: this part of the rendering might be asynchronous
this._renderDropdown();
}
@@ -455,13 +455,9 @@ var KanbanActivity = AbstractActivityField.extend({
/**
* @private
- * @param {MouseEvent} ev
*/
- _onButtonClicked: function (ev) {
- ev.preventDefault();
- if (!this.$el.hasClass('open')) {
- this._renderDropdown();
- }
+ _onDropdownShow: function () {
+ this._renderDropdown();
},
/**
* @private
diff --git a/addons/mail/static/src/js/composers/mention_manager.js b/addons/mail/static/src/js/composers/mention_manager.js
index fb8d9ddc065..62608fbf511 100644
--- a/addons/mail/static/src/js/composers/mention_manager.js
+++ b/addons/mail/static/src/js/composers/mention_manager.js
@@ -319,15 +319,18 @@ var MentionManager = Widget.extend({
suggestions: suggestions,
}));
this.$el
- .addClass('open')
- .find('ul')
+ .addClass('show')
+ .find('.dropdown-menu')
+ .addClass('show')
.css('max-width', this._composer.$input.width())
.find('.o_mention_proposition')
.first()
.addClass('active');
this._open = true;
} else {
- this.$el.removeClass('open');
+ this.$el.removeClass('show')
+ .find('.dropdown-menu')
+ .removeClass('show');
this.$el.empty();
this._open = false;
}
diff --git a/addons/mail/static/src/js/followers.js b/addons/mail/static/src/js/followers.js
index a28f72edb1c..42d5519ff40 100644
--- a/addons/mail/static/src/js/followers.js
+++ b/addons/mail/static/src/js/followers.js
@@ -135,9 +135,9 @@ var Followers = AbstractField.extend({
var old_parent_model;
var $list;
if (dialog) {
- $list = $('<ul>').appendTo(this.dialog.$el);
+ $list = $('<div>').appendTo(this.dialog.$el);
} else {
- $list = this.$('.o_subtypes_list ul');
+ $list = this.$('.o_subtypes_list .dropdown-menu');
}
$list.empty();
@@ -145,7 +145,7 @@ var Followers = AbstractField.extend({
_.each(data, function (record) {
if (old_parent_model !== record.parent_model && old_parent_model !== undefined) {
- $list.append($('<li>').addClass('divider'));
+ $list.append($('<div>', {class: 'dropdown-divider'}));
}
old_parent_model = record.parent_model;
record.followed = record.followed || undefined;
@@ -408,11 +408,11 @@ var Followers = AbstractField.extend({
ev.stopPropagation();
this._updateSubscription(ev);
var $list = this.$('.o_subtypes_list');
- if (!$list.hasClass('open')) {
- $list.addClass('open');
+ if (!$list.hasClass('show')) {
+ $list.addClass('show');
}
- if (this.$('.o_subtypes_list ul')[0].children.length < 1) {
- $list.removeClass('open');
+ if (this.$('.o_subtypes_list .dropdown-menu')[0].children.length < 1) {
+ $list.removeClass('show');
}
},
});
diff --git a/addons/mail/static/src/scss/abstract_thread_window.scss b/addons/mail/static/src/scss/abstract_thread_window.scss
index 21fc4ebd7ad..39de4fc9c51 100644
--- a/addons/mail/static/src/scss/abstract_thread_window.scss
+++ b/addons/mail/static/src/scss/abstract_thread_window.scss
@@ -119,7 +119,7 @@ $o-mail-thread-window-zindex: $zindex-modal + 1 !default;
font-size: smaller;
}
}
- &.open .o_thread_window_dropdown_toggler .o_total_unread_counter, .o_thread_window_expand {
+ &.show .o_thread_window_dropdown_toggler .o_total_unread_counter, .o_thread_window_expand {
display: none;
}
diff --git a/addons/mail/static/src/scss/composer.scss b/addons/mail/static/src/scss/composer.scss
index 884ca88134e..1eb2de031d5 100644
--- a/addons/mail/static/src/scss/composer.scss
+++ b/addons/mail/static/src/scss/composer.scss
@@ -45,7 +45,7 @@
width: 100%;
resize: none;
}
- .o_composer_mention_dropdown .o_mention_proposition > a {
+ .o_composer_mention_dropdown .o_mention_proposition {
@include o-text-overflow;
width: 100%;
padding: 3px 15px;
diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss
index 5995cab52e2..2c07068d9a9 100644
--- a/addons/mail/static/src/scss/discuss.scss
+++ b/addons/mail/static/src/scss/discuss.scss
@@ -401,7 +401,7 @@
@include media-breakpoint-down(sm) {
- .o_main_navbar > ul.o_menu_systray > li.open .dropdown-menu {
+ .o_main_navbar > ul.o_menu_systray > li .dropdown-menu.show {
border: none;
}
diff --git a/addons/mail/static/src/scss/systray.scss b/addons/mail/static/src/scss/systray.scss
index 4d774b2824a..d52add73ec4 100644
--- a/addons/mail/static/src/scss/systray.scss
+++ b/addons/mail/static/src/scss/systray.scss
@@ -15,7 +15,7 @@
display: none;
}
}
- &.open .o_mail_systray_dropdown {
+ &.show .o_mail_systray_dropdown {
display: flex;
flex-flow: column nowrap;
}
diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml
index 9a373dad533..8ecf3f8a7c6 100644
--- a/addons/mail/static/src/xml/composer.xml
+++ b/addons/mail/static/src/xml/composer.xml
@@ -47,17 +47,15 @@
@param {boolean} [suggestions.divider=false]
-->
<t t-name="mail.MentionSuggestions">
- <ul class="dropdown-menu" role="menu">
+ <div class="dropdown-menu" role="menu">
<t t-foreach="suggestions" t-as="suggestion">
- <li role="separator" t-if="suggestion.divider" class="divider"/>
- <li t-if="!suggestion.divider" class="o_mention_proposition" t-att-data-id="suggestion.id">
- <a role="menuitem" href="#"/>
- </li>
+ <div role="separator" t-if="suggestion.divider" class="dropdown-divider"/>
+ <a t-else="" href="#" class="dropdown-item o_mention_proposition" t-att-data-id="suggestion.id" role="menuitem"/>
</t>
- </ul>
+ </div>
</t>
<t t-name="mail.MentionSuggestions.Partner" t-extend="mail.MentionSuggestions">
- <t t-jquery=".o_mention_proposition a" t-operation="append">
+ <t t-jquery=".o_mention_proposition" t-operation="append">
<span class="o_mention_name"><t t-esc="suggestion.name"/></span>
<t t-if="suggestion.email">
<span class="o_mention_info">(<t t-esc="suggestion.email"/>)</span>
@@ -65,18 +63,18 @@
</t>
</t>
<t t-name="mail.MentionSuggestions.Channel" t-extend="mail.MentionSuggestions">
- <t t-jquery=".o_mention_proposition a" t-operation="append">
+ <t t-jquery=".o_mention_proposition" t-operation="append">
<span class="o_mention_name"><t t-esc="suggestion.name"/></span>
</t>
</t>
<t t-name="mail.MentionSuggestions.CannedResponse" t-extend="mail.MentionSuggestions">
- <t t-jquery=".o_mention_proposition a" t-operation="append">
+ <t t-jquery=".o_mention_proposition" t-operation="append">
<span class="o_mention_name"><t t-esc="suggestion.source"/></span>
<span class="o_mention_info"><t t-esc="suggestion.substitution"/></span>
</t>
</t>
<t t-name="mail.MentionSuggestions.Command" t-extend="mail.MentionSuggestions">
- <t t-jquery=".o_mention_proposition a" t-operation="append">
+ <t t-jquery=".o_mention_proposition" t-operation="append">
<span class="o_mention_name">/<t t-esc="suggestion.name"/></span>
<span class="o_mention_info"><t t-esc="suggestion.help"/></span>
</t>
diff --git a/addons/mail/static/src/xml/followers.xml b/addons/mail/static/src/xml/followers.xml
index a19831308a6..bbf51ca5c68 100644
--- a/addons/mail/static/src/xml/followers.xml
+++ b/addons/mail/static/src/xml/followers.xml
@@ -12,7 +12,7 @@
<i class="fa fa-user" role="img" aria-label="Dropdown menu - Followers"></i>
<span class="o_followers_count"/>
</button>
- <ul class="dropdown-menu o_followers_list" role="menu"></ul>
+ <div class="dropdown-menu o_followers_list" role="menu"/>
</div>
<div class="o_followers_actions">
<div class="btn-group o_subtypes_list">
@@ -25,7 +25,7 @@
</button><button class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-bell" role="img" aria-label="Alarm menu" title="Alarm menu"/>
</button>
- <ul class="dropdown-menu" role="menu"/>
+ <div class="dropdown-menu" role="menu"/>
</div>
</div>
</div>
@@ -59,13 +59,9 @@
-->
<t t-name="mail.Followers.add_more">
<t t-if="widget.isEditable">
- <li role="menuitem" class="o_add_follower">
- <a href="#"> Add Followers </a>
- </li>
- <li role="menuitem" class="o_add_follower_channel">
- <a href="#"> Add Channels </a>
- </li>
- <li role="separator" t-if="widget.followers.length > 0" class="divider"/>
+ <a href="#" role="menuitem" class="dropdown-item o_add_follower">Add Followers</a>
+ <a href="#" role="menuitem" class="dropdown-item o_add_follower_channel">Add Channels</a>
+ <div role="separator" t-if="widget.followers.length > 0" class="dropdown-divider"/>
</t>
</t>
@@ -73,7 +69,7 @@
Message subtypes of a follower subscription
-->
<t t-name="mail.Followers.subtype">
- <li role="menuitem" class="o_subtype">
+ <div role="menuitem" class="o_subtype dropdown-item">
<div class="o_checkbox">
<input type="checkbox" t-att-checked="record.followed"
t-att-id="'input_mail_followers_subtype_'+record.id+(dialog ? '_in_dialog': '')"
@@ -84,7 +80,7 @@
<t t-esc="record.name"/>
</span>
<i t-if="display_warning" class="fa fa-warning text-warning" role="img" aria-label="Warning" title="Warning"/>
- </li>
+ </div>
</t>
<t t-name="mail.Followers.subtypes.warning">
<span class="text-warning">
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml
index 1f0cf850f8c..16fe5c9ef10 100644
--- a/addons/mail/static/src/xml/systray.xml
+++ b/addons/mail/static/src/xml/systray.xml
@@ -6,25 +6,25 @@
-->
<t t-name="mail.systray.MessagingMenu">
<li class="o_mail_systray_item">
- <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="Conversations" href="#">
+ <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false" title="Conversations" href="#">
<i class="fa fa-comments" role="img" aria-label="Messages"/> <span class="o_notification_counter badge"/>
</a>
- <ul class="o_mail_systray_dropdown dropdown-menu" role="menu">
- <li role="menuitem" t-if="widget.isMobile()">
+ <div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu">
+ <t t-if="widget.isMobile()">
<div class="o_mail_systray_mobile_header">
<button type="button" class="btn btn-secondary o_new_message"> New message </button>
</div>
- </li>
- <li role="menuitem" t-if="!widget.isMobile()" class="o_mail_systray_dropdown_top">
+ </t>
+ <div t-if="!widget.isMobile()" class="o_mail_systray_dropdown_top">
<div>
<button type="button" class="btn btn-link o_filter_button active"> All </button>
<button type="button" class="btn btn-link o_filter_button" data-filter='chat'> Chat </button>
<button type="button" class="btn btn-link o_filter_button" data-filter='channels'> Channels </button>
</div>
<button type="button" class="btn btn-link o_new_message"> New message </button>
- </li>
- <li role="menuitem" class="o_mail_systray_dropdown_items"/>
- <li role="menuitem" t-if="widget.isMobile()">
+ </div>
+ <div class="o_mail_systray_dropdown_items"/>
+ <t t-if="widget.isMobile()">
<div class="o_mail_mobile_tabs">
<div class="o_mail_mobile_tab o_filter_button active">
<span class="fa fa-envelope"/>
@@ -39,8 +39,8 @@
<span class="o_tab_title">Channels</span>
</div>
</div>
- </li>
- </ul>
+ </t>
+ </div>
</li>
</t>
@@ -64,9 +64,9 @@
-->
<t t-name="mail.systray.ActivityMenu.Previews">
<t t-if="_.isEmpty(activities)">
- <li class="text-center o_no_activity">
+ <div class="dropdown-item-text text-center o_no_activity">
<span>No activities planned.</span>
- </li>
+ </div>
</t>
<t t-foreach="activities" t-as="activity">
<div class="o_mail_preview" t-att-data-res_model="activity.model" t-att-data-model_name="activity.name" data-filter='my'>
@@ -94,12 +94,12 @@
<t t-name="mail.systray.ActivityMenu">
<li class="o_mail_systray_item">
- <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="Activities" href="#">
+ <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false" title="Activities" href="#">
<i class="fa fa-clock-o" role="img" aria-label="Activities"/> <span class="o_notification_counter badge"/>
</a>
- <ul class="o_mail_systray_dropdown dropdown-menu" role="menu">
- <li role="menuitem" class="o_mail_systray_dropdown_items"/>
- </ul>
+ <div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu">
+ <div class="o_mail_systray_dropdown_items"/>
+ </div>
</li>
</t>
</templates>
diff --git a/addons/mail/static/src/xml/web_kanban_activity.xml b/addons/mail/static/src/xml/web_kanban_activity.xml
index c3148f13e95..65ece45d865 100644
--- a/addons/mail/static/src/xml/web_kanban_activity.xml
+++ b/addons/mail/static/src/xml/web_kanban_activity.xml
@@ -3,25 +3,24 @@
<t t-name="mail.KanbanActivity">
<div class="o_kanban_inline_block dropdown o_kanban_selection o_mail_activity">
- <a class="dropdown-toggle o_activity_btn" data-toggle="dropdown">
+ <a class="dropdown-toggle o-no-caret o_activity_btn" data-toggle="dropdown">
<span class="fa fa-clock-o fa-lg fa-fw" t-att-title="widget.selection[widget.activityState]" role="img" t-att-aria-label="widget.selection[widget.activity_state]"/>
</a>
- <ul class="dropdown-menu o_activity" role="menu">
- </ul>
+ <div class="dropdown-menu o_activity" role="menu"/>
</div>
</t>
<t t-name="mail.KanbanActivityLoading">
- <li class="text-center o_no_activity">
+ <div class="dropdown-item text-center o_no_activity">
<span class="fa fa-spinner fa-spin fa-2x" role="img" aria-label="Loading..." title="Loading..."/>
- </li>
+ </div>
</t>
<t t-name="mail.KanbanActivityDropdown">
- <li role="menuitem" t-if="_.isEmpty(records)" class="text-center o_no_activity">
- <span>No activities planned.</span>
- </li>
- <li t-if="!_.isEmpty(records)" aria-haspopup="true" role="menu">
+ <span role="menuitem" t-if="_.isEmpty(records)" class="dropdown-item-text text-center o_no_activity">
+ No activities planned.
+ </span>
+ <div t-else="" class="dropdown-item" aria-haspopup="true" role="menu">
<ul class="nav o_activity_log" role="menu">
<t t-foreach="_.keys(records)" t-as="key">
<t t-set="logs" t-value="records[key]" />
@@ -51,12 +50,12 @@
</li>
</t>
</ul>
- </li>
- <li role="menuitem" class="o_schedule_activity text-center">
+ </div>
+ <div role="menuitem" class="o_schedule_activity text-center">
<a role="button" class="btn btn-link btn-block">
<i class="fa fa-plus fa-fw"></i><strong>Schedule an activity</strong>
</a>
- </li>
+ </div>
</t>
</templates>
diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js
index 43675fedcee..088a854333e 100644
--- a/addons/mail/static/tests/chatter_tests.js
+++ b/addons/mail/static/tests/chatter_tests.js
@@ -410,7 +410,7 @@ QUnit.test('kanban activity widget with an activity', function (assert) {
assert.strictEqual(rpcCount, 5, 'should have done an RPC to mark activity as done, and a read');
assert.ok($record.find('.o_mail_activity .o_activity_color_default:not(.o_activity_color_today)').length,
"activity widget should have been updated correctly");
- assert.strictEqual($record.find('.o_mail_activity.open').length, 1,
+ assert.strictEqual($record.find('.o_mail_activity.show').length, 1,
"dropdown should remain open when marking an activity as done");
assert.strictEqual($record.find('.o_no_activity').length, 1, "should have no activity scheduled");
@@ -1466,9 +1466,9 @@ QUnit.test('followers widget: follow/unfollow, edit subtypes', function (assert)
assert.strictEqual(form.$('.o_subtypes_list .o_subtype_checkbox:checked').length, 2,
'two subtypes should be checked by default');
form.$('.o_subtypes_list .dropdown-toggle').click(); // click to open the dropdown
- assert.ok(form.$('.o_subtypes_list.open').length, 'dropdown should be opened');
+ assert.ok(form.$('.o_subtypes_list.show').length, 'dropdown should be opened');
form.$('.o_subtypes_list .o_subtype input[data-id=2]').click(); // uncheck second subtype
- assert.ok(form.$('.o_subtypes_list.open').length, 'dropdown should remain opened');
+ assert.ok(form.$('.o_subtypes_list.show').length, 'dropdown should remain opened');
assert.ok(!form.$('.o_subtypes_list .o_subtype_checkbox[data-id=2]:checked').length,
'second subtype should now be unchecked');
diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js
index 54f13eb48a5..a061873c39b 100644
--- a/addons/mail/static/tests/discuss_tests.js
+++ b/addons/mail/static/tests/discuss_tests.js
@@ -211,7 +211,7 @@ QUnit.test('@ mention in channel', function (assert) {
fetchListenersDef
.then(concurrency.delay.bind(concurrency, 0))
.then(function () {
- assert.strictEqual(discuss.$('.dropup.o_composer_mention_dropdown.open').length, 1,
+ assert.strictEqual(discuss.$('.dropup.o_composer_mention_dropdown.show').length, 1,
"dropup menu for partner mentions should be open");
var $mentionPropositions = discuss.$('.o_mention_proposition');
diff --git a/addons/mail/static/tests/systray/systray_activity_menu_tests.js b/addons/mail/static/tests/systray/systray_activity_menu_tests.js
index 83dbcbdfe4c..1b034dbdfd7 100644
--- a/addons/mail/static/tests/systray/systray_activity_menu_tests.js
+++ b/addons/mail/static/tests/systray/systray_activity_menu_tests.js
@@ -100,9 +100,9 @@ QUnit.test('activity menu widget: activity menu with 3 records', function (asser
search_default_activities_overdue: 1,
};
activityMenu.$('.dropdown-toggle').click();
- assert.strictEqual(activityMenu.$el.hasClass("open"), true, 'ActivityMenu should be open');
+ assert.strictEqual(activityMenu.$el.hasClass("show"), true, 'ActivityMenu should be open');
activityMenu.$(".o_activity_filter_button[data-model_name='Issue'][data-filter='overdue']").click();
- assert.strictEqual(activityMenu.$el.hasClass("open"), false, 'ActivityMenu should be closed');
+ assert.strictEqual(activityMenu.$el.hasClass("show"), false, 'ActivityMenu should be closed');
// case 2: click on "today"
context = {
search_default_activities_today: 1,
diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
index 54859060437..e1c5ef1851c 100644
--- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
+++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
@@ -242,7 +242,7 @@ QUnit.test("messaging menu widget: mark as read on thread preview", function ( a
messagingMenu.$('.dropdown-toggle').click();
assert.ok(messagingMenu.$el.hasClass('o_mail_systray_item'),
'should be the instance of widget');
- assert.ok(messagingMenu.$el.hasClass('open'),
+ assert.ok(messagingMenu.$el.hasClass('show'),
'MessagingMenu should be open');
var $preview = messagingMenu.$('.o_mail_preview.o_preview_unread');
diff --git a/addons/maintenance/views/maintenance_views.xml b/addons/maintenance/views/maintenance_views.xml
index 5e06a9eff59..7c4d3a00995 100644
--- a/addons/maintenance/views/maintenance_views.xml
+++ b/addons/maintenance/views/maintenance_views.xml
@@ -134,14 +134,14 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_semantic_html_override">
<div class="o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit...</a></li></t>
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit...</a></t>
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content" tooltip="kanban-tooltip">
<div class="o_kanban_record_top">
@@ -431,16 +431,16 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit...</a></li></t>
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- <li role="separator" class="divider"></li>
- <li role="separator" class="dropdown-header">Record Colour</li>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit...</a></t>
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ <div role="separator" class="dropdown-divider"></div>
+ <div role="separator" class="dropdown-header">Record Colour</div>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content" tooltip="kanban-tooltip">
<div class="o_kanban_record_top">
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_editor.js b/addons/mass_mailing/static/src/js/mass_mailing_editor.js
index ae38436ea2c..ec7f01bbc25 100644
--- a/addons/mass_mailing/static/src/js/mass_mailing_editor.js
+++ b/addons/mass_mailing/static/src/js/mass_mailing_editor.js
@@ -197,7 +197,7 @@ snippets_editor.Class.include({
* Add proposition to install enterprise themes if not installed.
*/
var $mail_themes_upgrade = $dropdown.find(".o_mass_mailing_themes_upgrade");
- $mail_themes_upgrade.on("click", "> a", function (e) {
+ $mail_themes_upgrade.on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
odoo_top[window.callback+"_do_action"]("mass_mailing.action_mass_mailing_configuration");
@@ -208,15 +208,15 @@ snippets_editor.Class.include({
* is pressed.
*/
var selected_theme = false;
- $dropdown.on("mouseenter", "li > a", function (e) {
+ $dropdown.on("mouseenter", ".dropdown-item", function (e) {
if (first_choice) return;
e.preventDefault();
- var theme_params = themes_params[$(e.currentTarget).parent().index()];
+ var theme_params = themes_params[$(e.currentTarget).index()];
switch_theme(theme_params);
});
- $dropdown.on("click", "li > a", function (e) {
+ $dropdown.on("click", ".dropdown-item", function (e) {
e.preventDefault();
- var theme_params = themes_params[$(e.currentTarget).parent().index()];
+ var theme_params = themes_params[$(e.currentTarget).index()];
if (first_choice) {
switch_theme(theme_params);
$body.removeClass("o_force_mail_theme_choice");
@@ -244,7 +244,7 @@ snippets_editor.Class.include({
*/
$dropdown.on("shown.bs.dropdown", function () {
check_selected_theme();
- $dropdown.find("li").removeClass("selected").filter(function () {
+ $dropdown.find(".dropdown-item").removeClass("selected").filter(function () {
return ($(this).has(".o_thumb[style=\""+ "background-image: url(" + (selected_theme && selected_theme.img) + "_small.png)"+ "\"]").length > 0);
}).addClass("selected");
});
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
index 93ea1689882..daaf956fc68 100644
--- a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
@@ -27,7 +27,7 @@
}
}
- &.open > a {
+ &.show > a {
color: white;
background-color: $o-we-color-dark;
}
@@ -39,26 +39,23 @@
overflow: auto;
background-color: $o-we-color-dark;
- > li {
- margin: 0;
+ .dropdown-item {
+ padding: 10px 10px;
- > a {
- padding: 10px 10px;
-
- .o_thumb {
- display: none;
- background-size: cover;
- padding-top: 50%;
- border: 1px solid $o-we-color-light;
- border-top: 1px solid $o-we-color-text-normal;
+ .o_thumb {
+ display: none;
+ background-size: cover;
+ padding-top: 50%;
+ border: 1px solid $o-we-color-light;
+ border-top: 1px solid $o-we-color-text-normal;
- &.logo {
- display: block;
- }
+ &.logo {
+ display: block;
}
}
- &:hover > a {
+
+ &:hover {
background-color: $o-we-color-darker;
.o_thumb {
@@ -66,7 +63,7 @@
}
}
- &.selected > a .o_thumb {
+ &.selected .o_thumb {
border: 2px solid $o-brand-primary;
background-color: $o-we-color-dark;
}
@@ -86,41 +83,39 @@ body.o_force_mail_theme_choice {
.dropdown-menu {
display: block;
- > li {
+ .dropdown-item {
margin: 0;
float: left;
+ clear: none;
width: 100%;
max-width: 25%;
-
- > a {
+ transition: all 0.3s ease 0s;
+
+ .o_thumb {
+ display: none;
+ padding-top: 107%;
+ border: 1px solid $o-we-color-light;
+ border-top: 1px solid $o-we-color-text-normal;
+ box-shadow: 0 5px 10px rgba(black, 0.8);
+ will-change: transform;
+ backface-visibility: hidden;
transition: all 0.3s ease 0s;
- .o_thumb {
- display: none;
- padding-top: 107%;
- border: 1px solid $o-we-color-light;
- border-top: 1px solid $o-we-color-text-normal;
- box-shadow: 0 5px 10px rgba(black, 0.8);
- will-change: transform;
- backface-visibility: hidden;
- transition: all 0.3s ease 0s;
+ &.small {
+ display: block;
+ }
+ @media screen and (min-width: 900px) {
&.small {
- display: block;
+ display: none;
}
-
- @media screen and (min-width: 900px) {
- &.small {
- display: none;
- }
- &.large {
- display: block;
- }
+ &.large {
+ display: block;
}
}
}
- &:hover > a {
+ &:hover {
background-color: $o-we-color-dark;
.o_thumb {
@@ -128,7 +123,7 @@ body.o_force_mail_theme_choice {
}
}
- &.o_mass_mailing_themes_upgrade > a .o_thumb {
+ &.o_mass_mailing_themes_upgrade .o_thumb {
position: relative;
display: block;
border: 1px dashed white;
diff --git a/addons/mass_mailing/static/src/xml/mass_mailing.xml b/addons/mass_mailing/static/src/xml/mass_mailing.xml
index ae79ebff979..cdc23484cdd 100644
--- a/addons/mass_mailing/static/src/xml/mass_mailing.xml
+++ b/addons/mass_mailing/static/src/xml/mass_mailing.xml
@@ -5,18 +5,18 @@
<i class="fa fa-paint-brush"/> Change Style
</a>
<div class="dropdown-menu" role="menu">
- <li t-foreach="themes" t-as="theme">
- <a role="menuitem" href="#">
+ <t t-foreach="themes" t-as="theme">
+ <a role="menuitem" href="#" class="dropdown-item">
<div class="o_thumb small" t-attf-style="background-image: url(#{theme.img}_small.png)"/>
<div class="o_thumb large" t-attf-style="background-image: url(#{theme.img}_large.png)"/>
<div class="o_thumb logo" t-attf-style="background-image: url(#{theme.img}_logo.png)"/>
</a>
- </li>
- <li t-if="themes.length === 1" class="o_mass_mailing_themes_upgrade">
- <a role="menuitem" href="#">
+ </t>
+ <t t-if="themes.length === 1">
+ <a role="menuitem" href="#" class="dropdown-item o_mass_mailing_themes_upgrade">
<div class="o_thumb"><i class="fa fa-plus" role="img" aria-label="Upgrade theme" title="Upgrade theme"/></div>
</a>
- </li>
+ </t>
</div>
</div>
</templates>
diff --git a/addons/mass_mailing/views/mass_mailing_views.xml b/addons/mass_mailing/views/mass_mailing_views.xml
index b0f1e7cc44e..c94d197d7c8 100644
--- a/addons/mass_mailing/views/mass_mailing_views.xml
+++ b/addons/mass_mailing/views/mass_mailing_views.xml
@@ -313,17 +313,13 @@
</div>
<div class="o_kanban_card_manage_pane">
<div class="o_kanban_card_manage_section o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-if="widget.editable">
- <a role="menuitem" type="edit">Edit</a>
- </li>
- <li t-if="widget.deletable">
- <a role="menuitem" type="delete">Delete</a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit</a>
+ <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
+ </div>
</div>
</div>
</div>
@@ -566,15 +562,15 @@
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing">
<div class="o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
+ <div class="dropdown-menu" role="menu">
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
<t t-if="widget.deletable">
- <li><a role="menuitem" type="delete">Delete</a></li>
+ <a role="menuitem" type="delete" class="dropdown-item">Delete</a>
</t>
- </ul>
+ </div>
</div>
<div class="oe_kanban_content">
<div class="o_kanban_record_top">
@@ -920,20 +916,20 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing_campaign">
<div class="o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
+ <div class="dropdown-menu" role="menu">
<t t-if="widget.editable">
- <li><a role="menuitem" type="edit">Settings</a></li>
+ <a role="menuitem" type="edit" class="dropdown-item">Settings</a>
</t>
<t t-if="widget.deletable">
- <li><a role="menuitem" type="delete">Delete</a></li>
+ <a role="menuitem" type="delete" class="dropdown-item">Delete</a>
</t>
- <li role="separator" class="divider"/>
- <li role="separator" class="dropdown-header">Colour</li>
- <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" role="menu" data-field="color"/></li>
- </ul>
+ <div role="separator" class="dropdown-divider"/>
+ <div role="separator" class="dropdown-header">Colour</div>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content">
<div class="o_kanban_record_top mb16">
diff --git a/addons/mass_mailing/views/snippets_themes_options.xml b/addons/mass_mailing/views/snippets_themes_options.xml
index 0a2a4a7bf81..65b25bc76bf 100644
--- a/addons/mass_mailing/views/snippets_themes_options.xml
+++ b/addons/mass_mailing/views/snippets_themes_options.xml
@@ -43,9 +43,7 @@
data-exclude=".o_mail_no_colorpicker, .o_mail_no_options">
<li class="dropdown-submenu">
<a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Background Color</a>
- <ul class="dropdown-menu" role="menu">
- <li></li>
- </ul>
+ <div class="dropdown-menu" role="menu"/>
</li>
</div>
</template>
diff --git a/addons/note/views/note_views.xml b/addons/note/views/note_views.xml
index 772b320dc12..d9b5fb8f052 100644
--- a/addons/note/views/note_views.xml
+++ b/addons/note/views/note_views.xml
@@ -97,13 +97,13 @@
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
<div class="o_dropdown_kanban dropdown">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" type="delete">Delete</a></li>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" type="delete" class="dropdown-item">Delete</a>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<span>
<a name="action_close" type="object" t-if="record.open.raw_value"><i class="fa fa-check" role="img" aria-label="Opened" title="Opened"/></a>
diff --git a/addons/point_of_sale/views/pos_templates.xml b/addons/point_of_sale/views/pos_templates.xml
index c6be6011cdd..7327aa936c6 100644
--- a/addons/point_of_sale/views/pos_templates.xml
+++ b/addons/point_of_sale/views/pos_templates.xml
@@ -98,26 +98,26 @@
<div data-js='pos_company_logo' data-selector=".pos-company_logo"/>
<div data-js='pos_palette' data-selector=".pos-customer_facing_display">
- <li data-select-class="pos-palette_01"><a href="#" class="pos-palette_01"/></li>
- <li data-select-class="pos-palette_02"><a href="#" class="pos-palette_02"/></li>
- <li data-select-class="pos-palette_03"><a href="#" class="pos-palette_03"/></li>
- <li data-select-class="pos-palette_04"><a href="#" class="pos-palette_04"/></li>
- <li data-select-class="pos-palette_05"><a href="#" class="pos-palette_05"/></li>
- <li data-select-class="pos-palette_06"><a href="#" class="pos-palette_06"/></li>
- <li data-select-class="pos-palette_07"><a href="#" class="pos-palette_07"/></li>
- <li data-select-class="pos-palette_08"><a href="#" class="pos-palette_08"/></li>
- <li data-select-class="pos-palette_09"><a href="#" class="pos-palette_09"/></li>
- <li data-select-class="pos-palette_10"><a href="#" class="pos-palette_10"/></li>
- <li data-select-class="pos-palette_11"><a href="#" class="pos-palette_11"/></li>
- <li data-select-class="pos-palette_12"><a href="#" class="pos-palette_12"/></li>
- <li data-select-class="pos-palette_13"><a href="#" class="pos-palette_13"/></li>
+ <a href="#" class="pos-palette_01 dropdown-item" data-select-class="pos-palette_01"></a>
+ <a href="#" class="pos-palette_02 dropdown-item" data-select-class="pos-palette_02"></a>
+ <a href="#" class="pos-palette_03 dropdown-item" data-select-class="pos-palette_03"></a>
+ <a href="#" class="pos-palette_04 dropdown-item" data-select-class="pos-palette_04"></a>
+ <a href="#" class="pos-palette_05 dropdown-item" data-select-class="pos-palette_05"></a>
+ <a href="#" class="pos-palette_06 dropdown-item" data-select-class="pos-palette_06"></a>
+ <a href="#" class="pos-palette_07 dropdown-item" data-select-class="pos-palette_07"></a>
+ <a href="#" class="pos-palette_08 dropdown-item" data-select-class="pos-palette_08"></a>
+ <a href="#" class="pos-palette_09 dropdown-item" data-select-class="pos-palette_09"></a>
+ <a href="#" class="pos-palette_10 dropdown-item" data-select-class="pos-palette_10"></a>
+ <a href="#" class="pos-palette_11 dropdown-item" data-select-class="pos-palette_11"></a>
+ <a href="#" class="pos-palette_12 dropdown-item" data-select-class="pos-palette_12"></a>
+ <a href="#" class="pos-palette_13 dropdown-item" data-select-class="pos-palette_13"></a>
</div>
<div data-js='pos_background' data-selector=".pos-company_logo, .pos-adv">
- <li data-choose-image="true" data-no-preview="true"><a href="#"><b>Set Custom Image...</b></a></li>
- <li class="d-none pos-use_default_logo" data-background=""><a href="#">Default company logo</a></li>
- <li class="divider"/>
- <li data-toggle-class="pos-hidden"><a href="#"><i class="fa fa-eye-slash"/>Hide</a></li>
+ <a href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><b>Set Custom Image...</b></a>
+ <a href="#" class="dropdown-item d-none pos-use_default_logo" data-background="">Default company logo</a>
+ <div class="dropdown-divider"/>
+ <a href="#" class="dropdown-item" data-toggle-class="pos-hidden"><i class="fa fa-eye-slash"/>Hide</a>
</div>
</div>
</template>
diff --git a/addons/portal/static/src/js/portal.js b/addons/portal/static/src/js/portal.js
index 5842596db1b..f750bab1318 100644
--- a/addons/portal/static/src/js/portal.js
+++ b/addons/portal/static/src/js/portal.js
@@ -23,21 +23,21 @@ odoo.define('portal.portal', function (require) {
if ($('.o_portal_search_panel').length) {
$('.o_portal_search_panel .search-submit').click(function () {
var search = $.deparam(window.location.search.substring(1));
- search.search_in = $(".o_portal_search_panel li.active a").attr("href").replace("#","");
+ search.search_in = $(".o_portal_search_panel .dropdown-item.active").attr("href").replace("#","");
search.search = $(".o_portal_search_panel input[name='search']").val();
window.location.search = $.param(search);
});
- $('.o_portal_search_panel .dropdown-menu').find('a').click(function (e) {
+ $('.o_portal_search_panel .dropdown-menu').find('.dropdown-item').click(function (e) {
e.preventDefault();
- $(this).parents('.dropdown-menu').find('li').removeClass('active');
- $(this).parent('li').addClass('active');
+ $(this).parents('.dropdown-menu').find('.dropdown-item').removeClass('active');
+ $(this).closest('.dropdown-item').addClass('active');
var label = $(this).clone();
label.find('span.nolabel').remove();
$(".o_portal_search_panel span#search_label").text(label.text());
});
// init search label
- $('.o_portal_search_panel .dropdown-menu').find('li.active a').trigger('click');
+ $('.o_portal_search_panel .dropdown-menu').find('.dropdown-item.active').trigger('click');
$(".o_portal_search_panel input[name='search']").on('keyup', function (e) {
if (e.keyCode === 13) {
diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml
index 89bc191cf32..da0ca7f5f2c 100644
--- a/addons/portal/views/portal_templates.xml
+++ b/addons/portal/views/portal_templates.xml
@@ -47,12 +47,11 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<b>
<span t-esc="user_id.name[:23] + '...' if user_id.name and len(user_id.name) &gt; 25 else user_id.name"/>
- <span class="caret"></span>
</b>
</a>
- <ul class="dropdown-menu js_usermenu" role="menu">
- <li id="o_logout"><a t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a></li>
- </ul>
+ <div class="dropdown-menu js_usermenu" role="menu">
+ <a id="o_logout" class="dropdown-item" t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a>
+ </div>
</li>
</ul>
</div>
@@ -175,46 +174,46 @@
<ul class="nav pull-left">
<t t-raw="0"/>
<li t-if="searchbar_sortings" class="dropdown pull-left ml16">
- <button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-secondary navbar-btn">
+ <button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn">
<span class="fa fa-sort"/>
<span class="d-none d-lg-inline"><t t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/></span>
- <span class="caret"/>
</button>
- <ul class="dropdown-menu" aria-labelledby="portal_searchbar_sortby">
- <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}">
- <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)">
+ <div class="dropdown-menu" aria-labelledby="portal_searchbar_sortby">
+ <t t-foreach="searchbar_sortings" t-as="option">
+ <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"
+ t-attf-class="dropdown-item#{sortby == option and ' active' or ''}">
<span t-esc="searchbar_sortings[option].get('label')"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</li>
<li t-if="searchbar_filters" class="dropdown pull-left ml4">
- <button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-secondary navbar-btn">
+ <button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn">
<span class="fa fa-filter"/>
<span class="d-none d-lg-inline"><t t-esc="searchbar_filters[filterby].get('label', 'All')"/></span>
- <span class="caret"/>
</button>
- <ul class="dropdown-menu" aria-labelledby="portal_searchbar_filters">
- <li t-foreach="searchbar_filters" t-as="option" t-att-class="filterby == option and 'active'">
- <a t-att-href="default_url + '?' + keep_query('*', filterby=option)">
+ <div class="dropdown-menu" aria-labelledby="portal_searchbar_filters">
+ <t t-foreach="searchbar_filters" t-as="option">
+ <a t-att-href="default_url + '?' + keep_query('*', filterby=option)"
+ t-attf-class="dropdown-item#{filterby == option and ' active' or ''}">
<span t-esc="searchbar_filters[option].get('label')"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</li>
<li t-if="searchbar_groupby" class="dropdown pull-left ml4">
- <button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-secondary navbar-btn">
+ <button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn">
<span class="fa fa-object-group"/>
<span class="d-none d-lg-inline"><t t-esc="searchbar_groupby[groupby].get('label', 'None')"/></span>
- <span class="caret"/>
</button>
- <ul class="dropdown-menu" aria-labelledby="portal_searchbar_groupby">
- <li t-foreach="searchbar_groupby" t-as="option" t-att-class="groupby == option and 'active'">
- <a t-att-href="default_url + '?' + keep_query('*', groupby=option)">
+ <div class="dropdown-menu" aria-labelledby="portal_searchbar_groupby">
+ <t t-foreach="searchbar_groupby" t-as="option">
+ <a t-att-href="default_url + '?' + keep_query('*', groupby=option)"
+ t-attf-class="dropdown-item#{groupby == option and ' active' or ''}">
<span t-esc="searchbar_groupby[option].get('label')"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</li>
</ul>
<button t-if='searchbar_inputs' type="button" class="navbar-toggle collapsed btn ml16" data-toggle="collapse" data-target="#o_portal_searchbar_collapse"><span class="fa fa-search"/></button>
@@ -227,13 +226,16 @@
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">
- <span id="search_label" class="d-none d-md-inline mr4">Search</span><span class="caret"></span>
+ <span id="search_label" class="d-none d-md-inline mr4">Search</span>
</button>
- <ul class="dropdown-menu" role="menu">
- <li t-foreach='searchbar_inputs' t-as='input' t-att-class="search_in == searchbar_inputs[input]['input'] and 'active'">
- <a t-att-href="'#' + searchbar_inputs[input]['input']"><span t-raw="searchbar_inputs[input]['label']"/></a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach='searchbar_inputs' t-as='input'>
+ <a t-att-href="'#' + searchbar_inputs[input]['input']"
+ t-attf-class="dropdown-item#{search_in == searchbar_inputs[input]['input'] and ' active' or ''}">
+ <span t-raw="searchbar_inputs[input]['label']"/>
+ </a>
+ </t>
+ </div>
</div>
<input type="text" class="form-control" t-att-value='search' name="search"/>
<span class="input-group-btn">
@@ -383,8 +385,8 @@
</template>
<template id="my_account_link" name="Link to frontend portal" inherit_id="portal.frontend_layout">
- <xpath expr="//li[@id='o_logout']" position="before">
- <li><a href="/my/home" role="menuitem">My Account</a></li>
+ <xpath expr="//a[@id='o_logout']" position="before">
+ <a href="/my/home" role="menuitem" class="dropdown-item">My Account</a>
</xpath>
</template>
diff --git a/addons/project/static/tests/project_tests.js b/addons/project/static/tests/project_tests.js
index e659658a7a2..35b41e93e9d 100644
--- a/addons/project/static/tests/project_tests.js
+++ b/addons/project/static/tests/project_tests.js
@@ -82,14 +82,12 @@ QUnit.module('project', {
'<div>' +
'<field name="name"/>' +
'<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">' +
- '<li>' +
- '<a type="set_cover">Set Cover Image</a>'+
- '</li>' +
- '</ul>' +
+ '<div class="dropdown-menu" role="menu">' +
+ '<a type="set_cover" class="dropdown-item">Set Cover Image</a>'+
+ '</div>' +
'</div>' +
'<div>'+
'<field name="displayed_image_id" widget="attachment_image"/>'+
diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml
index de6663ec65d..835dcf868f0 100644
--- a/addons/project/views/project_views.xml
+++ b/addons/project/views/project_views.xml
@@ -552,19 +552,17 @@
</small>
</div>
<div class="o_dropdown_kanban dropdown" groups="base.group_user">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-if="widget.editable"><a role="menuitem" type="set_cover">Set Cover Image</a></li>
- <li t-if="widget.editable"><a role="menuitem" type="edit">Edit Task</a></li>
- <li t-if="widget.deletable"><a role="menuitem" type="delete">Delete</a></li>
- <li role="separator" class="divider"></li>
- <li role="separator" class="dropdown-header">Record's Colour</li>
- <li role="menuitem" aria-haspopup="true">
- <ul role="menu" class="oe_kanban_colorpicker" data-field="color"/>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a t-if="widget.editable" role="menuitem" type="set_cover" class="dropdown-item">Set Cover Image</a>
+ <a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit Task</a>
+ <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
+ <div role="separator" class="dropdown-divider"></div>
+ <div role="separator" class="dropdown-header">Record's Colour</div>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
</div>
<div class="o_kanban_record_body">
diff --git a/addons/survey/views/survey_views.xml b/addons/survey/views/survey_views.xml
index 94db82a6a8e..4a259b67e51 100644
--- a/addons/survey/views/survey_views.xml
+++ b/addons/survey/views/survey_views.xml
@@ -239,16 +239,16 @@
<div t-name="kanban-box" t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown" t-if="widget.editable">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" type="edit">Edit Survey</a></li>
- <li t-if="widget.deletable"><a role="menuitem" type="delete">Delete</a></li>
- <li role="separator" class="divider"/>
- <li role="separator">Color</li>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" type="edit" class="dropdown-item">Edit Survey</a>
+ <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
+ <div role="separator" class="dropdown-divider"/>
+ <div role="separator" class="dropdown-item-text">Color</div>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="o_kanban_record_top">
<h4 class="o_kanban_record_title mb4"><field name="title" /></h4>
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>
diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js
index cd482a18d7c..fa993dff99a 100644
--- a/addons/web_editor/static/src/js/editor/rte.summernote.js
+++ b/addons/web_editor/static/src/js/editor/rte.summernote.js
@@ -142,7 +142,7 @@ renderer.tplPopovers = function (lang, options) {
})).appendTo($resizefa);
}
var $colorfa = $airPopover.find('.note-color').clone();
- $colorfa.find("ul.dropdown-menu").css('min-width', '172px');
+ $colorfa.find(".dropdown-menu").css('min-width', '172px');
$resizefa.after($colorfa);
// show dialog box and delete
diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js
index 97bd73cb832..e3a8803619a 100644
--- a/addons/web_editor/static/src/js/editor/snippets.editor.js
+++ b/addons/web_editor/static/src/js/editor/snippets.editor.js
@@ -199,7 +199,7 @@ var SnippetEditor = Widget.extend({
// Attach own and parent options on the current overlay
var $style_button = this.$el.find('.oe_options');
- var $ul = $style_button.find('ul:first');
+ var $ul = $style_button.find('.dropdown-menu:first');
var $headers = $ul.find('.dropdown-header:data(editor)');
_.each($headers, (function (el) {
var $el = $(el);
@@ -218,7 +218,7 @@ var SnippetEditor = Widget.extend({
}).bind(this));
// Activate the overlay
- $style_button.toggleClass('d-none', $ul.children(':not(.o_main_header):not(.divider):not(.d-none)').length === 0);
+ $style_button.toggleClass('d-none', $ul.children(':not(.o_main_header):not(.dropdown-divider):not(.d-none)').length === 0);
this.cover();
this.$el.toggleClass('oe_active', !!focus);
@@ -262,13 +262,13 @@ var SnippetEditor = Widget.extend({
_initializeOptions: function () {
var self = this;
var $styles = this.$el.find('.oe_options');
- var $ul = $styles.find('ul:first');
+ var $ul = $styles.find('.dropdown-menu:first');
this.styles = {};
this.selectorSiblings = [];
this.selectorChildren = [];
var i = 0;
- $ul.append($('<li/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this));
+ $ul.append($('<div/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this));
var defs = _.map(this.templateOptions, function (val, option_id) {
if (!val.selector.is(self.$target)) {
return;
@@ -277,7 +277,7 @@ var SnippetEditor = Widget.extend({
if (val['drop-in']) self.selectorChildren.push(val['drop-in']);
var optionName = val.option;
- var $el = val.$el.children('li').clone(true).addClass('snippet-option-' + optionName);
+ var $el = val.$el.children().clone(true).addClass('snippet-option-' + optionName);
var option = new (options.registry[optionName] || options.Class)(
self,
val.base_target ? self.$target.find(val.base_target).eq(0) : self.$target,
@@ -288,7 +288,7 @@ var SnippetEditor = Widget.extend({
option.__order = i++;
return option.attachTo($el);
});
- $ul.append($('<li/>', {class: 'divider'}));
+ $ul.append($('<div/>', {class: 'dropdown-divider'}));
var $parents = this.$target.parents();
_.each($parents, function (parent) {
@@ -296,7 +296,7 @@ var SnippetEditor = Widget.extend({
if (parentEditor) {
for (var styleName in parentEditor.styles) {
if (!parentEditor.styles[styleName].preventChildPropagation) {
- $ul.append($('<li/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor));
+ $ul.append($('<div/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor));
break;
}
}
diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js
index 54e92b60028..463d2acf08e 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -17,10 +17,10 @@ var _t = core._t;
*/
var SnippetOption = Widget.extend({
events: {
- 'mouseenter a': '_onLinkEnter',
- 'click a': '_onLinkClick',
+ 'mouseenter': '_onLinkEnter',
+ 'click': '_onLinkClick',
'mouseleave': '_onMouseleave',
- 'mouseleave ul': '_onMouseleave',
+ 'mouseleave .dropdown-menu': '_onMouseleave',
},
/**
* When editing a snippet, its options are shown alongside the ones of its
@@ -30,7 +30,7 @@ var SnippetOption = Widget.extend({
preventChildPropagation: false,
/**
- * The option `$el` is supposed to be the associated <li/> element in the
+ * The option `$el` is supposed to be the associated DOM element in the
* options dropdown. The option controls another DOM element: the snippet it
* customizes, which can be found at `$target`. Access to the whole edition
* overlay is possible with `$overlay` (this is not recommended though).
@@ -115,18 +115,18 @@ var SnippetOption = Widget.extend({
/**
* Default option method which allows to select one and only one class in
* the option classes set and set it on the associated snippet. The common
- * case is having a subdropdown with each <li/> having a `data-select-class`
+ * case is having a subdropdown with each item having a `data-select-class`
* value allowing to choose the associated class.
*
* @param {boolean|string} previewMode
* - truthy if the option is enabled for preview or if leaving it (in
* that second case, the value is 'reset')
* - false if the option should be activated for good
- * @param {*} value - the class to activate ($li.data('selectClass'))
- * @param {jQuery} $li - the related DOMElement option
+ * @param {*} value - the class to activate ($opt.data('selectClass'))
+ * @param {jQuery} $opt - the related DOMElement option
*/
- selectClass: function (previewMode, value, $li) {
- var $group = $li && $li.closest('.dropdown-submenu');
+ selectClass: function (previewMode, value, $opt) {
+ var $group = $opt && $opt.closest('.dropdown-submenu');
if (!$group || !$group.length) {
$group = this.$el;
}
@@ -141,12 +141,12 @@ var SnippetOption = Widget.extend({
/**
* Default option method which allows to select one or multiple classes in
* the option classes set and set it on the associated snippet. The common
- * case is having a subdropdown with each <li/> having a `data-toggle-class`
+ * case is having a subdropdown with each item having a `data-toggle-class`
* value allowing to toggle the associated class.
*
* @see this.selectClass
*/
- toggleClass: function (previewMode, value, $li) {
+ toggleClass: function (previewMode, value, $opt) {
var $lis = this.$el.find('[data-toggle-class]').addBack('[data-toggle-class]');
var classes = $lis.map(function () {return $(this).data('toggleClass');}).get().join(' ');
var activeClasses = $lis.filter('.active, :has(.active)').map(function () {return $(this).data('toggleClass');}).get().join(' ');
@@ -163,7 +163,7 @@ var SnippetOption = Widget.extend({
/**
* Override the helper method to search inside the $target element instead
- * of the dropdown <li/> element.
+ * of the dropdown item element.
*
* @override
*/
@@ -225,13 +225,13 @@ var SnippetOption = Widget.extend({
* - truthy if the option is enabled for preview or if leaving it (in
* that second case, the value is 'reset')
* - false if the option should be activated for good
- * @param {jQuery} $li - the related DOMElement option
+ * @param {jQuery} $opt - the related DOMElement option
*/
- _select: function (previewMode, $li) {
+ _select: function (previewMode, $opt) {
var self = this;
// Options can say they respond to strong choice
- if (previewMode && ($li.data('noPreview') || $li.parent().data('noPreview'))) {
+ if (previewMode && ($opt.data('noPreview') || $opt.parent().data('noPreview'))) {
return;
}
// If it is not preview mode, the user selected the option for good
@@ -243,7 +243,7 @@ var SnippetOption = Widget.extend({
// Search for methods (data-...) (i.e. data-toggle-class) on the
// selected (sub)option and its parents
- var el = $li[0];
+ var el = $opt[0];
var methods = [];
do {
methods.push([el, el.dataset]);
@@ -302,20 +302,25 @@ var SnippetOption = Widget.extend({
* @param {Event} ev
*/
_onLinkEnter: function (ev) {
- var $li = $(ev.currentTarget).parent();
- if ($li.is('.dropdown-submenu')) {
- var $menu = $li.children('.dropdown-menu');
+ var $opt = $(ev.target);
+ if (!$opt.hasClass('dropdown-item')) {
+ return;
+ }
+
+ var $dsmenu = $opt.parent('.dropdown-submenu');
+ if ($dsmenu.length) {
+ var $menu = $dsmenu.children('.dropdown-menu'); // FIXME
if ($menu.length) {
- var menuRightPosition = $li.offset().left + $li.outerWidth() + $menu.outerWidth();
+ var menuRightPosition = $dsmenu.offset().left + $dsmenu.outerWidth() + $menu.outerWidth();
$menu.toggleClass('o_open_to_left', menuRightPosition > $(window).outerWidth());
}
}
- if (!$li.is(':hasData')) {
+ if (!$opt.is(':hasData')) {
return;
}
this.__click = false;
- this._select(true, $li);
+ this._select(true, $opt);
this.$target.trigger('snippet-option-preview', [this]);
},
/**
@@ -325,13 +330,14 @@ var SnippetOption = Widget.extend({
* @param {Event} ev
*/
_onLinkClick: function (ev) {
- var $li = $(ev.currentTarget).parent(':hasData');
- if (!$li.length) {
+ var $opt = $(ev.target);
+ if (!$opt.hasClass('dropdown-item') || !$opt.is(':hasData')) {
return;
}
+
ev.preventDefault();
this.__click = true;
- this._select(false, $li);
+ this._select(false, $opt);
this.$target.trigger('snippet-option-change', [this]);
},
/**
@@ -678,7 +684,7 @@ registry.colorpicker = SnippetOption.extend({
$toggles.parent().empty().append($clpicker);
}
- this.$el.find('li').append($pt);
+ this.$el.find('.dropdown-menu').append($pt);
}
var classes = [];
@@ -781,7 +787,7 @@ registry.background = SnippetOption.extend({
*
* @see this.selectClass for parameters
*/
- background: function (previewMode, value, $li) {
+ background: function (previewMode, value, $opt) {
if (previewMode === 'reset' && value === undefined) {
// No background has been selected and we want to reset back to the
// original custom image
@@ -800,16 +806,16 @@ registry.background = SnippetOption.extend({
/**
* @override
*/
- selectClass: function (previewMode, value, $li) {
- this.background(previewMode, '', $li);
- this._super(previewMode, value ? (value + ' oe_img_bg') : value, $li);
+ selectClass: function (previewMode, value, $opt) {
+ this.background(previewMode, '', $opt);
+ this._super(previewMode, value ? (value + ' oe_img_bg') : value, $opt);
},
/**
* Opens a media dialog to add a custom background image.
*
* @see this.selectClass for parameters
*/
- chooseImage: function (previewMode, value, $li) {
+ chooseImage: function (previewMode, value, $opt) {
// Put fake image in the DOM, edit it and use it as background-image
var $image = $('<img/>', {class: 'd-none', src: value}).appendTo(this.$target);
@@ -881,7 +887,7 @@ registry.background = SnippetOption.extend({
this._super.apply(this, arguments);
var src = this._getSrcFromCssValue();
- this.$el.find('li[data-background]')
+ this.$el.find('[data-background]')
.removeClass('active')
.filter(function () {
var bgOption = $(this).data('background');
@@ -889,7 +895,7 @@ registry.background = SnippetOption.extend({
})
.addClass('active');
- this.$el.find('li[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg'));
+ this.$el.find('[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg'));
},
/**
* Sets the given value as custom background image.
@@ -938,7 +944,7 @@ registry.background_position = SnippetOption.extend({
*
* @see this.selectClass for parameters
*/
- backgroundPosition: function (previewMode, value, $li) {
+ backgroundPosition: function (previewMode, value, $opt) {
var self = this;
this.previous_state = [this.$target.attr('class'), this.$target.css('background-size'), this.$target.css('background-position')];
diff --git a/addons/web_editor/static/src/js/editor/summernote.js b/addons/web_editor/static/src/js/editor/summernote.js
index 657a8bbac8c..784aab3493e 100644
--- a/addons/web_editor/static/src/js/editor/summernote.js
+++ b/addons/web_editor/static/src/js/editor/summernote.js
@@ -958,15 +958,15 @@ range.WrappedRange.prototype.isContentEditable = function () {
renderer.tplButtonInfo.fontsize = function (lang, options) {
var items = options.fontSizes.reduce(function (memo, v) {
- return memo + '<li><a data-event="fontSize" href="#" data-value="' + v + '">' +
+ return memo + '<a data-event="fontSize" href="#" class="dropdown-item" data-value="' + v + '">' +
'<i class="fa fa-check"></i> ' + v +
- '</a></li>';
+ '</a>';
}, '');
var sLabel = '<span class="note-current-fontsize">11</span>';
return renderer.getTemplate().button(sLabel, {
title: lang.font.size,
- dropdown: '<ul class="dropdown-menu">' + items + '</ul>'
+ dropdown: '<div class="dropdown-menu">' + items + '</div>'
});
};
diff --git a/addons/web_editor/static/src/js/tours/rte.js b/addons/web_editor/static/src/js/tours/rte.js
index 82c31da5259..0a4ae0b32c3 100644
--- a/addons/web_editor/static/src/js/tours/rte.js
+++ b/addons/web_editor/static/src/js/tours/rte.js
@@ -67,7 +67,7 @@ tour.register('rte', {
trigger: ".note-color button.dropdown-toggle",
}, {
content: "change text color",
- trigger: ".btn-group.open button[data-event=foreColor]:first",
+ trigger: ".btn-group.show button[data-event=foreColor]:first",
}, {
content: "change selection to change text bg-color again",
trigger: '#editable_area > section .row > div:first h1 font:eq(2)',
diff --git a/addons/web_editor/static/src/scss/web_editor.ui.scss b/addons/web_editor/static/src/scss/web_editor.ui.scss
index e82ad579fe8..bb5cddcffe1 100644
--- a/addons/web_editor/static/src/scss/web_editor.ui.scss
+++ b/addons/web_editor/static/src/scss/web_editor.ui.scss
@@ -409,7 +409,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
}
// Open menu
- &.open .btn {
+ &.show .btn {
background-color: $o-we-color-light;
&:before, &:after {
width: 9px;
@@ -430,43 +430,21 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
border: 1px solid $o-we-color-dark;
border-radius: 0;
background-color: $o-we-color-light;
- a {
+
+ .dropdown-item {
+ position: relative;
color: $o-we-color-text-light;
font-weight: normal;
font-size: 12px;
padding: 5px 35px 5px 20px;
- }
- > li {
- position: relative;
&:hover {
background-color: fade-out($o-we-color-dark, 0.5);
- > a {
- color: white;
- background: transparent;
- cursor: pointer;
- }
- > .dropdown-menu {
- display: block;
- left: 100%;
- top: 0;
-
- &.o_open_to_left {
- left: auto;
- right: 100%;
- }
- }
- }
- &.dropdown-submenu:before {
- @include o-position-absolute($top: 10px, $right: 10px);
- @include o-caret-right(3px);
- border-left-color: $o-we-color-text-light;
- }
- &.divider {
- background-color: $o-we-color-divider;
- margin: 0 8px;
+ color: white;
+ background: transparent;
+ cursor: pointer;
}
- &.active > a {
+ &.active {
color: white;
background-color: fade-out($o-we-color-dark, 0.5);
&:before {
@@ -476,53 +454,73 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
color: $o-brand-optional;
}
}
- &.dropdown-header {
- color: white;
- font-weight: bold;
- font-size: 12px;
- margin-top: 2px;
- &:hover {
- background-color: initial;
- }
+ > i {
+ width: 16px;
+ margin-right: 8px;
+ }
+ }
- &.o_main_header {
- padding-left: 8px;
- }
- &.o_parent_editor_header {
- color: wheat;
- font-weight: 400;
- font-size: 10px;
- margin: 7px 0 4px 4px;
- &::before {
- content: "\f148";
- @include o-position-absolute($top: 2px, $left: 8px);
- font-family: FontAwesome;
- transform: scaleX(-1);
- }
- ~ li:not(.dropdown-header) {
- a {
- font-size: 11px;
- padding: 4px 35px 4px 20px;
- opacity: 0.8;
- &:hover {
- opacity: 1;
- }
- }
- }
- }
+ .dropdown-submenu {
+ position: relative;
+
+ &::before {
+ @include o-position-absolute($top: 10px, $right: 10px);
+ @include o-caret-right(3px);
+ border-left-color: $o-we-color-text-light;
}
- &.separator {
+ &:hover > .dropdown-menu {
display: block;
- margin: 4px 35px 4px 20px;
- height: 1px;
- background: rgba($o-we-color-text-light, 0.1);
+ left: 100%;
+ top: 0;
+
+ &.o_open_to_left {
+ left: auto;
+ right: 100%;
+ }
}
+ }
- > a > i {
- width: 16px;
- margin-right: 8px;
+ .dropdown-divider {
+ display: block;
+ height: 1px;
+ background: rgba($o-we-color-text-light, 0.1);
+ margin: 0 8px;
+ }
+
+ .dropdown-header {
+ color: white;
+ font-weight: bold;
+ font-size: 12px;
+ margin-top: 2px;
+
+ &:hover {
+ background-color: initial;
+ }
+
+ &.o_main_header {
+ padding-left: 8px;
+ }
+ &.o_parent_editor_header {
+ color: wheat;
+ font-weight: 400;
+ font-size: 10px;
+ margin: 7px 0 4px 4px;
+ &::before {
+ content: "\f148";
+ @include o-position-absolute($top: 2px, $left: 8px);
+ font-family: FontAwesome;
+ transform: scaleX(-1);
+ }
+ ~ .dropdown-item {
+ font-size: 11px;
+ padding: 4px 35px 4px 20px;
+ opacity: 0.8;
+ &:hover {
+ opacity: 1;
+ }
+ }
}
}
}
@@ -749,7 +747,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
> .btn-group {
margin-top: -2px;
- &.open, .btn-group.open {
+ &.show, .btn-group.show {
.dropdown-toggle {
border-top: 2px solid white;
background-color: $o-we-color-darker;
@@ -767,7 +765,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
border-radius: 0;
background-color: $o-we-color-darker;
color: $o-we-color-text-normal;
- > li > a {
+ .dropdown-item {
width: 100%;
color: $o-we-color-text-light;
@@ -831,7 +829,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
.note-popover .popover, .note-editor {
.dropdown-menu {
- > li > a {
+ .dropdown-item {
> i {
visibility: hidden;
}
diff --git a/addons/web_editor/static/src/xml/ace.xml b/addons/web_editor/static/src/xml/ace.xml
index 257ce6af707..800a0ef2ced 100644
--- a/addons/web_editor/static/src/xml/ace.xml
+++ b/addons/web_editor/static/src/xml/ace.xml
@@ -6,10 +6,10 @@
<div class="form-inline o_ace_view_editor_title">
<div class="btn-group o_ace_type_switcher">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">XML (HTML)</button>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a></li>
- <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a>
+ <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a>
+ </div>
</div>
<select id="ace-view-list" class="o_res_list"/>
<select id="ace-scss-list" class="o_res_list d-none"/>
diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml
index 1928572fc0d..96f126391cd 100644
--- a/addons/web_editor/static/src/xml/editor.xml
+++ b/addons/web_editor/static/src/xml/editor.xml
@@ -95,14 +95,11 @@
<div class="btn-group">
<button class="btn btn-primary o_upload_image_button" type="button">Upload an image</button>
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" type="button">
- <span class="caret"/>
<span class="sr-only">Alternate Upload</span>
</button>
- <ul class="dropdown-menu" role="menu">
- <li>
- <a role="menuitem" class="o_upload_image_button_no_optimization">Upload image without optimization</a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" class="dropdown-item o_upload_image_button_no_optimization">Upload image without optimization</a>
+ </div>
</div>
</div>
<div>
diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml
index 586b920edf0..a0c35288b93 100644
--- a/addons/web_editor/static/src/xml/snippets.xml
+++ b/addons/web_editor/static/src/xml/snippets.xml
@@ -13,7 +13,7 @@
<a role="button" href="#" class="btn btn-secondary oe_snippet_parent" title="Select Parent Container" aria-label="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a>
<div class="dropdown oe_options d-none btn-group">
<a role="button" href="#" data-toggle="dropdown" class="btn btn-primary" title="Customize">Customize</a>
- <ul class="dropdown-menu" role="menu"/>
+ <div class="dropdown-menu" role="menu"/>
</div>
<a role="button" href="#" class="btn btn-secondary oe_snippet_move" title="Drag to Move" aria-label="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a>
<a role="button" href="#" class="btn btn-secondary oe_snippet_clone" title="Duplicate Container" aria-label="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a>
@@ -41,9 +41,9 @@
<t t-name="web_editor.many2one.button">
<div class="btn-group">
<a role="button" href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact"><i class="fa fa-search"></i></a>
- <ul class="dropdown-menu contact_menu" role="menu">
- <li><a role="menuitem"><input href="#" type="email" placeholder="Search"/></a></li>
- </ul>
+ <div class="dropdown-menu contact_menu" role="menu">
+ <a role="menuitem" class="dropdown-item"><input href="#" type="email" placeholder="Search"/></a>
+ </div>
</div>
</t>
diff --git a/addons/web_tour/static/src/xml/debug_manager.xml b/addons/web_tour/static/src/xml/debug_manager.xml
index 6077723cf27..4fb8a8d6570 100644
--- a/addons/web_tour/static/src/xml/debug_manager.xml
+++ b/addons/web_tour/static/src/xml/debug_manager.xml
@@ -2,14 +2,10 @@
<templates id="template" xml:space="preserve">
<t t-extend="WebClient.DebugManager.Global">
- <t t-jquery="li > a[data-action='select_view']" t-operation="after">
+ <t t-jquery="a[data-action='select_view']" t-operation="after">
<t t-if="manager._is_admin">
- <li t-if="manager.consume_tours_enabled">
- <a href="#" data-action="consume_tours">Disable Tours</a>
- </li>
- <li>
- <a href="#" data-action="start_tour">Start Tour</a>
- </li>
+ <a t-if="manager.consume_tours_enabled" href="#" class="dropdown-item" data-action="consume_tours">Disable Tours</a>
+ <a href="#" class="dropdown-item" data-action="start_tour">Start Tour</a>
</t>
</t>
</t>
diff --git a/addons/website/static/src/js/content/menu.js b/addons/website/static/src/js/content/menu.js
index 5f8c337802f..9a5f393c0f6 100644
--- a/addons/website/static/src/js/content/menu.js
+++ b/addons/website/static/src/js/content/menu.js
@@ -66,7 +66,7 @@ sAnimation.registry.affixMenu = sAnimation.Class.extend({
this.$headerClone.toggleClass('affixed', wOffset > (hOffset + 300));
// Reset opened menus
- this.$dropdowns.removeClass('open');
+ this.$dropdowns.removeClass('show');
this.$navbarCollapses.removeClass('in').attr('aria-expanded', false);
},
});
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index 977edd2db96..0c3d02bffb8 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -248,8 +248,8 @@ options.registry.carousel = options.Class.extend({
* @override
*/
_setActive: function () {
- this.$el.find('li[data-interval]').removeClass('active')
- .filter('li[data-interval=' + this.$target.attr('data-interval') + ']').addClass('active');
+ this.$el.find('[data-interval]').removeClass('active')
+ .filter('[data-interval=' + this.$target.attr('data-interval') + ']').addClass('active');
},
/**
* Rebinds carousel events on indicators.
@@ -340,7 +340,7 @@ options.registry.layout_column = options.Class.extend({
*
* @see this.selectClass for parameters
*/
- selectCount: function (previewMode, value, $li) {
+ selectCount: function (previewMode, value, $opt) {
this._updateColumnCount(value - this.$target.children().length);
},
@@ -402,8 +402,8 @@ options.registry.layout_column = options.Class.extend({
*/
_setActive: function () {
this._super.apply(this, arguments);
- this.$el.find('li[data-select-count]').removeClass('active')
- .filter('li[data-select-count=' + this.$target.children().length + ']').addClass('active');
+ this.$el.find('[data-select-count]').removeClass('active')
+ .filter('[data-select-count=' + this.$target.children().length + ']').addClass('active');
},
});
@@ -968,7 +968,7 @@ options.registry.gallery = options.Class.extend({
*
* @see this.selectClass for parameters
*/
- mode: function (previewMode, value, $li) {
+ mode: function (previewMode, value, $opt) {
this.$target.css('height', '');
this[value]();
this.$target
@@ -1017,7 +1017,7 @@ options.registry.gallery = options.Class.extend({
* Displays the images with a "slideshow" layout.
*/
slideshow: function () {
- var imgStyle = this.$el.find('li.active[data-styling]').data('styling') || '';
+ var imgStyle = this.$el.find('.active[data-styling]').data('styling') || '';
var urls = _.map(this._getImages(), function (img) {
return $(img).attr('src');
});
@@ -1050,8 +1050,8 @@ options.registry.gallery = options.Class.extend({
* @see this.selectClass for parameters
*/
styling: function (previewMode, value) {
- var classes = _.map(this.$el.find('li[data-styling]'), function (li) {
- return $(li).data('styling');
+ var classes = _.map(this.$el.find('[data-styling]'), function (el) {
+ return $(el).data('styling');
}).join(' ');
this.$('img').removeClass(classes).addClass(value);
},
@@ -1163,8 +1163,8 @@ options.registry.gallery = options.Class.extend({
.removeClass('active')
.filter('[data-styling="' + classes.join('"], [data-styling="') + '"]').addClass('active');
- this.$el.find('li[data-interval]').removeClass('active')
- .filter('li[data-interval='+this.$target.find('.carousel:first').attr('data-interval')+']')
+ this.$el.find('[data-interval]').removeClass('active')
+ .filter('[data-interval='+this.$target.find('.carousel:first').attr('data-interval')+']')
.addClass('active');
var interval = this.$target.find('.carousel:first').attr('data-interval');
diff --git a/addons/website/static/src/js/menu/customize.js b/addons/website/static/src/js/menu/customize.js
index 2d525ac903e..0eac78cc90f 100644
--- a/addons/website/static/src/js/menu/customize.js
+++ b/addons/website/static/src/js/menu/customize.js
@@ -12,22 +12,21 @@ var qweb = core.qweb;
var CustomizeMenu = Widget.extend({
xmlDependencies: ['/web_editor/static/src/xml/editor.xml'],
events: {
- 'click > ul a[data-view-id]': '_onCustomizeOptionClick',
+ 'show.bs.dropdown': '_onDropdownShow',
+ 'click .dropdown-item[data-view-id]': '_onCustomizeOptionClick',
},
/**
* @override
*/
start: function () {
- var viewName = $(document.documentElement).data('view-xmlid');
- if (!viewName) {
+ this.viewName = $(document.documentElement).data('view-xmlid');
+ if (!this.viewName) {
_.defer(this.destroy.bind(this));
}
- if (this.$el.is('.open')) {
- this._loadCustomizeOptions(viewName);
- } else {
- this.$el.one('mousedown', '> a.dropdown-toggle', this._loadCustomizeOptions.bind(this, viewName));
+ if (this.$el.is('.show')) {
+ this._loadCustomizeOptions();
}
},
@@ -61,15 +60,19 @@ var CustomizeMenu = Widget.extend({
* the current page and shows them as switchable elements in the menu.
*
* @private
- * @param {string} viewName - xml id
* @return {Deferred}
*/
- _loadCustomizeOptions: function (viewName) {
- var $menu = this.$el.children('ul');
+ _loadCustomizeOptions: function () {
+ if (this.__customizeOptionsLoaded) {
+ return $.when();
+ }
+ this.__customizeOptionsLoaded = true;
+
+ var $menu = this.$el.children('.dropdown-menu');
return this._rpc({
route: '/website/get_switchable_related_views',
params: {
- key: viewName,
+ key: this.viewName,
},
}).then(function (result) {
var currentGroup = '';
@@ -78,11 +81,10 @@ var CustomizeMenu = Widget.extend({
currentGroup = item.inherit_id[1];
$menu.append('<li class="dropdown-header">' + currentGroup + '</li>');
}
- var $li = $('<li/>', {role: 'presentation'})
- .append($('<a/>', {href: '#', 'data-view-id': item.id, role: 'menuitem'})
- .append(qweb.render('web_editor.components.switch', {id: 'switch-' + item.id, label: item.name})));
- $li.find('input').prop('checked', !!item.active);
- $menu.append($li);
+ var $a = $('<a/>', {href: '#', class: 'dropdown-item', 'data-view-id': item.id, role: 'menuitem'})
+ .append(qweb.render('web_editor.components.switch', {id: 'switch-' + item.id, label: item.name}));
+ $a.find('input').prop('checked', !!item.active);
+ $menu.append($a);
});
});
},
@@ -103,6 +105,12 @@ var CustomizeMenu = Widget.extend({
var viewID = parseInt($(ev.currentTarget).data('view-id'), 10);
this._doCustomize(viewID);
},
+ /**
+ * @private
+ */
+ _onDropdownShow: function () {
+ this._loadCustomizeOptions();
+ },
});
var AceEditorMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
diff --git a/addons/website/static/src/js/menu/navbar.js b/addons/website/static/src/js/menu/navbar.js
index 9a25d50c3ed..ed8cf1ffa31 100644
--- a/addons/website/static/src/js/menu/navbar.js
+++ b/addons/website/static/src/js/menu/navbar.js
@@ -11,7 +11,7 @@ var websiteNavbarRegistry = new rootWidget.RootWidgetRegistry();
var WebsiteNavbar = rootWidget.RootWidget.extend({
events: _.extend({}, rootWidget.RootWidget.prototype.events || {}, {
'click [data-action]': '_onActionMenuClick',
- 'mouseover > ul > li.dropdown:not(.open)': '_onMenuHovered',
+ 'mouseover > ul > li.dropdown:not(.show)': '_onMenuHovered',
'click .o_mobile_menu_toggle': '_onMobileMenuToggleClick',
}),
custom_events: _.extend({}, rootWidget.RootWidget.prototype.custom_events || {}, {
@@ -121,10 +121,10 @@ var WebsiteNavbar = rootWidget.RootWidget.extend({
* @param {Event} ev
*/
_onMenuHovered: function (ev) {
- var $opened = this.$('> ul > li.dropdown.open');
+ var $opened = this.$('> ul > li.dropdown.show');
if ($opened.length) {
- $opened.removeClass('open');
- $(ev.currentTarget).find('.dropdown-toggle').mousedown().focus().mouseup().click();
+ $opened.find('.dropdown-toggle').dropdown('toggle');
+ $(ev.currentTarget).find('.dropdown-toggle').dropdown('toggle');
}
},
/**
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
index ecc9babb274..9100155d9f6 100644
--- a/addons/website/static/src/scss/website.scss
+++ b/addons/website/static/src/scss/website.scss
@@ -518,7 +518,7 @@ div.carousel {
top: $o-navbar-height;
}
-.navbar .o_extra_menu_items.open > ul {
+.navbar .o_extra_menu_items.show > ul {
> li {
+ li {
border-top: 1px solid $gray-lighter;
diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml
index 929233dea9d..e1d9efb767d 100644
--- a/addons/website/views/snippets.xml
+++ b/addons/website/views/snippets.xml
@@ -764,128 +764,119 @@
<t t-call="web_editor.snippet_options"/>
<div data-js='gallery' data-selector=".o_gallery">
- <li data-add-images="true" data-no-preview="true"><a href="#"><i class="fa fa-plus-circle"/>Add images</a></li>
- <li data-remove-all-images="true" data-no-preview="true"><a href="#"><i class="fa fa-trash"/>Remove all images</a></li>
- <li class="separator"/>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-magic"/>Mode</a>
- <ul class="dropdown-menu" role="menu">
- <li data-mode="nomode"><a role="menuitem" href="#">Float</a></li>
- <li data-mode="masonry"><a role="menuitem" href="#">Masonry</a></li>
- <li data-mode="grid"><a role="menuitem" href="#">Grid</a></li>
- <li data-mode="slideshow"><a role="menuitem" href="#">Slideshow</a></li>
- </ul>
- </li>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-clock-o"/>Slideshow speed</a>
- <ul class="dropdown-menu" role="menu">
- <li data-interval="1000"><a role="menuitem" href="#">1s</a></li>
- <li data-interval="2000"><a role="menuitem" href="#">2s</a></li>
- <li data-interval="3000"><a role="menuitem" href="#">3s</a></li>
- <li data-interval="5000"><a role="menuitem" href="#">5s</a></li>
- <li data-interval="10000"><a role="menuitem" href="#">10s</a></li>
- <li data-interval="0"><a role="menuitem" href="#">Disable autoplay</a></li>
- </ul>
- </li>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-th"/>Columns</a>
- <ul class="dropdown-menu" role="menu">
- <li data-columns="1"><a role="menuitem" href="#">1</a></li>
- <li data-columns="2"><a role="menuitem" href="#">2</a></li>
- <li data-columns="3"><a role="menuitem" href="#">3</a></li>
- <li data-columns="4"><a role="menuitem" href="#">4</a></li>
- <li data-columns="6"><a role="menuitem" href="#">6</a></li>
- <li data-columns="12"><a role="menuitem" href="#">12</a></li>
- </ul>
- </li>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-arrows-h"/>Images spacing</a>
-
- <ul class="dropdown-menu" role="menu">
- <li data-select-class="o_spc-none"><a role="menuitem" href="#">None</a></li>
- <li data-select-class="o_spc-small"><a role="menuitem" href="#">Small</a></li>
- <li data-select-class="o_spc-medium"><a role="menuitem" href="#">Medium</a></li>
- <li data-select-class="o_spc-big"><a role="menuitem" href="#">Big</a></li>
- </ul>
- </li>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-paint-brush"/>Styling</a>
- <ul class="dropdown-menu" role="menu">
- <li data-styling=""><a role="menuitem" href="#">Square</a></li>
- <li data-styling="img-rounded"><a role="menuitem" href="#">Rounded corners</a></li>
- <li data-styling="img-thumbnail"><a role="menuitem" href="#">Thumbnails</a></li>
- <li data-styling="img-circle"><a role="menuitem" href="#">Circle</a></li>
- <li data-styling="shadow"><a role="menuitem" href="#">Shadows</a></li>
- </ul>
- </li>
- <li class="separator"/>
+ <a href="#" class="dropdown-item" data-add-images="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add images</a>
+ <a href="#" class="dropdown-item" data-remove-all-images="true" data-no-preview="true"><i class="fa fa-trash"/>Remove all images</a>
+ <div class="dropdown-divider"/>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magic"/>Mode</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-mode="nomode">Float</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-mode="masonry">Masonry</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-mode="grid">Grid</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-mode="slideshow">Slideshow</a>
+ </div>
+ </div>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Slideshow speed</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a>
+ </div>
+ </div>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-th"/>Columns</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="1">1</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="2">2</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="3">3</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="4">4</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="6">6</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-columns="12">12</a>
+ </div>
+ </div>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-h"/>Images spacing</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-none">None</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-small">Small</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-medium">Medium</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-big">Big</a>
+ </div>
+ </div>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-paint-brush"/>Styling</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-styling="">Square</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-styling="img-rounded">Rounded corners</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-styling="img-thumbnail">Thumbnails</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-styling="img-circle">Circle</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-styling="shadow">Shadows</a>
+ </div>
+ </div>
+ <div class="dropdown-divider"/>
</div>
<div data-js="background"
data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax, .s_banner .carousel-content">
- <li data-choose-image="true" data-no-preview="true">
- <a tabindex="-1" href="#"><i class="fa fa-picture-o"/>Choose Background Image</a>
- </li>
+ <a tabindex="-1" href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/>Choose Background Image</a>
</div>
<div data-js="background_position"
data-selector="section, :not(.o_gallery > .container) > .carousel, .s_banner .carousel-content">
- <li class="background_position_li" data-background-position="true" data-no-preview="true">
- <a tabindex="-1" href="#"><i class="fa fa-arrows"/>Background Image Sizing</a>
- </li>
+ <a tabindex="-1" href="#" class="dropdown-item background_position_li" data-background-position="true" data-no-preview="true"><i class="fa fa-arrows"/>Background Image Sizing</a>
</div>
<div data-js="colorpicker"
data-selector="section, :not(.o_gallery > .container) > .carousel"
data-exclude=".parallax">
- <li class="dropdown-submenu">
- <a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Background Color</a>
- <ul class="dropdown-menu" role="menu">
- <li></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>
+ <div class="dropdown-menu" role="menu"/>
+ </div>
</div>
<div data-js="colorpicker"
data-selector=".s_text_block_image_fw .row > div, .s_banner .carousel-content"
data-palette-exclude="grayscale"
data-palette-default="transparent_grayscale"
data-palette-title="Overlay Color">
- <li class="dropdown-submenu">
- <a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Overlay color</a>
- <ul class="dropdown-menu" role="menu">
- <li></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Overlay color</a>
+ <div class="dropdown-menu" role="menu"/>
+ </div>
</div>
<div data-js='gallery_img' data-selector=".o_gallery img">
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-refresh"/>Re-order</a>
- <ul class="dropdown-menu" role="menu" data-no-preview="true">
- <li data-position="first"><a role="menuitem" href="#">Move to first</a></li>
- <li data-position="prev"><a role="menuitem" href="#">Move to previous</a></li>
- <li data-position="next"><a role="menuitem" href="#">Move to next</a></li>
- <li data-position="last"><a role="menuitem" href="#">Move to last</a></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-refresh"/>Re-order</a>
+ <div class="dropdown-menu" role="menu" data-no-preview="true">
+ <a href="#" class="dropdown-item" role="menuitem" data-position="first">Move to first</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-position="prev">Move to previous</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-position="next">Move to next</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-position="last">Move to last</a>
+ </div>
+ </div>
</div>
<div data-js='carousel'
data-selector=":not(.o_gallery > .container) > .carousel">
- <li class="divider"></li>
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-clock-o"/>Slideshow speed</a>
- <ul class="dropdown-menu" role="menu">
- <li data-interval="1000"><a role="menuitem" href="#">1s</a></li>
- <li data-interval="2000"><a role="menuitem" href="#">2s</a></li>
- <li data-interval="3000"><a role="menuitem" href="#">3s</a></li>
- <li data-interval="5000"><a role="menuitem" href="#">5s</a></li>
- <li data-interval="10000"><a role="menuitem" href="#">10s</a></li>
- <li data-interval="0"><a role="menuitem" href="#">Disable autoplay</a></li>
- </ul>
- </li>
- <li data-add-slide="true" data-no-preview="true"><a href="#"><i class="fa fa-plus-circle"/>Add Slide</a></li>
- <li data-remove-slide="true" data-no-preview="true"><a href="#" ><i class="fa fa-trash-o"/>Remove Slide</a></li>
+ <div class="dropdown-divider"/>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Slideshow speed</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a>
+ </div>
+ </div>
+ <a href="#" class="dropdown-item" data-add-slide="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add Slide</a>
+ <a href="#" class="dropdown-item" data-remove-slide="true" data-no-preview="true"><i class="fa fa-trash-o"/>Remove Slide</a>
</div>
<div data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax"
@@ -899,17 +890,17 @@
data-selector="section"
data-target="> * > .row"
data-exclude=".s_text_block_image_fw, .s_company_team, .s_big_picture">
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-columns"/>Number of columns</a>
- <ul class="dropdown-menu" role="menu" data-no-preview="true">
- <li data-select-count="1"><a role="menuitem" href="#">1</a></li>
- <li data-select-count="2"><a role="menuitem" href="#">2</a></li>
- <li data-select-count="3"><a role="menuitem" href="#">3</a></li>
- <li data-select-count="4"><a role="menuitem" href="#">4</a></li>
- <li data-select-count="5"><a role="menuitem" href="#">5</a></li>
- <li data-select-count="6"><a role="menuitem" href="#">6</a></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-columns"/>Number of columns</a>
+ <div class="dropdown-menu" role="menu" data-no-preview="true">
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="1">1</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="2">2</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="3">3</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="4">4</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="5">5</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-count="6">6</a>
+ </div>
+ </div>
</div>
<div data-js="sizing_x"
@@ -929,53 +920,51 @@
</div>
<div data-selector=".o_image_floating">
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-expand"/>Margin</a>
- <ul class="dropdown-menu" role="menu">
- <li data-select-class="o_margin_xl"><a role="menuitem" href="#">Extra-Large</a></li>
- <li data-select-class="o_margin_l"><a role="menuitem" href="#">Large</a></li>
- <li data-select-class="o_margin_m"><a role="menuitem" href="#">Medium</a></li>
- <li data-select-class="o_margin_s"><a role="menuitem" href="#">Small</a></li>
- <li data-select-class=""><a role="menuitem" href="#">None</a></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-expand"/>Margin</a>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_xl">Extra-Large</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_l">Large</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_m">Medium</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_s">Small</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="">None</a>
+ </div>
+ </div>
</div>
<div data-selector=".o_image_floating">
- <li class="dropdown-submenu">
- <a tabindex="-2" href="#"><i class="fa fa-magnet"/>Float</a>
- <ul class="dropdown-menu" role="menu" data-no-preview="true">
- <li data-select-class="pull-left"><a role="menuitem" href="#">Left</a></li>
- <li data-select-class="pull-right"><a role="menuitem" href="#">Right</a></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magnet"/>Float</a>
+ <div class="dropdown-menu" role="menu" data-no-preview="true">
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="pull-left">Left</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select-class="pull-right">Right</a>
+ </div>
+ </div>
</div>
<div data-js="parallax" data-selector=".parallax">
- <li class="dropdown-submenu">
- <a tabindex="-1" href="#"><i class="fa fa-clock-o"/>Scroll Speed</a>
- <ul class="dropdown-menu" role="menu" name="parallax-scroll">
- <li data-scroll="0"><a role="menuitem" href="#">No-scroll</a></li>
- <li class="separator" role="separator"/>
- <li data-scroll="1"><a role="menuitem" href="#">Fixed</a></li>
- <li class="separator" role="separator"/>
- <li data-scroll="0.6"><a role="menuitem" href="#">Very Slow</a></li>
- <li data-scroll="1.2"><a role="menuitem" href="#">Slow</a></li>
- <li data-scroll="1.6"><a role="menuitem" href="#">Fast</a></li>
- <li data-scroll="2"><a role="menuitem" href="#">Very Fast</a></li>
- </ul>
- </li>
+ <div class="dropdown-submenu">
+ <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Scroll Speed</a>
+ <div class="dropdown-menu" role="menu" name="parallax-scroll">
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="0">No-scroll</a>
+ <div class="dropdown-divider" role="separator"/>
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="1">Fixed</a>
+ <div class="dropdown-divider" role="separator"/>
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="0.6">Very Slow</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.2">Slow</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.6">Fast</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-scroll="2">Very Fast</a>
+ </div>
+ </div>
</div>
<div data-js='ul'
data-selector=":not(li) > ul:has(ul,ol), :not(li) > ol:has(ul,ol)">
- <li data-toggle-class="o_ul_folded"><a href="#">Folded list</a></li>
+ <a href="#" class="dropdown-item" data-toggle-class="o_ul_folded">Folded list</a>
</div>
<div data-js="facebookPage" data-selector=".o_facebook_page">
- <li data-fb-page-options="true" data-no-preview="true">
- <a href="#"><i class="fa fa-facebook"/>Options</a>
- </li>
+ <a href="#" class="dropdown-item" data-fb-page-options="true" data-no-preview="true"><i class="fa fa-facebook"/>Options</a>
</div>
<div data-js='collapse'
diff --git a/addons/website/views/website_navbar_templates.xml b/addons/website/views/website_navbar_templates.xml
index 89edb16a756..a96dcecf68f 100644
--- a/addons/website/views/website_navbar_templates.xml
+++ b/addons/website/views/website_navbar_templates.xml
@@ -9,20 +9,26 @@
<nav groups="base.group_user" t-if="website and menu_data" id="oe_main_menu_navbar" class="o_main_navbar">
<ul id="oe_applications">
<li class="dropdown active">
- <a class="dropdown full" data-toggle="dropdown" href="#">
- <i class="fa fa-th-large"/> WEBSITE <b class="caret"/>
+ <a class="dropdown-toggle full" data-toggle="dropdown" href="#">
+ <i class="fa fa-th-large"/> WEBSITE
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-as="menu" t-foreach="menu_data['children']">
- <t t-set="debug_param" t-value="'?&amp;debug=' if debug else ''"/>
- <a role="menuitem" t-att-class="'oe_menu_toggler' if menu.get('children') else 'oe_menu_leaf'" t-att-data-action-id="menu['action'] and menu['action'].split(',')[1] or None" t-att-data-action-model="menu['action'] and menu['action'].split(',')[0] or None" t-att-data-menu="menu['id']" t-att-data-menu-xmlid="menu.get('xmlid')" t-att-href="'/web%s#menu_id=%s&amp;action=%s' % (debug_param, menu['id'], menu['action'] and menu['action'].split(',')[1] or '')">
+ <div class="dropdown-menu" role="menu">
+ <t t-set="debug_param" t-value="'?&amp;debug=' if debug else ''"/>
+ <t t-as="menu" t-foreach="menu_data['children']">
+ <a role="menuitem"
+ t-attf-class="dropdown-item #{'oe_menu_toggler' if menu.get('children') else 'oe_menu_leaf'}"
+ t-att-data-action-id="menu['action'] and menu['action'].split(',')[1] or None"
+ t-att-data-action-model="menu['action'] and menu['action'].split(',')[0] or None"
+ t-att-data-menu="menu['id']"
+ t-att-data-menu-xmlid="menu.get('xmlid')"
+ t-att-href="'/web%s#menu_id=%s&amp;action=%s' % (debug_param, menu['id'], menu['action'] and menu['action'].split(',')[1] or '')">
<i t-attf-class="fa #{menu.get('icon')} fa-lg fa-fw" t-if="menu.get('icon')" role="img" aria-label="Menu" title="Menu"/>
<span class="oe_menu_text">
<t t-esc="menu['name']"/>
</span>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</li>
</ul>
@@ -31,30 +37,30 @@
<ul class="o_menu_sections" groups="website.group_website_designer">
<!-- Content -->
<li t-if="editable" class="dropdown" id="content-menu">
- <a id="content-menu-button" class="dropdown-toggle waves" data-toggle="dropdown" href="#">Content</a>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" data-action="edit_menu" href="#" title="Edit Top Menu">Edit Menu</a></li>
- <li><a role="menuitem" href="/website/pages" title="Manage Your Website Pages">Manage Pages</a></li>
- <li t-if="deletable" role="separator" class="divider"></li>
- <li t-if="deletable"><a role="menuitem" href="#" data-action="page_properties">Page Properties</a></li>
- </ul>
+ <a id="content-menu-button" class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Content</a>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" data-action="edit_menu" href="#" title="Edit Top Menu" class="dropdown-item">Edit Menu</a>
+ <a role="menuitem" href="/website/pages" title="Manage Your Website Pages" class="dropdown-item">Manage Pages</a>
+ <div t-if="deletable" role="separator" class="dropdown-divider"/>
+ <a role="menuitem" href="#" data-action="page_properties" class="dropdown-item" t-if="deletable">Page Properties</a>
+ </div>
</li>
<!-- Customize -->
<li class="dropdown" id="customize-menu">
- <a class="dropdown-toggle waves" data-toggle="dropdown" href="#">Customize</a>
- <ul class="dropdown-menu" role="menu">
- <li id="theme_customize"><a role="menuitem" href="#" data-action="customize_theme">Customize Theme</a></li>
- <li id="html_editor"><a role="menuitem" href="#" data-action="ace">HTML/CSS Editor</a></li>
- <li id="install_apps"><a role="menuitem" href="/web#action=website.action_website_configuration">Settings</a></li>
- <li class="divider" role="separator"/>
- </ul>
+ <a class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Customize</a>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" data-action="customize_theme" class="dropdown-item" id="theme_customize">Customize Theme</a>
+ <a role="menuitem" href="#" data-action="ace" class="dropdown-item" id="html_editor">HTML/CSS Editor</a>
+ <a role="menuitem" href="/web#action=website.action_website_configuration" class="dropdown-item" id="install_apps">Settings</a>
+ <div role="separator" class="dropdown-divider"/>
+ </div>
</li>
<!-- Promote -->
<li class="dropdown" id="promote-menu">
- <a class="dropdown-toggle waves" data-toggle="dropdown" href="#">Promote</a>
- <ul class="dropdown-menu oe_promote_menu" role="menu">
- <li><a role="menuitem" data-action="promote-current-page" href="#" title="Promote page on the web">Optimize SEO</a></li>
- </ul>
+ <a class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Promote</a>
+ <div class="dropdown-menu oe_promote_menu" role="menu">
+ <a role="menuitem" data-action="promote-current-page" href="#" title="Promote page on the web" class="dropdown-item">Optimize SEO</a>
+ </div>
</li>
</ul>
@@ -85,15 +91,12 @@
</li>
<li t-if="'website_published' in main_object.fields_get() and main_object._name != 'website.page'">
<a role="button" class="btn btn-primary btn-xs dropdown-toggle css_edit_dynamic" data-toggle="dropdown">
- <span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</a>
- <ul class="dropdown-menu" role="menu">
- <li id="edit-in-backend">
- <a role="menuitem" style="text-align: left;" t-attf-href="/web#return_label=Website&amp;view_type=form&amp;model=#{main_object._name}&amp;id=#{main_object.id}&amp;action=#{action}"
- class="btn btn-link btn-xs" title='Edit in backend'>Edit in backend</a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" style="text-align: left;" t-attf-href="/web#return_label=Website&amp;view_type=form&amp;model=#{main_object._name}&amp;id=#{main_object.id}&amp;action=#{action}"
+ class="dropdown-item btn btn-link btn-xs" title='Edit in backend' id="edit-in-backend">Edit in backend</a>
+ </div>
</li>
<li t-if="translatable">
<a data-action="translate" href="#">TRANSLATE</a>
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index 37f85a2e161..44018c26a39 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -79,13 +79,13 @@
(submenu.clean_url() and request.httprequest.path == submenu.clean_url())) and 'active'
}">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
- <span t-field="submenu.name"/> <span class="caret" t-ignore="true"></span>
+ <span t-field="submenu.name"/>
</a>
- <ul class="dropdown-menu" role="menu">
+ <div class="dropdown-menu" role="menu">
<t t-foreach="submenu.child_id" t-as="submenu">
<t t-call="website.submenu"/>
</t>
- </ul>
+ </div>
</li>
</template>
@@ -314,15 +314,16 @@
<span t-esc="list(filter(lambda lg : lg[0] == lang, languages))[0][1].split('/').pop()"/>
<span class="caret ml4"/>
</button>
- <ul class="dropdown-menu" role="menu">
- <li t-foreach="languages" t-as="lg">
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach="languages" t-as="lg">
<a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])"
+ class="dropdown-item js_change_lang"
t-att-data-default-lang="(editable or translatable) and 'true' if website and lg[0] == website.default_lang_code else None"
- t-att-data-lang="lg[0]" class="js_change_lang">
+ t-att-data-lang="lg[0]">
<t t-esc="lg[1].split('/').pop()"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</div>
</li>
<li groups="website.group_website_publisher">
@@ -341,16 +342,12 @@
<div t-attf-class="btn-group #{btn_class} js_publish_management #{object.website_published and 'css_published' or 'css_unpublished'}" t-att-data-id="object.id" t-att-data-object="object._name" t-att-data-controller="publish_controller">
<button class="btn btn-danger js_publish_btn">Unpublished</button>
<button class="btn btn-success js_publish_btn">Published</button>
- <button type="button" t-attf-class="btn btn-secondary dropdown-toggle" t-att-id="'dopprod-%s' % object.id" data-toggle="dropdown">
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id">
+ <button type="button" t-attf-class="btn btn-secondary dropdown-toggle dropdown-toggle-split" t-att-id="'dopprod-%s' % object.id" data-toggle="dropdown"/>
+ <div class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id">
<t t-raw="0"/>
- <li t-if="publish_edit">
- <a role="menuitem" t-attf-href="/web#return_label=Website&amp;view_type=form&amp;model=#{object._name}&amp;id=#{object.id}&amp;action=#{action}"
- title='Edit in backend'>Edit</a>
- </li>
- </ul>
+ <a role="menuitem" t-attf-href="/web#return_label=Website&amp;view_type=form&amp;model=#{object._name}&amp;id=#{object.id}&amp;action=#{action}"
+ title='Edit in backend' class="dropdown-item" t-if="publish_edit">Edit</a>
+ </div>
</div>
</div>
</template>
@@ -879,18 +876,19 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml
<t t-call="website.website_search_box"/>
</form>
<div t-if="searchbar_sortings" class="dropdown pull-right mt8 mr8">
- <button class="btn btn-secondary" type="button" data-toggle="dropdown">
+ <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
<span class="fa fa-sort fa-lg" role="img" aria-label="Sort" title="Sort"/>
<span class="d-none d-xl-inline" t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/>
- <span class="caret" role="img" aria-label="Dropdown menu" title="Dropdown menu"></span>
</button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="portal_searchbar_sortby">
- <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}">
- <a role="menuitem" t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)">
+ <div class="dropdown-menu" aria-labelledby="portal_searchbar_sortby" role="menu">
+ <t t-foreach="searchbar_sortings" t-as="option">
+ <a role="menuitem"
+ t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"
+ t-attf-class="dropdown-item#{sortby == option and ' active' or ''}">
<span t-esc="searchbar_sortings[option].get('label')"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</div>
<h3 class="mt16">Manage Your Pages</h3>
<t t-if="not pages">
diff --git a/addons/website_blog/views/snippets.xml b/addons/website_blog/views/snippets.xml
index eee8bccc9b2..6366b9c5458 100644
--- a/addons/website_blog/views/snippets.xml
+++ b/addons/website_blog/views/snippets.xml
@@ -3,36 +3,36 @@
<template id="website_blog" inherit_id="website.snippets" name="Snippet Blog">
<xpath expr="//div[@id='snippet_options']" position="inside">
<div data-js="blog_cover" data-selector=".website_blog .o_blog_cover_container" data-no-check="true">
- <li data-change="true" data-no-preview="true"><a href="#">Change Cover</a></li>
- <li data-clear="true" data-no-preview="true"><a href="#" >No Cover</a></li>
+ <a href="#" class="dropdown-item" data-change="true" data-no-preview="true">Change Cover</a>
+ <a href="#" class="dropdown-item" data-clear="true" data-no-preview="true">No Cover</a>
<li class="dropdown-submenu">
<a href="#">Size</a>
- <ul class="dropdown-menu" role="menu">
- <li data-select-class="cover container-fluid cover_full"><a role="menuitem" href="#">Full Screen</a></li>
- <li data-select-class="cover container-fluid cover_narrow"><a role="menuitem" href="#">Mid screen</a></li>
- <li data-select-class="cover container cover_narrow"><a role="menuitem" href="#">Narrow</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container-fluid cover_full">Full Screen</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container-fluid cover_narrow">Mid screen</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container cover_narrow">Narrow</a>
+ </div>
</li>
<li class="dropdown-submenu">
<a href="#">Filter Intensity</a>
- <ul class="dropdown-menu" role="menu">
- <li data-filter_value="0.0"><a role="menuitem" href="#">None</a></li>
- <li data-filter_value="0.2"><a role="menuitem" href="#">Low</a></li>
- <li data-filter_value="0.4"><a role="menuitem" href="#">Medium</a></li>
- <li data-filter_value="0.6"><a role="menuitem" href="#">High</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.0">None</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.2">Low</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.4">Medium</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.6">High</a>
+ </div>
</li>
<li class="dropdown-submenu">
<a href="#">Filter Color</a>
- <ul class="dropdown-menu" role="menu">
- <li data-filter_color="oe_black"><a role="menuitem" href="#">Black</a></li>
- <li data-filter_color="oe_none"><a role="menuitem" href="#">White</a></li>
- <li data-filter_color="oe_blue"><a role="menuitem" href="#">Blue</a></li>
- <li data-filter_color="oe_yellow"><a role="menuitem" href="#">Yellow</a></li>
- <li data-filter_color="oe_red"><a role="menuitem" href="#">Red</a></li>
- <li data-filter_color="oe_purple"><a role="menuitem" href="#">Purple</a></li>
- <li data-filter_color="oe_green"><a role="menuitem" href="#">Green</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_black">Black</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_none">White</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_blue">Blue</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_yellow">Yellow</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_red">Red</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_purple">Purple</a>
+ <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_green">Green</a>
+ </div>
</li>
</div>
</xpath>
diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml
index b1ebc6cfc8a..1aa02994a5a 100644
--- a/addons/website_blog/views/website_blog_templates.xml
+++ b/addons/website_blog/views/website_blog_templates.xml
@@ -213,14 +213,14 @@
<!-- Blog Post Complete -->
<template id="blog_edit_options" inherit_id="website.user_navbar" name="Edit Blog Options">
- <xpath expr="//li[@id='edit-in-backend']" position="after">
- <li groups="website.group_website_designer" t-if="main_object._name == 'blog.post'">
+ <xpath expr="//a[@id='edit-in-backend']" position="after">
+ <t groups="website.group_website_designer" t-if="main_object._name == 'blog.post'">
<form class="duplicate d-none" action="/blog/post_duplicate" method="POST">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input name="blog_post_id" t-att-value="blog_post.id if blog_post else None"/>
</form>
- <a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
- </li>
+ <a href="#" class="duplicate dropdown-item" onclick="$(this).prev('form').submit()">Duplicate</a>
+ </t>
</xpath>
</template>
<template id="blog_post_complete" name="Blog Post">
diff --git a/addons/website_event_track/views/event_track_views.xml b/addons/website_event_track/views/event_track_views.xml
index efdeb374d04..d0ce53a11e8 100644
--- a/addons/website_event_track/views/event_track_views.xml
+++ b/addons/website_event_track/views/event_track_views.xml
@@ -18,15 +18,15 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown" groups="base.group_user">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" t-att-href="record.website_url.value">View Track</a></li>
- <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit Track</a></li></t>
- <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" t-att-href="record.website_url.value" class="dropdown-item">View Track</a>
+ <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit Track</a></t>
+ <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="oe_kanban_content">
<div class="o_kanban_record_top">
diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml
index a2a109ea9f4..200e26bb1d1 100644
--- a/addons/website_forum/views/website_forum.xml
+++ b/addons/website_forum/views/website_forum.xml
@@ -90,10 +90,10 @@
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
<i class="fa fa-cog" role="img" aria-label="Dropdown menu" title="Dropdown menu"/>
</button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
- <li><a role="menuitem" tabindex="-1" t-attf-href="/forum/#{slug(forum)}/edit_welcome_message?enable_editor=1">Design Welcome Message</a></li>
- <li><a role="menuitem" tabindex="-1" t-attf-href="/web#id=#{forum.id}&amp;view_type=form&amp;model=forum.forum">Forum Settings</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
+ <a role="menuitem" tabindex="-1" t-attf-href="/forum/#{slug(forum)}/edit_welcome_message?enable_editor=1" class="dropdown-item">Design Welcome Message</a>
+ <a role="menuitem" tabindex="-1" t-attf-href="/web#id=#{forum.id}&amp;view_type=form&amp;model=forum.forum" class="dropdown-item">Forum Settings</a>
+ </div>
</span>
</form>
</li>
@@ -137,14 +137,13 @@
</a>
<t t-if="multi_type">
<button type="button" class="btn btn-primary btn-lg col-sm-2 dropdown-toggle" data-toggle="dropdown">
- <span class="caret"></span>
<span class="sr-only">Select Post</span>
</button>
- <ul class="dropdown-menu" role="menu">
- <li t-if="forum.allow_question"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=question">Ask a Question</a></li>
- <li t-if="forum.allow_link"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=link">Submit a Link</a></li>
- <li t-if="forum.allow_discussion"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=discussion">New Discussion</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=question" class="dropdown-item" t-if="forum.allow_question">Ask a Question</a>
+ <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=link" class="dropdown-item" t-if="forum.allow_link">Submit a Link</a>
+ <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=discussion" class="dropdown-item" t-if="forum.allow_discussion">New Discussion</a>
+ </div>
</t>
</div>
<div class="panel panel-default">
@@ -418,40 +417,21 @@
<t t-if="sorting == 'create_date desc'"> by newest</t>
<t t-if="sorting == 'child_count desc'"> by most answered</t>
<t t-if="sorting == 'vote_count desc'"> by most voted</t>
- <b class="caret"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li role="separator" class="dropdown-header">Filter on</li>
- <li t-att-class="filters == 'all' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='all')">All</a>
- </li>
- <li t-att-class="filters == 'unanswered' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unanswered')">Unanswered</a>
- </li>
- <li t-if="uid" t-att-class="filters == 'followed' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='followed')">Followed</a>
- </li>
- <li role="separator" t-if="tag" class="dropdown-header">Tags</li>
- <li t-if="tag" t-att-class="tag and 'active' or None ">
- <a role="menuitem" href=""><t t-esc="tag.name"/></a>
- </li>
- <li role="separator" class="dropdown-header">Sort by</li>
- <li t-att-class="sorting == 'relevancy desc' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='relevancy desc')">Relevance</a>
- </li>
- <li t-att-class="sorting == 'write_date desc' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='write_date desc')">Last activity date</a>
- </li>
- <li t-att-class="sorting == 'create_date desc' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='create_date desc')">Newest</a>
- </li>
- <li t-att-class="sorting == 'child_count desc' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='child_count desc')">Most answered</a>
- </li>
- <li t-att-class="sorting == 'vote_count desc' and 'active' or None ">
- <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='vote_count desc')">Most voted</a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <div role="separator" class="dropdown-header">Filter on</div>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='all')" t-attf-class="dropdown-item#{filters == 'all' and ' active' or ''}">All</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unanswered')" t-attf-class="dropdown-item#{filters == 'unanswered' and ' active' or ''}">Unanswered</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='followed')" t-if="uid" t-attf-class="dropdown-item#{filters == 'followed' and ' active' or ''}">Followed</a>
+ <div role="separator" t-if="tag" class="dropdown-header">Tags</div>
+ <a role="menuitem" href="" t-if="tag" t-attf-class="dropdown-item#{tag and ' active' or None}"><t t-esc="tag.name"/></a>
+ <div role="separator" class="dropdown-header">Sort by</div>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='relevancy desc')" t-attf-class="dropdown-item#{sorting == 'relevancy desc' and ' active' or ''}">Relevance</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='write_date desc')" t-attf-class="dropdown-item#{sorting == 'write_date desc' and ' active' or ''}">Last activity date</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='create_date desc')" t-attf-class="dropdown-item#{sorting == 'create_date desc' and ' active' or ''}">Newest</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='child_count desc')" t-attf-class="dropdown-item#{sorting == 'child_count desc' and ' active' or ''}">Most answered</a>
+ <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='vote_count desc')" t-attf-class="dropdown-item#{sorting == 'vote_count desc' and ' active' or ''}">Most voted</a>
+ </div>
</small>
</h2>
<div t-foreach="question_ids" t-as="question" class="mb16">
@@ -1220,19 +1200,12 @@
<t t-if="queue_type == 'validation'"> Pending</t>
<t t-if="queue_type == 'flagged'"> Flagged</t>
<t t-if="queue_type == 'offensive'"> Offensive</t>
- <b class="caret"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-att-class="queue_type == 'validation' and 'active' or None ">
- <a role="menuitem" data-type='validation' t-attf-href="/forum/#{slug(forum)}/validation_queue">Pending</a>
- </li>
- <li t-att-class="queue_type == 'flagged' and 'active' or None ">
- <a role="menuitem" data-type='flagged' t-attf-href="/forum/#{slug(forum)}/flagged_queue">Flagged</a>
- </li>
- <li t-if="uid" t-att-class="queue_type == 'offensive' and 'active' or None ">
- <a role="menuitem" data-type='offensive' t-attf-href="/forum/#{slug(forum)}/offensive_posts">Offensive</a>
- </li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" data-type='validation' t-attf-href="/forum/#{slug(forum)}/validation_queue" t-attf-class="dropdown-item#{queue_type == 'validation' and ' active' or ''}">Pending</a>
+ <a role="menuitem" data-type='flagged' t-attf-href="/forum/#{slug(forum)}/flagged_queue" t-attf-class="dropdown-item#{queue_type == 'flagged' and ' active' or ''}">Flagged</a>
+ <a role="menuitem" data-type='offensive' t-attf-href="/forum/#{slug(forum)}/offensive_posts" t-if="uid" t-attf-class="dropdown-item#{queue_type == 'offensive' and ' active' or ''}">Offensive</a>
+ </div>
</span>
</h2>
<div class="text-center" t-if="count_posts == 0">
diff --git a/addons/website_forum_doc/views/doc.xml b/addons/website_forum_doc/views/doc.xml
index eca1b5811ae..a0a2f037269 100644
--- a/addons/website_forum_doc/views/doc.xml
+++ b/addons/website_forum_doc/views/doc.xml
@@ -37,14 +37,14 @@
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="o_dropdown_kanban dropdown" groups="base.group_user">
- <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
<span class="fa fa-ellipsis-v"/>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-if="widget.editable"><a type="edit" role="menuitem">Edit Post</a></li>
- <li t-if="widget.deletable"><a type="delete" role="menuitem">Delete</a></li>
- <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" type="edit" class="dropdown-item" t-if="widget.editable">Edit Post</a>
+ <a role="menuitem" type="delete" class="dropdown-item" t-if="widget.deletable">Delete</a>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
</div>
<div class="o_kanban_record_top">
<b class="o_kanban_record_title"><field name="name"/></b>
diff --git a/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml b/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml
index 6480e2b5a16..fda2c310a32 100644
--- a/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml
+++ b/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml
@@ -34,25 +34,25 @@
<div data-js='s_hr_rating_option_type' data-selector=".s_hr_rating" data-drop-in="[class^='col-']">
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Rating type</a>
- <ul class="dropdown-menu" role="menu">
- <li data-select_class="s_hr_rating_stars"><a role="menuitem" href="#"><i class="fa fa-star"/> Stars</a></li>
- <li data-select_class="s_hr_rating_bolts"><a role="menuitem" href="#"><i class="fa fa-bolt"/> Bolts</a></li>
- <li data-select_class="s_hr_rating_hearts"><a role="menuitem" href="#"><i class="fa fa-heart"/> Hearts</a></li>
- <li data-select_class="s_hr_rating_bar"><a role="menuitem" href="#"><i class="fa fa-tasks"/> Bar</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" data-select_class="s_hr_rating_stars" role="menuitem"><i class="fa fa-star"/> Stars</a>
+ <a href="#" class="dropdown-item" data-select_class="s_hr_rating_bolts" role="menuitem"><i class="fa fa-bolt"/> Bolts</a>
+ <a href="#" class="dropdown-item" data-select_class="s_hr_rating_hearts" role="menuitem"><i class="fa fa-heart"/> Hearts</a>
+ <a href="#" class="dropdown-item" data-select_class="s_hr_rating_bar" role="menuitem"><i class="fa fa-tasks"/> Bar</a>
+ </div>
</li>
</div>
<div data-js='s_hr_rating_option_value' data-selector=".s_hr_rating">
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Rating value</a>
- <ul class="dropdown-menu" role="menu">
- <li data-select_class=""><a role="menuitem" href="#">0</a></li>
- <li data-select_class="s_hr_rating_1"><a role="menuitem" href="#">1/5</a></li>
- <li data-select_class="s_hr_rating_2"><a role="menuitem" href="#">2/5</a></li>
- <li data-select_class="s_hr_rating_3"><a role="menuitem" href="#">3/5</a></li>
- <li data-select_class="s_hr_rating_4"><a role="menuitem" href="#">4/5</a></li>
- <li data-select_class="s_hr_rating_5"><a role="menuitem" href="#">5/5</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu">
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="">0</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_1">1/5</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_2">2/5</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_3">3/5</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_4">4/5</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_5">5/5</a>
+ </div>
</li>
</div>
</xpath>
diff --git a/addons/website_links/views/website_links_template.xml b/addons/website_links/views/website_links_template.xml
index 2e1525a3280..3c7b329db56 100644
--- a/addons/website_links/views/website_links_template.xml
+++ b/addons/website_links/views/website_links_template.xml
@@ -11,12 +11,10 @@
</template>
<template id="share_page_menu" inherit_id="website.user_navbar">
- <xpath expr="//li/a[@data-action='promote-current-page']/.." position="after">
- <li>
- <a href="/r" id="o_website_links_share_page">
- <span title="Track this page to count clicks">Track this Page</span>
- </a>
- </li>
+ <xpath expr="//a[@data-action='promote-current-page']" position="after">
+ <a href="/r" id="o_website_links_share_page" class="dropdown-item">
+ <span title="Track this page to count clicks">Track this Page</span>
+ </a>
</xpath>
</template>
diff --git a/addons/website_sale/static/src/js/website_sale_tour_shop.js b/addons/website_sale/static/src/js/website_sale_tour_shop.js
index 72beb5999d8..d166367d23d 100644
--- a/addons/website_sale/static/src/js/website_sale_tour_shop.js
+++ b/addons/website_sale/static/src/js/website_sale_tour_shop.js
@@ -63,7 +63,7 @@ odoo.define("website_sale.tour_shop", function (require) {
content: _t("Click on this button so your customers can see it."),
position: "bottom",
}, {
- trigger: ".o_main_navbar .o_menu_toggle, #oe_applications .dropdown.full",
+ trigger: ".o_main_navbar .o_menu_toggle, #oe_applications .dropdown-toggle",
content: _t("Let's now take a look at your administration dashboard to get your eCommerce website ready in no time."),
position: "bottom",
}, {
diff --git a/addons/website_sale/static/src/js/website_sale_tracking.js b/addons/website_sale/static/src/js/website_sale_tracking.js
index 52d65a468fc..fb7a095cce6 100644
--- a/addons/website_sale/static/src/js/website_sale_tracking.js
+++ b/addons/website_sale/static/src/js/website_sale_tracking.js
@@ -26,7 +26,7 @@ $(document).ready(function () {
});
$(".oe_website_sale form[action='/shop/confirm_order'] a.a-submit").on('click', function(o) {
- if ($("#top_menu > li > a[href='/web/login']").length){
+ if ($("#top_menu [href='/web/login']").length){
vpv("/stats/ecom/customer_signup");
}
vpv("/stats/ecom/order_checkout");
diff --git a/addons/website_sale/views/snippets.xml b/addons/website_sale/views/snippets.xml
index f19ba2f051a..1fb5f776501 100644
--- a/addons/website_sale/views/snippets.xml
+++ b/addons/website_sale/views/snippets.xml
@@ -9,30 +9,30 @@
<li class='dropdown-submenu'>
<a tabindex="-1" href="#">Size</a>
- <ul class="dropdown-menu" role="menu" name="size">
- <li><a role="menuitem" href="#">
+ <div class="dropdown-menu" role="menu" name="size">
+ <a href="#" role="menuitem" class="dropdown-item">
<table>
<tr><td class="selected"></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</table>
- </a></li>
- </ul>
+ </a>
+ </div>
</li>
<li class='dropdown-submenu' role="menuitem" aria-haspopup="true">
<a tabindex="-1" href="#">Styles</a>
- <ul class="dropdown-menu" role="menu" name="style">
- </ul>
+ <div class="dropdown-menu" role="menu" name="style">
+ </div>
</li>
<li class='dropdown-submenu' role="menuitem" aria-haspopup="true">
<a tabindex="-1" href="#">Promote</a>
- <ul class="dropdown-menu" role="menu" data-no-preview="true">
- <li data-go_to="top"><a role="menuitem">Push to top</a></li>
- <li data-go_to="up"><a role="menuitem">Push up</a></li>
- <li data-go_to="down"><a role="menuitem">Push down</a></li>
- <li data-go_to="bottom"><a role="menuitem">Push to bottom</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu" data-no-preview="true">
+ <a href="#" class="dropdown-item" role="menuitem" data-go_to="top">Push to top</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-go_to="up">Push up</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-go_to="down">Push down</a>
+ <a href="#" class="dropdown-item" role="menuitem" data-go_to="bottom">Push to bottom</a>
+ </div>
</li>
</div>
</xpath>
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index d3e703af08d..d8c3b3442ab 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -159,15 +159,14 @@
<t t-set="curr_pl" t-value="website.get_current_pricelist()" />
<a role="button" href="#" class="dropdown-toggle btn btn-secondary" data-toggle="dropdown">
<t t-esc="curr_pl and curr_pl.name or ' - '" />
- <span class="caret"></span>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-foreach="website_sale_pricelists" t-as="pl">
- <a role="menuitem" t-att-href="'/shop/change_pricelist/%s' % pl.id">
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach="website_sale_pricelists" t-as="pl">
+ <a role="menuitem" t-att-href="'/shop/change_pricelist/%s' % pl.id" class="dropdown-item">
<span class="switcher_pricelist" t-att-data-pl_id="pl.id" t-esc="pl.name" />
</a>
- </li>
- </ul>
+ </t>
+ </div>
</div>
</template>
@@ -253,16 +252,15 @@
</t>
<t t-else='1'>
<span>Sort by</span>
- <span class="caret"></span>
</t>
</a>
- <ul class="dropdown-menu" role="menu">
- <li t-foreach="website_sale_sortable" t-as="sortby">
- <a role="menuitem" t-att-href="keep('/shop', order=sortby[1])">
+ <div class="dropdown-menu" role="menu">
+ <t t-foreach="website_sale_sortable" t-as="sortby">
+ <a role="menuitem" t-att-href="keep('/shop', order=sortby[1])" class="dropdown-item">
<span t-raw="sortby[0]"/>
</a>
- </li>
- </ul>
+ </t>
+ </div>
</div>
</xpath>
</template>
diff --git a/addons/website_sale_digital/views/website_sale_digital.xml b/addons/website_sale_digital/views/website_sale_digital.xml
index 92415355916..cf6e541cd7f 100644
--- a/addons/website_sale_digital/views/website_sale_digital.xml
+++ b/addons/website_sale_digital/views/website_sale_digital.xml
@@ -6,13 +6,13 @@
<t t-if="attachments">
<span class="dropdown">
<button class="btn btn-xs btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
- Downloads <span class="caret"></span>
+ Downloads
</button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
+ <div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<t t-foreach="attachments" t-as="a">
- <li><a role="menuitem" tabindex="-1" t-att-href="'/my/download?attachment_id=%i' % a['id']"><t t-esc="a['name']"/></a></li>
+ <a role="menuitem" tabindex="-1" t-att-href="'/my/download?attachment_id=%i' % a['id']" class="dropdown-item"><t t-esc="a['name']"/></a>
</t>
- </ul>
+ </div>
</span>
</t>
</xpath>
diff --git a/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml b/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml
index 73fa0bc3019..e9e9bc88e99 100644
--- a/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml
+++ b/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml
@@ -20,13 +20,13 @@
<t t-name="website_sale.LinkTrackersDropDown">
<div class="dropdown">
- <button class="btn btn-secondary dropdown-toggle utm_dropdown ml4" id="utm_dropdown" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><span class="utm_button_name">Campaigns</span><span class="caret ml4"/>
+ <button class="btn btn-secondary dropdown-toggle utm_dropdown ml4" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><span class="utm_button_name">Campaigns</span>
</button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="utm_dropdown">
- <li><a role="menuitem" class="js_utm_selector" name="campaign_id">Campaigns</a></li>
- <li><a role="menuitem" class="js_utm_selector" name="medium_id">Medium</a></li>
- <li><a role="menuitem" class="js_utm_selector" name="source_id">Sources</a></li>
- </ul>
+ <div class="dropdown-menu" role="menu" aria-labelledby="utm_dropdown">
+ <a name="campaign_id" class="dropdown-item js_utm_selector" role="menuitem">Campaigns</a>
+ <a name="medium_id" class="dropdown-item js_utm_selector" role="menuitem">Medium</a>
+ <a name="source_id" class="dropdown-item js_utm_selector" role="menuitem">Sources</a>
+ </div>
</div>
</t>
</templates>
diff --git a/addons/website_theme_install/static/src/scss/website_theme_install.scss b/addons/website_theme_install/static/src/scss/website_theme_install.scss
index ea84164b6e5..721b6f33528 100644
--- a/addons/website_theme_install/static/src/scss/website_theme_install.scss
+++ b/addons/website_theme_install/static/src/scss/website_theme_install.scss
@@ -125,7 +125,7 @@
color: $text-color;
}
- &:hover, &.open {
+ &:hover, &.show {
.o_kanban_config {
display: none;
}
diff --git a/doc/howtos/themes.rst b/doc/howtos/themes.rst
index a4ca988306f..0ce91112e43 100644
--- a/doc/howtos/themes.rst
+++ b/doc/howtos/themes.rst
@@ -763,11 +763,11 @@ We start by adding a new file in our views folder - name it **options.xml** and
<div data-selector=".snippet_testimonial"> <!-- Options group -->
<li class="dropdown-submenu">
<a href="#">Your Option</a>
- <ul class="dropdown-menu"> <!-- Options list -->
- <li data-select-class="opt_shadow"><a>Shadow Images</a></li>
- <li data-select-class="opt_grey_bg"><a>Grey Bg</a></li>
- <li data-select-class=""><a>None</a></li>
- </ul>
+ <div class="dropdown-menu"> <!-- Options list -->
+ <a href="#" class="dropdown-item" data-select-class="opt_shadow">Shadow Images</a>
+ <a href="#" class="dropdown-item" data-select-class="opt_grey_bg">Grey Bg</a>
+ <a href="#" class="dropdown-item" data-select-class="">None</a>
+ </div>
</li>
</div>
</xpath>
diff --git a/odoo/addons/base/tests/test_translate.py b/odoo/addons/base/tests/test_translate.py
index 5bd33a4852f..a35ac6056ac 100644
--- a/odoo/addons/base/tests/test_translate.py
+++ b/odoo/addons/base/tests/test_translate.py
@@ -165,7 +165,7 @@ class TranslationToolsTestCase(unittest.TestCase):
</li>
<li class="dropdown" id="menu_more_container" style="display: none;">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">More <b class="caret"/></a>
- <ul class="dropdown-menu" id="menu_more"/>
+ <div class="dropdown-menu" id="menu_more"/>
</li>
</ul>
</t>"""
diff --git a/odoo/addons/test_new_api/static/tests/x2many.js b/odoo/addons/test_new_api/static/tests/x2many.js
index a4cb4be9d88..ecdab8317de 100644
--- a/odoo/addons/test_new_api/static/tests/x2many.js
+++ b/odoo/addons/test_new_api/static/tests/x2many.js
@@ -335,7 +335,7 @@ odoo.define('web.test.x2many', function (require) {
edition: 'community'
}, {
content: "switch to the second form view to test one2many with editable list (toggle menu dropdown)",
- trigger: 'nav .o_menu_sections li a:containsExact(Discussions)',
+ trigger: 'nav .o_menu_sections .dropdown-toggle:containsExact(Discussions)',
extra_trigger: '.tab-pane:eq(0) .o_field_widget tbody .o_data_row:eq(2)',
edition: 'enterprise'
}, {
@@ -344,7 +344,7 @@ odoo.define('web.test.x2many', function (require) {
edition: 'community'
}, {
content: "switch to the second form view to test one2many with editable list (open submenu)",
- trigger: 'nav .o_menu_sections ul li a:contains(Discussions 2)',
+ trigger: 'nav .o_menu_sections .dropdown-item:contains(Discussions 2)',
edition: 'enterprise'
}, {
content: "select previous created record",
@@ -463,7 +463,7 @@ odoo.define('web.test.x2many', function (require) {
edition: 'community'
}, {
content: "switch to the third form view to test onchange changing one2many (toggle menu dropdown)",
- trigger: 'nav .o_menu_sections li a:containsExact(Discussions)',
+ trigger: 'nav .o_menu_sections .dropdown-toggle:containsExact(Discussions)',
extra_trigger: '.tab-pane:eq(0) .o_field_widget tbody .o_data_row:eq(2)',
edition: 'enterprise'
}, {
@@ -472,7 +472,7 @@ odoo.define('web.test.x2many', function (require) {
edition: 'community'
}, {
content: "switch to the thied form view to test onchange changing one2many (open submenu)",
- trigger: 'nav .o_menu_sections ul li a:contains(Discussions 3)',
+ trigger: 'nav .o_menu_sections .dropdown-item:contains(Discussions 3)',
edition: 'enterprise'
}, {
content: "wait web client",