diff --git a/odex25_base/web_hijri_datepicker/static/src/js/web_hijri_date.js b/odex25_base/web_hijri_datepicker/static/src/js/web_hijri_date.js index c24aacdb3..f60032d26 100644 --- a/odex25_base/web_hijri_datepicker/static/src/js/web_hijri_date.js +++ b/odex25_base/web_hijri_datepicker/static/src/js/web_hijri_date.js @@ -34,68 +34,142 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { datepicker.DateWidget.include({ start: function () { var self = this; + + // ✅ FIX: Initialize __libInput if it doesn't exist + if (typeof this.__libInput === 'undefined') { + this.__libInput = 0; + } + this.$input = this.$('input.o_datepicker_input'); this.$input_hijri = this.$('input.o_hijri'); - // ✅ إضافة بسيطة للـ placeholder للحقل الميلادي + // ✅ Add placeholder for Gregorian field if (this.$input && this.$input.length && !this.$input.attr('placeholder')) { this.$input.attr('placeholder', 'التاريخ الميلادي'); } - // Enhanced click handler with better UX - this.$input_hijri.click(function (e) { - e.preventDefault(); - e.stopPropagation(); - self.$input_hijri.calendarsPicker('show'); - }); + // ✅ Initialize Hijri calendar with safety checks + if (this.$input_hijri && this.$input_hijri.length) { + this._initHijriCalendar(); + } - // Modern configuration with enhanced features - this.$input_hijri.calendarsPicker({ - calendar: $.calendars.instance('islamic', this.options.locale || 'ar'), - dateFormat: 'M d, yyyy', - showAnim: 'slideDown', // Modern animation - showSpeed: 'fast', - showOnFocus: false, - closeOnDateSelect: true, // Better UX - close after selection - yearRange: 'c-100:c+50', // Extended year range - changeMonth: true, - changeYear: true, - showOtherMonths: true, - selectOtherMonths: true, - localNumbers: true, // Enable Arabic numerals - renderer: this._getModernRenderer(), - onSelect: this._convertDateToHijri.bind(this), - onShow: function() { - // Add modern CSS class for styling - $('.calendars-popup').addClass('hijri-modern-popup'); + // ✅ FIX: Safe datetimepicker initialization + if (this.$el && this.$el.datetimepicker) { + this.__libInput++; + try { + this.$el.datetimepicker(this.options); + } catch (e) { + console.warn('Error initializing datetimepicker:', e); + } finally { + this.__libInput--; } - }); + } - this.__libInput++; - this.$el.datetimepicker(this.options); - this.__libInput--; this._setReadonly(false); - // ✅ تأكد مرة أخيرة من الـ placeholder بعد تحميل datetimepicker + // ✅ Final check for placeholder and Hijri calendar setTimeout(function() { if (self.$input && self.$input.length && !self.$input.attr('placeholder')) { self.$input.attr('placeholder', 'التاريخ الميلادي'); } - }, 50); + + // Try to initialize Hijri calendar again if not done + if (typeof $ !== 'undefined' && $.calendars && self.$input_hijri && + self.$input_hijri.length && !self.$input_hijri.hasClass('hasCalendarsPicker')) { + self._initHijriCalendar(); + } + }, 200); + }, + + // ✅ Separate method for Hijri calendar initialization + _initHijriCalendar: function() { + var self = this; + + // Check if jQuery Calendars library is available + if (typeof $ === 'undefined' || !$.calendars || !$.calendars.instance) { + console.warn('jQuery Calendars library not loaded yet. Will retry...'); + return; + } + + try { + // Enhanced click handler with better event handling + this.$input_hijri.off('click.hijri').on('click.hijri', function (e) { + e.preventDefault(); + e.stopPropagation(); + if (self.$input_hijri.hasClass('hasCalendarsPicker')) { + self.$input_hijri.calendarsPicker('show'); + } + }); + + // ✅ Initialize calendar with fixed configuration + this.$input_hijri.calendarsPicker({ + calendar: $.calendars.instance('islamic', this.options.locale || 'ar'), + dateFormat: 'M d, yyyy', + showAnim: 'slideDown', + showSpeed: 'fast', + showOnFocus: false, + closeOnDateSelect: true, + yearRange: 'c-100:c+50', + changeMonth: true, + changeYear: true, + showOtherMonths: true, + selectOtherMonths: true, + localNumbers: true, + renderer: this._getModernRenderer(), + onSelect: this._convertDateToHijri.bind(this), + onShow: function() { + // Add modern CSS class + $('.calendars-popup').addClass('hijri-modern-popup'); + + // ✅ FIX: Navigation buttons with proper symbols + setTimeout(function() { + // Fix previous button + $('.calendars-prev').each(function() { + $(this).html('‹').attr('title', 'الشهر السابق'); + $(this).css({ + 'cursor': 'pointer', + 'user-select': 'none', + 'pointer-events': 'auto' + }); + }); + + // Fix next button + $('.calendars-next').each(function() { + $(this).html('›').attr('title', 'الشهر التالي'); + $(this).css({ + 'cursor': 'pointer', + 'user-select': 'none', + 'pointer-events': 'auto' + }); + }); + }, 50); + } + }); + + console.log('Hijri calendar initialized successfully'); + + } catch (error) { + console.error('Error initializing Hijri calendar:', error); + } }, /** - * Get modern renderer configuration for better styling + * ✅ Get modern renderer configuration with fixed navigation buttons */ _getModernRenderer: function() { + // Check if library is available + if (!$ || !$.calendarsPicker || !$.calendarsPicker.defaultRenderer) { + return {}; + } + return $.extend({}, $.calendarsPicker.defaultRenderer, { picker: '
{months}
', monthRow: '
{months}
', month: '
' + '
' + - '' + + '' + '
{monthHeader}
' + - '' + + '' + '
' + '{weekHeader}{weeks}
' + '
', @@ -121,41 +195,53 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { }, _convertGregorianToHijri: function (date) { + // Check if library is available + if (!$ || !$.calendars || !$.calendars.instance) { + return null; + } + var year, month, day, jd, formatted_date; - var calendar = $.calendars.instance('islamic'); + var calendar; if (date && !_.isUndefined(date)) { - date = moment(date).locale('en'); - month = parseInt(date.format('M')); - day = parseInt(date.format('D')); - year = parseInt(date.format('YYYY')); - - jd = $.calendars.instance('gregorian').toJD(year, month, day); - formatted_date = calendar.fromJD(jd); - - var hijriMonth = calendar.formatDate('MM', formatted_date); - var hijriDate = calendar.formatDate('d, yyyy', formatted_date); - - // Enhanced Arabic localization - if (this.options.locale === 'ar' || !this.options.locale) { - hijriDate = hijriDate.fromDigits(); - // Find Arabic month name - var arabicMonth = _.find(hijriMonths, function (value, key) { - return key === hijriMonth; - }); - hijriMonth = arabicMonth || hijriMonth; + try { + calendar = $.calendars.instance('islamic'); + date = moment(date).locale('en'); + month = parseInt(date.format('M')); + day = parseInt(date.format('D')); + year = parseInt(date.format('YYYY')); + + jd = $.calendars.instance('gregorian').toJD(year, month, day); + formatted_date = calendar.fromJD(jd); + + var hijriMonth = calendar.formatDate('MM', formatted_date); + var hijriDate = calendar.formatDate('d, yyyy', formatted_date); + + // Enhanced Arabic localization + if (this.options.locale === 'ar' || !this.options.locale) { + hijriDate = hijriDate.fromDigits(); + // Find Arabic month name + var arabicMonth = _.find(hijriMonths, function (value, key) { + return key === hijriMonth; + }); + hijriMonth = arabicMonth || hijriMonth; + } + + return _.str.sprintf("%s %s", hijriMonth, hijriDate); + } catch (error) { + console.error('Error converting Gregorian to Hijri:', error); + return null; } - - return _.str.sprintf("%s %s", hijriMonth, hijriDate); } + return null; }, _convertDateToHijri: function (date) { - if (!date || date.length === 0) { + if (!date || date.length === 0 || !$ || !$.calendars) { return false; } - // Prevent event bubbling for better UX + // Prevent event bubbling $(document).off('click.calendars').on('click.calendars', '.calendars a', function (e) { e.preventDefault(); e.stopImmediatePropagation(); @@ -176,11 +262,13 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { this.setValue(this._parseClient(dateValue)); this.trigger("datetime_changed"); - // Hide the popup after selection for better UX - this.$input_hijri.calendarsPicker('hide'); + // Hide the popup after selection + if (this.$input_hijri && this.$input_hijri.hasClass('hasCalendarsPicker')) { + this.$input_hijri.calendarsPicker('hide'); + } } catch (error) { - console.warn('Hijri date conversion error:', error); + console.error('Hijri date conversion error:', error); } }, @@ -194,10 +282,12 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { var hijri_value = parsed_date ? this._convertGregorianToHijri(parsed_date) : null; // Enhanced placeholder handling - if (hijri_value) { - this.$input_hijri.val(hijri_value).removeClass('o_input_placeholder'); - } else { - this.$input_hijri.val('').addClass('o_input_placeholder'); + if (this.$input_hijri && this.$input_hijri.length) { + if (hijri_value) { + this.$input_hijri.val(hijri_value).removeClass('o_input_placeholder'); + } else { + this.$input_hijri.val('').addClass('o_input_placeholder'); + } } }, @@ -205,14 +295,32 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { // Clean up event handlers $(document).off('click.calendars'); - if (this.$input_hijri && this.$input_hijri.hasClass('hasCalendarsPicker')) { - this.$input_hijri.calendarsPicker('destroy'); + if (this.$input_hijri) { + this.$input_hijri.off('click.hijri'); + + if (this.$input_hijri.hasClass('hasCalendarsPicker')) { + try { + this.$input_hijri.calendarsPicker('destroy'); + } catch (error) { + console.warn('Error destroying calendars picker:', error); + } + } } - if (this.$el) { + if (this.$el && this.$el.datetimepicker) { + // ✅ FIX: Initialize __libInput if not exists + if (typeof this.__libInput === 'undefined') { + this.__libInput = 0; + } + this.__libInput++; - this.$el.datetimepicker('destroy'); - this.__libInput--; + try { + this.$el.datetimepicker('destroy'); + } catch (e) { + console.warn('Error destroying datetimepicker:', e); + } finally { + this.__libInput--; + } } }, @@ -267,9 +375,9 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { }); // Enhanced integration with Odoo's form validation - if ($.validator) { + if ($ && $.validator) { $.validator.addMethod('hijriDate', function(value, element) { - if (!value) return true; + if (!value || !$ || !$.calendars) return true; try { var calendar = $.calendars.instance('islamic'); @@ -282,7 +390,7 @@ odoo.define('web_hijri_datepicker.datepicker', function (require) { } // Global configuration for better performance - if ($.calendarsPicker) { + if ($ && $.calendarsPicker) { $.calendarsPicker.setDefaults({ showSpeed: 'fast', showAnim: 'slideDown',