PageSourceSearch

https://www.sdw-sa.de/_assets/bfa2c2186fd7a266438b0b120d5580e7/Jav…/repeatable-container.js?1745318537

js sdw-sa.de collected 2026-10-07 02:14:03 UTC 14,516 bytes, 258 lines download raw bytes

1var ready = (callback) => {
2  if (document.readyState != "loading") callback();
3  else document.addEventListener("DOMContentLoaded", callback);
4}
5ready(() => {
6    var containerClones = {};
7
8    document.querySelectorAll('[data-repeatable-container][data-is-root]').forEach((rootElement) => {
9        let containerClone = rootElement.cloneNode(true),
10            containerIdentifier = rootElement.dataset['identifier'],
11            formIdentifier = rootElement.closest('form').getAttribute('id'),
12            copyButton = containerClone.querySelector('[data-repeatable-container][data-copy-button]');
13
14        containerClones[formIdentifier] = containerClones[formIdentifier] || {};
15
16        for (const copyElement of containerClone.querySelectorAll('[data-repeatable-container][data-is-copy]')) {
17            copyElement.remove();
18        }
19        if (copyButton !== null) {
20            copyButton.remove();
21        }
22        for (const alertElement of containerClone.querySelectorAll('[role="alert"]')) {
23            alertElement.remove();
24        }
25
26        containerClone.querySelectorAll('[data-repeatable-container][data-is-root]').forEach((cloneElement) => {
27            delete cloneElement.dataset.isRoot;
28            cloneElement.dataset.isCopy = '';
29            cloneElement.dataset.copyMother = cloneElement.dataset['identifier'];
30        });
31        delete containerClone.dataset.isRoot;
32        containerClone.dataset.isCopy = '';
33        containerClone.querySelectorAll('*').forEach((cloneChildElement) => {
34            cloneChildElement.classList.remove('has-error');
35        });
36
37        let inputs = [...containerClone.querySelectorAll('input')];
38        inputs.filter((input) => ['checkbox', 'radio', 'hidden'].indexOf(input.getAttribute('type')) == -1).forEach((inputElement) => {
39            inputElement.setAttribute('value', '');
40        });
41        inputs.filter((input) => ['file'].indexOf(input.getAttribute('type')) >= 0).forEach((inputElement) => {
42            [...inputElement.parentNode.children].filter((child) => child !== inputElement).forEach((siblingElement) => {
43                siblingElement.remove();
44            });
45        });
46        inputs.filter((input) => ['checkbox', 'radio'].indexOf(input.getAttribute('type')) >= 0).forEach((inputElement) => {
47            inputElement.checked = false;
48        });
49        containerClone.querySelectorAll('textarea').forEach((textareaElement) => {
50            textareaElement.setAttribute('value', '');
51        });
52        containerClone.querySelectorAll('select').forEach((selectElement) => {
53            let selected = selectElement.selectedOptions;
54            for (let i = 0; i < selected.length; i++) {
55                selected[i].removeAttribute('selected');
56            }
57            selectElement.selectedIndex = -1;
58        });
59
60        containerClones[formIdentifier][containerIdentifier] = containerClone;
61    });
62
63    document.dispatchEvent(new CustomEvent('initialize-repeatable-container-copy-buttons', { 'detail': { 'containerClones': containerClones } }));
64    document.dispatchEvent(new CustomEvent('initialize-repeatable-container-remove-buttons'));
65});
66
67document.addEventListener('initialize-repeatable-container-copy-buttons', (copyEvent) => {
68    let containerClones = copyEvent.detail.containerClones,
69        getNextCopyNumber = (referenceElement, formElement) => {
70            let highestCopyNumber = 0;
71
72            formElement.querySelectorAll('[data-repeatable-container][data-copy-reference="' + referenceElement.dataset['identifier'] + '"]').forEach((copyElement) => {
73                let copyNumber = parseInt(copyElement.dataset['identifier'].split('.').pop());
74
75                if (copyNumber > highestCopyNumber) {
76                    highestCopyNumber = copyNumber;
77                }
78            });
79
80            return ++highestCopyNumber;
81        },
82        setRandomIds = (subject) => {
83            let idReplacements = {};
84
85            subject.querySelectorAll('[id]').forEach((subjectIdElement) => {
86                let id = subjectIdElement.getAttribute('id'),
87                    newId = Math.floor(Math.random() * 99999999) + Date.now();
88
89                subjectIdElement.setAttribute('id', newId);
90                idReplacements[id] = newId;
91            });
92
93            subject.querySelectorAll('*').forEach((subjectChildElement) => {
94                for (let i = 0, len = subjectChildElement.attributes.length; i < len; i++) {
95                    let attributeValue = subjectChildElement.attributes[i].nodeValue;
96
97                    if (attributeValue in idReplacements) {
98                        subjectChildElement.attributes[i].nodeValue = idReplacements[attributeValue];
99                    }
100                }
101            });
102        },
103        escapeRegExp = (subject) => {
104            return subject.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
105        };
106
107    document.querySelectorAll('[data-repeatable-container][data-copy-button]').forEach((copyBtnElement) => {
108        let formElement = copyBtnElement.closest('form'),
109            referenceElementIdentifier = copyBtnElement.dataset['copyButtonFor'],
110            referenceElement = formElement.querySelector('[data-repeatable-container][data-identifier="' + referenceElementIdentifier + '"]'),
111            elementCopies = formElement.querySelectorAll('[data-repeatable-container][data-copy-reference="' + referenceElementIdentifier + '"]'),
112            maxCopies = referenceElement.dataset['maxCopies'] || false;
113
114        if (maxCopies && elementCopies.length >= maxCopies) {
115            copyBtnElement.disabled = true;
116        } else {
117            copyBtnElement.disabled = false;
118            /* clone element to remove all event listeners */
119            let copyBtnElementClone = copyBtnElement.cloneNode(true);
120            copyBtnElement.replaceWith(copyBtnElementClone);
121            copyBtnElementClone.addEventListener('click', (clickEvent) => {
122                clickEvent.preventDefault();
123                let clickElement = clickEvent.currentTarget,
124                    clickFormElement = clickElement.closest('form'),
125                    referenceElementIdentifier = clickElement.dataset['copyButtonFor'],
126                    formIdentifier = clickFormElement.getAttribute('id'),
127                    referenceElement = clickFormElement.querySelector('[data-repeatable-container][data-identifier="' + referenceElementIdentifier + '"]'),
128                    referenceElementIsRoot = 'isRoot' in referenceElement.dataset,
129                    elementCopies = clickFormElement.querySelectorAll('[data-repeatable-container][data-copy-reference="' + referenceElementIdentifier + '"]'),
130                    containerCloneIdentifier = referenceElementIsRoot ? referenceElementIdentifier : referenceElement.dataset['copyMother'],
131                    copyMotherIdentifier = containerClones[formIdentifier][containerCloneIdentifier].dataset['identifier'],
132                    newIdentifierParts = referenceElement.dataset['identifier'].split('.'),
133                    oldIdentifierNameRegex = escapeRegExp('[' + copyMotherIdentifier.split('.').join('][') + ']'),
134                    copyMotherIdentifierRegex = '(' + escapeRegExp('data-copy-mother="') + ')?' + escapeRegExp(copyMotherIdentifier),
135                    newIdentifier = undefined,
136                    newIdentifierNameRegex = undefined,
137                    containerClone = undefined,
138                    containerCloneHtml = undefined;
139
140                newIdentifierParts.pop();
141                newIdentifierParts.push(getNextCopyNumber(referenceElement, clickFormElement));
142                newIdentifier = newIdentifierParts.join('.');
143
144                containerCloneHtml = containerClones[formIdentifier][containerCloneIdentifier].outerHTML;
145                // leading, negative lookbehind ("?<!")
146                containerCloneHtml = containerCloneHtml.replace(new RegExp(copyMotherIdentifierRegex, 'g'), ($0, $1) => {
147                    return $1 ? $0 : newIdentifier;
148                });
149
150                newIdentifierNameRegex = '[' + newIdentifierParts.join('][') + ']';
151                containerCloneHtml = containerCloneHtml.replace(new RegExp(oldIdentifierNameRegex, 'g'), newIdentifierNameRegex);
152
153                let containerCloneWrap = document.createElement('div');
154                containerCloneWrap.innerHTML = containerCloneHtml;
155                containerClone = containerCloneWrap.firstChild;
156                containerClone.dataset.copyReference = referenceElementIdentifier;
157
158                setRandomIds(containerClone);
159
160                if (elementCopies.length === 0) {
161                    referenceElement.after(containerClone);
162                } else {
163                    [...elementCopies].at(-1).after(containerClone);
164                }
165
166                // document.dispatchEvent(new CustomEvent('after-element-copy', { 'detail': { 'containerClone': containerClone } }));
167                document.dispatchEvent(new CustomEvent('initialize-repeatable-container-copy-buttons', { 'detail': { 'containerClones': containerClones } }));
168                document.dispatchEvent(new CustomEvent('initialize-repeatable-container-remove-buttons'));
169            });
170        }
171    });
172});
173
174document.addEventListener('initialize-repeatable-container-remove-buttons', (removeEvent) => {
175    document.querySelectorAll('[data-repeatable-container][data-remove-button]').forEach((removeBtnElement) => {
176        let formElement = removeBtnElement.closest('form'),
177            referenceElementIdentifier = removeBtnElement.dataset['removeButtonFor'],
178            referenceElement = formElement.querySelector('[data-repeatable-container][data-identifier="' + referenceElementIdentifier + '"]'),
179            referenceElementIsRoot = 'isRoot' in referenceElement.dataset,
180            referenceReferenceElementIdentifier = referenceElementIsRoot ? referenceElementIdentifier : referenceElement.dataset['copyReference'],
181            referenceReferenceElement = formElement.querySelector('[data-repeatable-container][data-identifier="' + referenceReferenceElementIdentifier + '"]'),
182            elementCopies = formElement.querySelectorAll('[data-repeatable-container][data-copy-reference="' + referenceReferenceElementIdentifier + '"]'),
183            minCopies = referenceReferenceElement?.dataset['minCopies'] || false;
184
185        if ((referenceElement.dataset['copyReference'] || false) && referenceElement.dataset['copyReference'] !== '') {
186            if (minCopies && elementCopies.length <= minCopies) {
187                // removeBtnElement.classList.remove('d-none');
188                removeBtnElement.disabled = true;
189            } else {
190                // removeBtnElement.classList.remove('d-none');
191                removeBtnElement.disabled = false;
192            }
193        } else {
194            removeBtnElement.remove();
195        }
196
197        if (removeBtnElement.disabled) {
198            /* clone element to remove all event listeners */
199            removeBtnElement.replaceWith(removeBtnElement.cloneNode(true));
200        } else {
201            /* clone element to remove all event listeners */
202            let removeBtnElementClone = removeBtnElement.cloneNode(true);
203            removeBtnElement.replaceWith(removeBtnElementClone);
204            removeBtnElementClone.addEventListener('click', (clickEvent) => {
205                clickEvent.preventDefault();
206
207                let clickElement = clickEvent.currentTarget,
208                    clickFormElement = clickElement.closest('form'),
209                    referenceElementIdentifier = clickElement.dataset['removeButtonFor'],
210                    referenceElement = clickFormElement.querySelector('[data-repeatable-container][data-identifier="' + referenceElementIdentifier + '"]'),
211                    referenceElementIsRoot = 'isRoot' in referenceElement.dataset,
212                    referenceReferenceElementIdentifier = referenceElementIsRoot ? referenceElementIdentifier : referenceElement.dataset['copyReference'],
213                    referenceReferenceElement = clickFormElement.querySelector('[data-repeatable-container][data-identifier="' + referenceReferenceElementIdentifier + '"]'),
214                    elementCopies = clickFormElement.querySelectorAll('[data-repeatable-container][data-copy-reference="' + referenceReferenceElementIdentifier + '"]'),
215                    maxCopies = referenceReferenceElement?.dataset['maxCopies'] || false,
216                    copyButton = clickFormElement.querySelector('[data-repeatable-container][data-copy-button-for="' + referenceReferenceElementIdentifier + '"]');
217
218                if (maxCopies && elementCopies.length - 1 < maxCopies) {
219                    copyButton.disabled = false;
220                }
221
222                referenceElement.remove();
223                document.dispatchEvent(new CustomEvent('initialize-repeatable-container-remove-buttons'));
224            });
225        }
226    });
227});
228
229/* DatePicker is a jQuery UI function and we want to get rid of jQuery... */
230/* document.addEventListener('after-element-copy', (afterCopyEvent) => {
231    let containerClone = afterCopyEvent.detail.containerClone;
232    document.querySelectorAll('[data-element-type="DatePicker"]').forEach((datePickerElement) => {
233        var dateFormat;
234
235        // if (!datePickerElement.classList.contains('hasDatepicker') && parseInt(datePickerElement.getAttribute('data-element-datepicker-enabled')) === 1) {
236        if (!datePickerElement.classList.contains('hasDatepicker') && parseInt(datePickerElement.dataset['elementDatepickerEnabled']) === 1) {
237            // dateFormat = datePickerElement.getAttribute('data-element-datepicker-date-format');
238            dateFormat = datePickerElement.dataset['elementDatepickerDateFormat'];
239
240            dateFormat = dateFormat.replace('d', 'dd');
241            dateFormat = dateFormat.replace('j', 'o');
242            dateFormat = dateFormat.replace('l', 'DD');
243            dateFormat = dateFormat.replace('F', 'MM');
244            dateFormat = dateFormat.replace('m', 'mm');
245            dateFormat = dateFormat.replace('n', 'm');
246            dateFormat = dateFormat.replace('Y', 'yy');
247
248            $('#' + datePickerElement.attr('id')).datepicker({
249                dateFormat: dateFormat
250            }).on('keydown', function(e) {
251                if(e.keyCode == 8 || e.keyCode == 46) {
252                    e.preventDefault();
253                    $.datepicker._clearDate(this);
254                }
255            });
256        }
257    });
258}); */

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.