From 7ab2d7e2df65dfeeb1afefca0ab616418a10a261 Mon Sep 17 00:00:00 2001
From: enured <enis.nuredini@uzh.ch>
Date: Fri, 16 Dec 2022 14:50:15 +0100
Subject: [PATCH] B15191: WIP: Problem - After removing rows, existing rows
 behind them are not updated, instead they will be inserted new. refs #15191

---
 javascript/src/FieldTemplate.js |  53 +++++++++++++++-
 javascript/src/Main.js          | 105 ++++++++++++++++----------------
 2 files changed, 106 insertions(+), 52 deletions(-)

diff --git a/javascript/src/FieldTemplate.js b/javascript/src/FieldTemplate.js
index 8aa9e3433..db3e5f024 100644
--- a/javascript/src/FieldTemplate.js
+++ b/javascript/src/FieldTemplate.js
@@ -20,6 +20,8 @@ var QfqNS = QfqNS || {};
      */
     n.addFields = function (templateSelector, targetSelector, maxLines) {
         n.appendTemplate(templateSelector, targetSelector, maxLines);
+        // New added fields are maybe qfq-datepicker. These needs to be initialized again after added dynamically.
+        n.initializeDatetimepicker(true);
     };
 
     /**
@@ -54,6 +56,13 @@ var QfqNS = QfqNS || {};
         var deserializedTemplate = n.deserializeTemplateAndRetainPlaceholders($template.text());
         n.expandRetainedPlaceholders(deserializedTemplate, lines);
 
+        // Change ids to their real ones
+        var elements = deserializedTemplate[0].childNodes;
+        elements.forEach(function(element) {
+            n.adjustIds(element, lines);
+        });
+
+
         // Store the button object, so we can easily access it when this `line` is removed by the user
         responsibleButton = n.getResponsibleButtonFromTarget($target);
         if (responsibleButton) {
@@ -69,6 +78,32 @@ var QfqNS = QfqNS || {};
         }
     };
 
+    n.adjustIds = function (item, startId) {
+        if (item.id !== undefined && item.id !== '' && !item.classList.contains("hidden") && (item.tagName === "INPUT" || item.tagName === "DIV")) {
+            var id = item.id;
+            var last2 = id.slice(-2);
+            var endingChars = startId + last2;
+            if (item.tagName === "INPUT") {
+                item.id = id.slice(0, -1) + startId;
+            } else {
+                item.id = id.slice(0, -3) + endingChars;
+            }
+
+        }
+
+        // Get inner children and adjust id
+        if (item.childNodes !== undefined && item.childNodes.length > 0) {
+            n.adjustIds(item.childNodes, startId);
+        }
+
+        // Recursive function to iterate over elements without childNodes, which itself can contain childNodes.
+        if (item.length > 0 && item.childNodes === undefined) {
+            item.forEach(function(element) {
+                n.adjustIds(element, startId);
+            });
+        }
+    };
+
     n.getResponsibleButtonFromTarget = function ($target) {
         var $button;
         var buttonSelector = $target.data('qfq-line-add-button');
@@ -166,6 +201,16 @@ var QfqNS = QfqNS || {};
         var $container = $line.parent();
         var buttonToEnable = $line.data('field.template.addButton');
 
+        var last3Chars = $line[0].childNodes[0].id.slice(-3);
+        var startId = last3Chars.slice(0, 1);
+        var arrayCount = startId - 1;
+
+        function adjustChildIds (actualChild, startId) {
+            actualChild.childNodes.forEach(function(element) {
+                n.adjustIds(element, startId);
+            });
+        }
+
         $line.remove();
 
         n.reExpandLineByLine($container);
@@ -173,6 +218,12 @@ var QfqNS = QfqNS || {};
         if (buttonToEnable) {
             n.enableButton(buttonToEnable);
         }
+
+        for (var i = arrayCount; i < $container[0].childNodes.length; i++) {
+            var actualChild = $container[0].childNodes[i];
+                adjustChildIds(actualChild, startId);
+            startId++;
+        }
     };
 
     /**
@@ -264,7 +315,7 @@ var QfqNS = QfqNS || {};
             var $element = $(this);
             $.each(this.attributes, function () {
                 var retainedPlaceholder = $element.data(this.name);
-                if (retainedPlaceholder) {
+                if (retainedPlaceholder && this.ownerElement.tagName !== "INPUT" || retainedPlaceholder && this.ownerElement.tagName === "INPUT" && this.ownerElement.value === '') {
                     this.value = n.replacePlaceholder(retainedPlaceholder, value);
                 }
             });
diff --git a/javascript/src/Main.js b/javascript/src/Main.js
index d256c6dc0..a0647d71e 100644
--- a/javascript/src/Main.js
+++ b/javascript/src/Main.js
@@ -131,62 +131,65 @@ $(document).ready( function () {
 
         });
 
-        $('.qfq-datepicker').each(function() {
-            var dates = {};
-            var dateArray = {};
-            var datesToFormat = ["minDate", "maxDate"];
-            var correctAttributeNames = ["mindate", "maxdate"];
-            var onlyTime = false;
-            for(var i = 0; i < datesToFormat.length; i++) {
-                var date = false;
-                if($(this).data(correctAttributeNames[i])) {
-                    var cleanDate = $(this).data(correctAttributeNames[i]).split(" ")[0];
-                    var cleanTime = $(this).data(correctAttributeNames[i]).split(" ")[1];
-                    if(cleanDate.includes('.')) {
-                        dateArray = cleanDate.split(".");
-                        date = dateArray[1] + "/" + dateArray[0] + "/" + dateArray[2];
-                    } else if(cleanDate.includes('-')){
-                        dateArray = cleanDate.split("-");
-                        date = dateArray[1] + "/" + dateArray[2] + "/" + dateArray[0];
-                    } else {
-                        var today = new Date();
-                        var dd = String(today.getDate()).padStart(2, '0');
-                        var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
-                        var yyyy = today.getFullYear();
-                        date = mm + "/" + dd + "/" + yyyy + " " + cleanDate;
-                        onlyTime = true;
-                    }
-                    if(cleanTime !== '' && cleanTime !== undefined) {
-                        date = date + " " + cleanTime;
-                    } else if(correctAttributeNames[i] === "maxdate" && !onlyTime) {
-                        date = date + " 23:59:59";
-                    }
-                }
-                dates[datesToFormat[i]] = date;
+        n.initializeDatetimepicker = function (flagDynamicElement) {
+            var selector = '.qfq-datepicker';
+            if (flagDynamicElement) {
+                selector = '.qfq-datepicker:empty';
             }
 
-            var options = {
-                locale: $(this).data("locale") || "en",
-                daysOfWeekDisabled: $(this).data("days-of-week-disabled") || [],
-                minDate: dates.minDate,
-                maxDate: dates.maxDate,
-                format: $(this).data("format") || "DD.MM.YYYY HH:mm",
-                viewMode: $(this).data("view-mode-default") || "days",
-                showClear: ($(this).data("show-clear-button") !== undefined) ? $(this).data("show-clear-button") : true,
-                calendarWeeks: ($(this).data("show-calendar-weeks") !== undefined) ? $(this).data("show-calendar-weeks") : false,
-                useCurrent: ($(this).data("use-current-datetime") !== undefined) ? $(this).data("use-current-datetime") : false,
-                sideBySide: ($(this).data("datetime-side-by-side") !== undefined) ? $(this).data("datetime-side-by-side") : false,
-            };
-
-            var currentDatePicker = $(this).datetimepicker(options);
-
-
-        });
-
-
+            $(selector).each(function () {
+                var dates = {};
+                var dateArray = {};
+                var datesToFormat = ["minDate", "maxDate"];
+                var correctAttributeNames = ["mindate", "maxdate"];
+                var onlyTime = false;
+                for (var i = 0; i < datesToFormat.length; i++) {
+                    var date = false;
+                    if ($(this).data(correctAttributeNames[i])) {
+                        var cleanDate = $(this).data(correctAttributeNames[i]).split(" ")[0];
+                        var cleanTime = $(this).data(correctAttributeNames[i]).split(" ")[1];
+                        if (cleanDate.includes('.')) {
+                            dateArray = cleanDate.split(".");
+                            date = dateArray[1] + "/" + dateArray[0] + "/" + dateArray[2];
+                        } else if (cleanDate.includes('-')) {
+                            dateArray = cleanDate.split("-");
+                            date = dateArray[1] + "/" + dateArray[2] + "/" + dateArray[0];
+                        } else {
+                            var today = new Date();
+                            var dd = String(today.getDate()).padStart(2, '0');
+                            var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
+                            var yyyy = today.getFullYear();
+                            date = mm + "/" + dd + "/" + yyyy + " " + cleanDate;
+                            onlyTime = true;
+                        }
+                        if (cleanTime !== '' && cleanTime !== undefined) {
+                            date = date + " " + cleanTime;
+                        } else if (correctAttributeNames[i] === "maxdate" && !onlyTime) {
+                            date = date + " 23:59:59";
+                        }
+                    }
+                    dates[datesToFormat[i]] = date;
+                }
 
+                var options = {
+                    locale: $(this).data("locale") || "en",
+                    daysOfWeekDisabled: $(this).data("days-of-week-disabled") || [],
+                    minDate: dates.minDate,
+                    maxDate: dates.maxDate,
+                    format: $(this).data("format") || "DD.MM.YYYY HH:mm",
+                    viewMode: $(this).data("view-mode-default") || "days",
+                    showClear: ($(this).data("show-clear-button") !== undefined) ? $(this).data("show-clear-button") : true,
+                    calendarWeeks: ($(this).data("show-calendar-weeks") !== undefined) ? $(this).data("show-calendar-weeks") : false,
+                    useCurrent: ($(this).data("use-current-datetime") !== undefined) ? $(this).data("use-current-datetime") : false,
+                    sideBySide: ($(this).data("datetime-side-by-side") !== undefined) ? $(this).data("datetime-side-by-side") : false,
+                };
+
+                var currentDatePicker = $(this).datetimepicker(options);
 
+            });
+        };
 
+        n.initializeDatetimepicker(false);
         n.Helper.calendar();
 
     })(QfqNS);
-- 
GitLab