Fix: Hijri datepicker calendar not hiding on outside click (#4694)

* Fix hijri datepicker calendar not hiding on outside click

* Improve list renderer outside click handling for hijri calendar

* Update CSS z-index for better hijri calendar popup handling
This commit is contained in:
Mohamed Eltayar 2025-09-17 11:13:32 +03:00 committed by GitHub
parent 052a39d228
commit 6154c2cc34
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 32 deletions

View File

@ -92,12 +92,7 @@ odoo.define('web_hijri_datepicker.ListRenderer', function (require) {
}
var $td = $('<td>', { class: tdClassName, tabindex: -1 });
// We register modifiers on the <td> element so that it gets the correct
// modifiers classes (for styling)
var modifiers = this._registerModifiers(node, record, $td, _.pick(options, 'mode'));
// If the invisible modifiers is true, the <td> element is left empty.
// Indeed, if the modifiers was to change the whole cell would be
// rerendered anyway.
if (modifiers.invisible && !(options && options.renderInvisible)) {
return $td;
}
@ -124,7 +119,6 @@ odoo.define('web_hijri_datepicker.ListRenderer', function (require) {
};
var formattedValue = formatter(value, field, formatOptions);
// فقط إضافة التاريخ الهجري إذا كان الـ widget هو hijri_date أو hijri_datetime
if (_.contains(['date', 'datetime'], field.type) &&
(node.attrs.widget === 'hijri_date' || node.attrs.widget === 'hijri_datetime')) {
if (formattedValue) {
@ -157,7 +151,12 @@ odoo.define('web_hijri_datepicker.ListRenderer', function (require) {
},
_onWindowClicked: function (event) {
if ($(event.target).hasClass('calendars-highlight')) {
var $target = $(event.target);
if ($target.hasClass('calendars-highlight') ||
$target.closest('.calendars-popup').length ||
$target.closest('.calendars').length ||
$target.hasClass('o_hijri') ||
$target.closest('.o_hijri').length) {
return;
}
this._super.apply(this, arguments);

View File

@ -31,7 +31,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
});
}
// إنشاء HijriDateWidget مخصص للتواريخ الهجرية
var HijriDateWidget = datepicker.DateWidget.extend({
template: 'web_hijri.datepicker',
@ -40,11 +39,9 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
this.$input = this.$('input.o_datepicker_input');
this.$input_hijri = this.$('input.o_hijri');
// تحديد اللغة
var locale = this.options.locale || 'en';
var userLang = (odoo.session_info && odoo.session_info.user_context && odoo.session_info.user_context.lang) || 'en_US';
// تحديد placeholders حسب اللغة
var gregorianPlaceholder, hijriPlaceholder;
if (locale === 'ar' || userLang.startsWith('ar')) {
gregorianPlaceholder = 'التاريخ الميلادي';
@ -54,35 +51,33 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
hijriPlaceholder = 'Hijri Date';
}
// حفظ placeholders للاستخدام لاحقاً
this.gregorianPlaceholder = gregorianPlaceholder;
this.hijriPlaceholder = hijriPlaceholder;
// تطبيق placeholder للتاريخ الهجري
this.$input_hijri.attr('placeholder', hijriPlaceholder);
this.$input_hijri.click(function (e) {
e.preventDefault();
self.$input_hijri.calendarsPicker('show');
});
this.$input_hijri.calendarsPicker({
calendar: $.calendars.instance('islamic', this.options.locale),
dateFormat: 'M d, yyyy',
closeOnDateSelect: false,
onSelect: this._convertDateToHijri.bind(this),
onClose: function() {
self._removeOutsideClickHandler();
}
});
// تهيئة datetimepicker
this.__libInput++;
this.$el.datetimepicker(this.options);
this.__libInput--;
// تطبيق placeholder للتاريخ الميلادي بعد تهيئة datetimepicker
setTimeout(function() {
self.$input.attr('placeholder', gregorianPlaceholder);
}, 0);
// إعادة تطبيق placeholder عند فقدان التركيز
this.$input.on('blur', function() {
if (!$(this).val()) {
$(this).attr('placeholder', gregorianPlaceholder);
@ -90,11 +85,44 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
});
this._setReadonly(false);
this._setupOutsideClickHandler();
},
_setupOutsideClickHandler: function() {
var self = this;
this._outsideClickHandler = function(e) {
var $target = $(e.target);
if (!$target.closest('.calendars-popup').length &&
!$target.closest('.o_hijri').length &&
!$target.hasClass('o_hijri') &&
!$target.closest('.calendars').length) {
self._hideHijriCalendar();
}
};
this._keydownHandler = function(e) {
if (e.keyCode === 27) {
self._hideHijriCalendar();
}
};
$(document).on('click.hijri_calendar', this._outsideClickHandler);
$(document).on('keydown.hijri_calendar', this._keydownHandler);
},
_removeOutsideClickHandler: function() {
$(document).off('click.hijri_calendar');
$(document).off('keydown.hijri_calendar');
},
_hideHijriCalendar: function() {
if (this.$input_hijri && this.$input_hijri.calendarsPicker) {
this.$input_hijri.calendarsPicker('hide');
}
},
changeDatetime: function () {
this._super.apply(this, arguments);
// إعادة تطبيق placeholder بعد تغيير التاريخ
if (this.gregorianPlaceholder && !this.$input.val()) {
this.$input.attr('placeholder', this.gregorianPlaceholder);
}
@ -128,16 +156,12 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
if (!date || date.length === 0) {
return false;
}
$(document).on('click', '.calendars a', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
return false;
});
var jd = $.calendars.instance('islamic').toJD(parseInt(date[0].year()), parseInt(date[0].month()), parseInt(date[0].day()));
var formatted_date = $.calendars.instance('gregorian').fromJD(jd);
var date_value = moment(time.str_to_date(formatted_date)).add(1, 'days');
this.setValue(this._parseClient(date_value));
this.trigger("datetime_changed");
this._hideHijriCalendar();
},
_parseDate: function (v) {
@ -150,7 +174,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
var hijri_value = parsed_date ? this._convertGregorianToHijri(parsed_date) : null;
this.$input_hijri.val(hijri_value);
// إعادة تطبيق placeholders عند مسح القيم
if (!value && this.gregorianPlaceholder) {
this.$input.attr('placeholder', this.gregorianPlaceholder);
}
@ -160,11 +183,13 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
},
destroy: function () {
this._removeOutsideClickHandler();
if (this.$el) {
this.__libInput++;
this.$el.datetimepicker('destroy');
this.__libInput--;
}
this._super.apply(this, arguments);
},
_onInputClicked: function (e) {
@ -178,7 +203,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
},
});
// إنشاء FieldHijriDate للتواريخ مع التقويم الهجري
var FieldHijriDate = FieldDate.extend({
_makeDatePicker: function () {
return new HijriDateWidget(this, this.datepickerOptions);
@ -197,7 +221,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
var parsed_date = this.value ? this.datewidget._parseDate(this.value) : '';
var hijri_value = parsed_date ? this.datewidget._convertGregorianToHijri(parsed_date) : '';
// إضافة labels توضيحية في وضع القراءة فقط
var userLang = (odoo.session_info && odoo.session_info.user_context && odoo.session_info.user_context.lang) || 'en_US';
var gregorianLabel = userLang.startsWith('ar') ? 'التاريخ الميلادي: ' : 'Gregorian Date: ';
var hijriLabel = userLang.startsWith('ar') ? 'التاريخ الهجري: ' : 'Hijri Date: ';
@ -216,7 +239,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
},
});
// إنشاء FieldHijriDateTime للتواريخ والأوقات مع التقويم الهجري
var FieldHijriDateTime = FieldDateTime.extend({
_makeDatePicker: function () {
return new HijriDateWidget(this, this.datepickerOptions);
@ -235,7 +257,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
var parsed_date = this.value ? this.datewidget._parseDate(this.value) : '';
var hijri_value = parsed_date ? this.datewidget._convertGregorianToHijri(parsed_date) : '';
// إضافة labels توضيحية في وضع القراءة فقط
var userLang = (odoo.session_info && odoo.session_info.user_context && odoo.session_info.user_context.lang) || 'en_US';
var gregorianLabel = userLang.startsWith('ar') ? 'التاريخ الميلادي: ' : 'Gregorian Date: ';
var hijriLabel = userLang.startsWith('ar') ? 'التاريخ الهجري: ' : 'Hijri Date: ';
@ -254,7 +275,6 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) {
},
});
// تسجيل الحقول الجديدة في registry
registry.add('hijri_date', FieldHijriDate);
registry.add('hijri_datetime', FieldHijriDateTime);

View File

@ -1,5 +1,5 @@
.calendars-popup {
z-index: 99999 !important;
z-index: 9999 !important;
position: absolute !important;
& > .calendars {
min-width: 225px;
@ -27,7 +27,6 @@
}
}
}
}
}
}