From 23933885ca25f8e4e929c5b8cec30bcf09aeb694 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Thu, 10 Apr 2025 19:25:03 -0300 Subject: [PATCH] fix(datetimepicker): Handle manually entered dates with UNIX epoch This supersedes commit 19578e9fee1d which attempted to fix the issue but was limited to a specific date format (dd.mm.yyyy). The new approach uses the datetimepicker's native parsing capabilities to handle dates in any configured format. When users manually typed dates in fields set with `data-date-unix="true"` without clicking on the calendar widget, the values weren't being converted to UNIX timestamps as expected. This resulted in the date field not appearing to save its value. The improved solution: - Uses the picker's `getDate()` method to parse dates according to the configured format - Properly handles timezone adjustments for datetime fields - Includes better error handling and validation - Works with all locale formats supported by the datetimepicker Fixes #5412 --- .../js/bootstrap-datetimepicker.init.js | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/e107_web/js/bootstrap-datetimepicker/js/bootstrap-datetimepicker.init.js b/e107_web/js/bootstrap-datetimepicker/js/bootstrap-datetimepicker.init.js index 8808954ad..f9058774e 100755 --- a/e107_web/js/bootstrap-datetimepicker/js/bootstrap-datetimepicker.init.js +++ b/e107_web/js/bootstrap-datetimepicker/js/bootstrap-datetimepicker.init.js @@ -14,42 +14,46 @@ var e107 = e107 || {'settings': {}, 'behaviors': {}}; var $item = $(this); // Fix for changeDate() not being fired when value manually altered. - $item.on("change keyup", function () { - var $this = $(this); - var useUnix = $this.attr("data-date-unix"); - var newValue = $this.val(); - - if (useUnix !== "true" || newValue == "") { + $item.on("change keyup", function() { + var $this = $(this); + var useUnix = $this.attr("data-date-unix"); + var newValue = $this.val(); var id = $this.attr("id"); var newTarget = "#" + id.replace("e-datepicker-", ""); - $(newTarget).val(newValue); - } - // If UNIX timestamp is required, manually convert the date string (dd.mm.yyyy) - if (useUnix === "true") { - var parts = newValue.split("."); - if (parts.length === 3) { - var day = parseInt(parts[0], 10); - var month = parseInt(parts[1], 10) - 1; // Month is zero-based in JS - var year = parseInt(parts[2], 10); - - // Validate date parts - if (!isNaN(day) && !isNaN(month) && !isNaN(year)) { - var date = new Date(year, month, day); - var unixTimestamp = Math.floor(date.getTime() / 1000); - var id = $this.attr("id"); - var newTarget = "#" + id.replace("e-datepicker-", ""); - $(newTarget).val(unixTimestamp); // Update hidden UNIX field - } + // For non-UNIX fields or empty values, just copy the value + if (useUnix !== "true" || newValue === "") { + $(newTarget).val(newValue); + return; + } + + // For UNIX timestamp conversion, use the datetimepicker instance + try { + // Get date from the picker (handles format automatically) + var pickerInstance = $this.data('datetimepicker'); + if (!pickerInstance) return; + + var date = pickerInstance.getDate(); + if (!date || isNaN(date.getTime())) return; + + // Convert to UNIX timestamp + var unixTimestamp = Math.floor(date.getTime() / 1000); + + // Apply timezone offset if this is a datetime field + if ($this.hasClass('e-datetime')) { + var offset = parseInt($this.attr("data-date-timezone-offset")); + if (!isNaN(offset)) { + var browserOffset = date.getTimezoneOffset() * 60; + var relativeOffset = browserOffset + offset; + unixTimestamp = unixTimestamp - relativeOffset; + } + } + + $(newTarget).val(unixTimestamp); + } catch (e) { + console.error("Error processing date:", e); } - } else { - // If not using UNIX timestamp, update with raw value - var id = $this.attr("id"); - var newTarget = "#" + id.replace("e-datepicker-", ""); - $(newTarget).val(newValue); // Update hidden field with text input value - } }); - }); $(context).find('input.e-date').once('datetimepicker-init').each(function () {