[FIX] website, *: prevent bottom fixed elements from hiding buttons
*: web, website_livechat, website_sale_comparison Before this commit, bottom fixed elements (e.g. the livechat button) hid the buttons to go to the next step in website sale when these buttons are located at the bottom of the page, on some screen sizes. After this commit, - A bottom fixed element is hidden if this element hides a button at the bottom of the page. - Bottom fixed elements are hidden if a modal is open to prevent it to hide buttons or any important part of the modal. task-2501400 closes odoo/odoo#74515 X-original-commit: a851db9495fe9d8c1951f218a71e4d4a427cf96d Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -59,6 +59,21 @@ var dom = {
|
||||
_notify(content, options.callbacks);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Detects if 2 elements are colliding.
|
||||
*
|
||||
* @param {Element} el1
|
||||
* @param {Element} el2
|
||||
* @returns {boolean}
|
||||
*/
|
||||
areColliding(el1, el2) {
|
||||
const el1Rect = el1.getBoundingClientRect();
|
||||
const el2Rect = el2.getBoundingClientRect();
|
||||
return el1Rect.bottom > el2Rect.top
|
||||
&& el1Rect.top < el2Rect.bottom
|
||||
&& el1Rect.right > el2Rect.left
|
||||
&& el1Rect.left < el2Rect.right;
|
||||
},
|
||||
/**
|
||||
* Autoresize a $textarea node, by recomputing its height when necessary
|
||||
* @param {number} [options.min_height] by default, 50.
|
||||
|
||||
@@ -1028,6 +1028,60 @@ registry.HeaderHamburgerFull = publicWidget.Widget.extend({
|
||||
},
|
||||
});
|
||||
|
||||
registry.BottomFixedElement = publicWidget.Widget.extend({
|
||||
selector: '#wrapwrap',
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
this.$scrollingElement = $().getScrollingElement();
|
||||
this.__hideBottomFixedElements = _.debounce(() => this._hideBottomFixedElements(), 500);
|
||||
this.$scrollingElement.on('scroll.bottom_fixed_element', this.__hideBottomFixedElements);
|
||||
$(window).on('resize.bottom_fixed_element', this.__hideBottomFixedElements);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
destroy() {
|
||||
this._super(...arguments);
|
||||
this.$scrollingElement.off('.bottom_fixed_element');
|
||||
$(window).off('.bottom_fixed_element');
|
||||
$('.o_bottom_fixed_element').removeClass('o_bottom_fixed_element_hidden');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Hides the elements that are fixed at the bottom of the screen if the
|
||||
* scroll reaches the bottom of the page and if the elements hide a button.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_hideBottomFixedElements() {
|
||||
// Note: check in the whole DOM instead of #wrapwrap as unfortunately
|
||||
// some things are still put outside of the #wrapwrap (like the livechat
|
||||
// button which is the main reason of this code).
|
||||
const $bottomFixedElements = $('.o_bottom_fixed_element');
|
||||
if (!$bottomFixedElements.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
$bottomFixedElements.removeClass('o_bottom_fixed_element_hidden');
|
||||
if ((this.$scrollingElement[0].offsetHeight + this.$scrollingElement[0].scrollTop) >= (this.$scrollingElement[0].scrollHeight - 2)) {
|
||||
const buttonEls = [...this.$('.btn:visible')];
|
||||
for (const el of $bottomFixedElements) {
|
||||
if (buttonEls.some(button => dom.areColliding(button, el))) {
|
||||
el.classList.add('o_bottom_fixed_element_hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
Widget: publicWidget.Widget,
|
||||
Animation: Animation,
|
||||
|
||||
@@ -1422,3 +1422,10 @@ ul.o_checklist > li.o_checked::after {
|
||||
left: - ($o-checklist-margin-left - $o-checklist-checkmark-width) - 1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
// Bottom fixed element (e.g. livechat button)
|
||||
.modal-open .o_bottom_fixed_element, .o_bottom_fixed_element_hidden {
|
||||
// Prevent bottom fixed elements from hidding buttons and
|
||||
// hide them if a modal is open.
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ var LivechatButton = require('im_livechat.legacy.im_livechat.im_livechat').Livec
|
||||
|
||||
|
||||
LivechatButton.include({
|
||||
className: `${LivechatButton.prototype.className} o_bottom_fixed_element`,
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -22,6 +23,19 @@ LivechatButton.include({
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start() {
|
||||
// We trigger a resize to launch the event that checks if this element hides
|
||||
// a button when the page is loaded.
|
||||
$(window).trigger('resize');
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
|
||||
@@ -59,6 +59,9 @@ var ProductComparison = publicWidget.Widget.extend(VariantMixin, {
|
||||
return $('#comparelist .o_product_panel_content').html();
|
||||
}
|
||||
});
|
||||
// We trigger a resize to launch the event that checks if this element hides
|
||||
// a button when the page is loaded.
|
||||
$(window).trigger('resize');
|
||||
|
||||
$(document.body).on('click.product_comparaison_widget', '.comparator-popover .o_comparelist_products .o_remove', function (ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<templates id="compare_products" xml:space="preserve">
|
||||
|
||||
<t t-name="product_comparison_template">
|
||||
<div class="o_product_feature_panel d-none css_editable_mode_hidden">
|
||||
<div class="o_product_feature_panel d-none css_editable_mode_hidden o_bottom_fixed_element">
|
||||
<span class="o_product_panel" id="comparelist">
|
||||
<span class="o_product_panel_header">
|
||||
<span class="o_product_icon"><i class="fa fa-exchange" role="img" aria-label="Product" title="Product"></i></span>
|
||||
|
||||
Reference in New Issue
Block a user