From eed21fa552f33483dc110f730507283f2a4a03e2 Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Thu, 21 Mar 2024 15:09:47 +0000
Subject: [PATCH] calendar date form: move end date or time when moving the
 begin date or time, fixes #3862

Closes #3862

Merge request studip/studip!2726
---
 .../assets/javascripts/bootstrap/calendar.js  | 31 ++++++++++++++++++
 resources/assets/javascripts/entry-base.js    |  1 +
 resources/assets/javascripts/lib/calendar.js  | 32 +++++++++++++++++++
 3 files changed, 64 insertions(+)
 create mode 100644 resources/assets/javascripts/bootstrap/calendar.js

diff --git a/resources/assets/javascripts/bootstrap/calendar.js b/resources/assets/javascripts/bootstrap/calendar.js
new file mode 100644
index 00000000000..82484268a4e
--- /dev/null
+++ b/resources/assets/javascripts/bootstrap/calendar.js
@@ -0,0 +1,31 @@
+STUDIP.ready(function() {
+    jQuery(document).on('change', 'form.new-calendar-date-form input[name=begin]', function(event) {
+        let begin_value = jQuery(event.target).val();
+        let begin = STUDIP.Calendar.parseDateFromString(begin_value);
+        if (!begin) {
+            return;
+        }
+        let end_value = jQuery('form.new-calendar-date-form input[name=end]').val();
+        let end = STUDIP.Calendar.parseDateFromString(end_value);
+        if (end) {
+            //Check if the date and time in end_value is past the date in begin_value.
+            //If so, set the date or the time or both to a value after begin_value.
+            if (end.getTime() <= begin.getTime()) {
+                //Get the distance of the time (hours and minutes only) between begin and end:
+                let diff = Math.abs(end.getHours() - begin.getHours()) * 3600
+                    + Math.abs(end.getMinutes() - begin.getMinutes()) * 60;
+                end = begin;
+                end.setTime(end.getTime() + diff * 1000);
+            }
+        } else {
+            //Clone begin and add one hour to end:
+            end = begin;
+            end.setTime(end.getTime() + 3600000);
+        }
+
+        //Display the new end:
+        let end_string = STUDIP.DateTime.pad(end.getDate()) + '.' + STUDIP.DateTime.pad(end.getMonth() + 1) + '.' + end.getFullYear()
+            + ' ' + STUDIP.DateTime.pad(end.getHours()) + ':' + STUDIP.DateTime.pad(end.getMinutes());
+        jQuery('form.new-calendar-date-form input[name=end]').val(end_string);
+    });
+});
diff --git a/resources/assets/javascripts/entry-base.js b/resources/assets/javascripts/entry-base.js
index 845f19e9a20..73b1aaa52e8 100644
--- a/resources/assets/javascripts/entry-base.js
+++ b/resources/assets/javascripts/entry-base.js
@@ -38,6 +38,7 @@ import "./bootstrap/i18n_input.js"
 import "./bootstrap/forms.js"
 import "./bootstrap/drag_and_drop_upload.js"
 import "./bootstrap/admin_sem_classes.js"
+import "./bootstrap/calendar.js"
 import "./bootstrap/cronjobs.js"
 import "./bootstrap/contentbox.js"
 import "./bootstrap/dates.js"
diff --git a/resources/assets/javascripts/lib/calendar.js b/resources/assets/javascripts/lib/calendar.js
index 2d995b5f5f8..e36988b2b60 100644
--- a/resources/assets/javascripts/lib/calendar.js
+++ b/resources/assets/javascripts/lib/calendar.js
@@ -124,6 +124,38 @@ const Calendar = {
         }
 
         return true;
+    },
+
+    parseDateFromString: function(date_string) {
+        if (!date_string) {
+            //Nothing that can be done.
+            return null;
+        }
+        let string_parts = date_string.split(' ');
+        if (string_parts.length !== 2) {
+            //Invalid format.
+            return null;
+        }
+        let date_parts = string_parts[0].split('.');
+        if (date_parts.length !== 3) {
+            //Invalid format.
+            return null;
+        }
+        let time_parts = string_parts[1].split(':');
+        if (time_parts.length !== 2) {
+            //Invalid format.
+            return null;
+        }
+        let date = new Date(
+            parseInt(date_parts[2]),
+            parseInt(date_parts[1]) - 1,
+            parseInt(date_parts[0])
+        );
+        date.setHours(parseInt(time_parts[0]));
+        date.setMinutes(parseInt(time_parts[1]));
+        date.setSeconds(0);
+
+        return date;
     }
 };
 
-- 
GitLab