From 915b2c3d89e9b52a4301639bab6386869dd353e6 Mon Sep 17 00:00:00 2001 From: "Dardenne Florent (dafl)" Date: Fri, 2 Sep 2022 12:53:12 +0000 Subject: [PATCH] [IMP] web: daterange field: update `daterangepicker` library The `daterangepicker` was in version 3.0.5, since then the library is now in version 3.1. This version introduce a new feature that allows to automatically (depending on the space left) position the picker above or below the HTML element it's attached. This commit updates the library but also take advantage of this update: Before when clicking on a daterange field, even if there was no space left below, the picker was still displayed below the field. Now, the picker is displayed above the field if there is less space below the field Part-of: odoo/odoo#99495 --- .../lib/daterangepicker/daterangepicker.js | 55 ++++++++++++------- .../views/fields/daterange/daterange_field.js | 1 + 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/addons/web/static/lib/daterangepicker/daterangepicker.js b/addons/web/static/lib/daterangepicker/daterangepicker.js index c6e008a2a95..034692e4284 100644 --- a/addons/web/static/lib/daterangepicker/daterangepicker.js +++ b/addons/web/static/lib/daterangepicker/daterangepicker.js @@ -1,5 +1,5 @@ /** -* @version: 3.0.5 +* @version: 3.1 * @author: Dan Grossman http://www.dangrossman.info/ * @copyright: Copyright (c) 2012-2019 Dan Grossman. All rights reserved. * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php @@ -8,10 +8,10 @@ // Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js (function (root, factory) { if (typeof define === 'function' && define.amd) { - // AMD. Make globally available as well + // AMD. Make globaly available as well define(['moment', 'jquery'], function (moment, jquery) { if (!jquery.fn) jquery.fn = {}; // webpack server rendering - if (typeof moment !== 'function' && moment.default) moment = moment.default + if (typeof moment !== 'function' && moment.hasOwnProperty('default')) moment = moment['default'] return factory(moment, jquery); }); } else if (typeof module === 'object' && module.exports) { @@ -28,7 +28,7 @@ // Browser globals root.daterangepicker = factory(root.moment, root.jQuery); } -}(this, function(moment, $) { +}(typeof window !== 'undefined' ? window : this, function(moment, $) { var DateRangePicker = function(element, options, cb) { //default settings for options @@ -57,7 +57,7 @@ this.ranges = {}; this.opens = 'right'; - if (this.element.hasClass('float-end')) + if (this.element.hasClass('pull-right')) this.opens = 'left'; this.drops = 'down'; @@ -386,7 +386,7 @@ this.container.find('.drp-calendar.left').addClass('single'); this.container.find('.drp-calendar.left').show(); this.container.find('.drp-calendar.right').hide(); - if (!this.timePicker) { + if (!this.timePicker && this.autoApply) { this.container.addClass('auto-apply'); } } @@ -417,20 +417,20 @@ .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)) .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this)) .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this)) - .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)) + .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)); this.container.find('.ranges') - .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)) + .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)); this.container.find('.drp-buttons') .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)) - .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)) + .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)); if (this.element.is('input') || this.element.is('button')) { this.element.on({ 'click.daterangepicker': $.proxy(this.show, this), // odoo cutomization, to align behavior of the daterange widget with the date picker one - // 'focus.daterangepicker': $.proxy(this.show, this), + // 'focus.daterangepicker': $.proxy(this.show, this), 'keyup.daterangepicker': $.proxy(this.elementChanged, this), 'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility }); @@ -527,9 +527,9 @@ this.renderTimePicker('left'); this.renderTimePicker('right'); if (!this.endDate) { - this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled'); + this.container.find('.right .calendar-time select').prop('disabled', true).addClass('disabled'); } else { - this.container.find('.right .calendar-time select').removeAttr('disabled').removeClass('disabled'); + this.container.find('.right .calendar-time select').prop('disabled', false).removeClass('disabled'); } } if (this.endDate) @@ -1015,16 +1015,18 @@ updateFormInputs: function() { if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) { - this.container.find('button.applyBtn').removeAttr('disabled'); + this.container.find('button.applyBtn').prop('disabled', false); } else { - this.container.find('button.applyBtn').attr('disabled', 'disabled'); + this.container.find('button.applyBtn').prop('disabled', true); } }, move: function() { var parentOffset = { top: 0, left: 0 }, - containerTop; + containerTop, + drops = this.drops; + var parentRightEdge = $(window).width(); if (!this.parentEl.is('body')) { parentOffset = { @@ -1033,11 +1035,22 @@ }; parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left; } - - if (this.drops == 'up') - containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; - else + + switch (drops) { + case 'auto': containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; + if (containerTop + this.container.outerHeight() >= this.parentEl[0].scrollHeight) { + containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; + drops = 'up'; + } + break; + case 'up': + containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; + break; + default: + containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; + break; + } // Force the container to it's actual width this.container.css({ @@ -1047,7 +1060,7 @@ }); var containerWidth = this.container.outerWidth(); - this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('drop-up'); + this.container.toggleClass('drop-up', drops == 'up'); if (this.opens == 'left') { var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth(); @@ -1342,7 +1355,7 @@ if (this.singleDatePicker) { this.setEndDate(this.startDate); - if (!this.timePicker) + if (!this.timePicker && this.autoApply) this.clickApply(); } diff --git a/addons/web/static/src/views/fields/daterange/daterange_field.js b/addons/web/static/src/views/fields/daterange/daterange_field.js index 7d1cd1e95f3..08d1ee4d9e6 100644 --- a/addons/web/static/src/views/fields/daterange/daterange_field.js +++ b/addons/web/static/src/views/fields/daterange/daterange_field.js @@ -39,6 +39,7 @@ export class DateRangeField extends Component { }, startDate: start ? window.moment(start) : window.moment(), endDate: end ? window.moment(end) : window.moment(), + drops: "auto", }); this.pickerContainer = window.$(el).data("daterangepicker").container[0];