PageSourceSearch

https://www.stadtwerk-am-see.de/de/static/js/HRSysLib/Hilfsfunktionen/DOM.js?nc=1790923960777

js stadtwerk-am-see.de collected 2026-10-04 00:25:27 UTC 35,101 bytes, 1,190 lines download raw bytes

1/***************************************************************************
2// Firma:        Hehner Reus Systems GmbH
3// Projekt:      com.cerno.basis
4// Datei:        DOM.js
5// Erstellung:   02.07.2010
6// Verwendung:   Hilfsfunktionen für den Umgang mit dem DOM.
7/***************************************************************************/
8
9// TODO: Wenn zu den einzelnen Funktionen ausreichend Unit-Tests geschrieben 
10// wurden, den strict-Modus aktivieren, um weiteren unschönen Effekten vorzubeugen.
11// "use strict";
12
13class HRDOM
14{
15   /**
16    * Funktion ergänzt zu dem übergebenen Objekt das Funktions-Objekt
17    * als Bearbeiter des als Zeichenkette angegebenen Event.
18    * 
19    * @param elementOrId Das Element, zu dem ein EventListener hinzugefügt
20    * werden soll. Entweder direkt das Objekt oder dessen Id.
21    * Wird null übergeben, wird der Event an das window-Objekt geknüpft.
22    * @param eventName Der Name des Events, auf den gelauscht werden soll.
23    * Beispiele: "resize", "click", "select" (immer ohne das "on"!)
24    * @param listener Ein Object, dass das Event interface implementiert hat. Das kann ein Object mit einer 
25    * handleEvent()-Methode oder eine Funktion sein, welche das Event bearbeiten soll.
26    * @param Weitere Konfigurationen. Wie etwa once: true, um einen Listener nur einmal zu nutzen und danach automatisch wieder zu entfernen.
27    */
28   static addEventListener(elementOrId, eventName, listener, config={capture: false})
29   {
30      try
31      {
32         if (eventName == null || typeof(eventName) != "string" || !listener || (typeof(listener) !== 'function' && typeof(listener.handleEvent) !== 'function'))
33            return;
34         
35         var targetElement = null;
36         if (elementOrId != null && typeof(elementOrId) == "string")
37            targetElement = document.getElementById(elementOrId);
38         else if (elementOrId != null && typeof(elementOrId) == "object")
39            targetElement = elementOrId;
40         else if (elementOrId == null)
41            targetElement = window;
42         
43         if (targetElement == null)
44            return;
45         
46         if (targetElement.addEventListener)
47         {
48            targetElement.addEventListener(eventName, listener, config);
49         }
50         else if (targetElement.attachEvent)
51         {
52            targetElement.attachEvent("on" + eventName, listener);
53         }
54      }
55      catch (e)
56      {
57         if (typeof(HRLogError) === 'function')
58            HRLogError(e);
59      }
60   }
61   
62   /**
63    * Funktion entfernt zu dem übergebenen Objekt das Funktions-Objekt
64    * als Bearbeiter des als Zeichenkette angegebenen Event.
65    * 
66    * @param elementOrId Das Element, bei dem ein EventListener entfernt
67    * werden soll. Entweder direkt das Objekt oder dessen Id.
68    * Wird null übergeben, wird der Event vom window-Objekt entfernt.
69    * @param eventName Der Name des Events, auf den nicht mehr gelauscht werden soll.
70    * Beispiele: "resize", "click", "select" (immer ohne das "on"!)
71    * @param listener Ein Object, dass das Event interface implementiert hat. Das kann ein Object mit einer 
72    * handleEvent()-Methode oder eine Funktion sein, welche das Event bearbeiten soll.
73    */
74   static removeEventListener(elementOrId, eventName, listener)
75   {
76      try
77      {
78         if (eventName == null || typeof(eventName) != "string" || !listener || (typeof(listener) !== 'function' && typeof(listener.handleEvent) !== 'function'))
79            return;
80         
81         var targetElement = null;
82         if (elementOrId != null && typeof(elementOrId) == "string")
83            targetElement = document.getElementById(elementOrId);
84         else if (elementOrId != null && typeof(elementOrId) == "object")
85            targetElement = elementOrId;
86         else if (elementOrId == null)
87            targetElement = window;
88         
89         if (targetElement == null)
90            return;
91         
92         if (targetElement.removeEventListener)
93         {
94            targetElement.removeEventListener(eventName, listener, false);
95         }
96         else if (targetElement.attachEvent)
97         {
98            targetElement.detachEvent("on" + eventName, listener);
99         }
100      }
101      catch (e)
102      {
103         if (typeof(HRLogError) === 'function')
104            HRLogError(e);
105      }
106   }
107   
108   /**
109    * Fügt die übergebene Funktion dem onload-Event der
110    * Seite hinzu.
111    * 
112    * @param onLoadFunction die JavaScript-Funktion, die
113    * beim onload-Event zusätzlich aufgerufen wird.
114    */
115   static addOnLoad(onLoadFunction)
116   {
117      if (window.addEventListener)
118      {
119         window.addEventListener("load", onLoadFunction, false);
120      }
121      else if (window.attachEvent)  
122      {
123         window.attachEvent("onload", onLoadFunction);
124      }
125      else
126         window.onload = onLoadFunction;
127   }
128
129   /**
130    * Fügt die übergebene Funktion dem ajax-onload-Event der Seite hinzu.
131    * 
132    * @param sender Das Element, welches das Event getriggert hat.
133    * @param onLoadFunction die JavaScript-Funktion, die beim onload-Event zusätzlich aufgerufen wird.
134    */
135   static addOnAjaxLoad(sender, onLoadFunction)
136   {
137      try
138      {
139         if (sender && typeof(sender) === 'string')
140         {
141            sender = document.getElementById(sender);
142         }
143         if (sender && HREventManager && typeof(HREventManager.addListener) === 'function')
144            HREventManager.addListener(sender, 'ajax-load', onLoadFunction, {useStandard: false, notifiedByParents: true});
145      }
146      catch (e)
147      {
148         if (typeof(HRLogError) === 'function')
149            HRLogError(e);
150      }
151   }
152   
153   /**
154    * Hiermit kann ein Element durch ein anderes Element "gewrappt" werden.
155    * 
156    * @param element Das zu wrappende Element
157    * @param wrapper Der Wrapper
158    */
159   static wrap(element, wrapper)
160   {
161      try
162      {
163         if (element && wrapper && element.parentNode)
164         {
165            element.parentNode.insertBefore(wrapper, element);
166            wrapper.appendChild(element);
167         }
168      }
169      catch (e)
170      {
171         if (typeof(HRLogError) === 'function')
172            HRLogError(e);
173      }
174   }
175   
176   /**
177    * Analogon zur Methode insertBefore: Fügt ein Element hinter ein anderes Element ein.
178    * 
179    * Anmerkung: Aktuell (10.03.2020) gibt es keine insertAfter-Standardfunktion.
180    * Quelle: https://stackoverflow.com/questions/4793604/how-to-insert-an-element-after-another-element-in-javascript-without-using-a-lib
181    * 
182    * @param element Das einzufügende Element
183    * @param referenceElement Das Element, hinter welches das Element eingefügt werden soll.
184    */
185   static insertAfter(element, referenceElement)
186   {
187      try
188      {
189         //
190         // Falls das Referenz-Element das letzte Element sein sollte, ist nextSibling null, doch insertBefore
191         // deckt diesen Fall bereits ab und fügt das Element als letztes Element der Nodelist ein. 
192         //
193         if (referenceElement.parentNode)
194            referenceElement.parentNode.insertBefore(element, referenceElement.nextSibling);
195      }
196      catch (e)
197      {
198         if (typeof(HRLogError) === 'function')
199            HRLogError(e);
200      }
201   }
202   
203   /**
204    * Fügt das übergebene Element als erstes Kind in den übergebenen Parentknoten ein.
205    * 
206    * @param element Das einzufügende Element.
207    * @param parent Der Parent-Knoten, in den das Kind eingefügt werden soll.
208    */
209   static insertAsFirstChild(element, parent)
210   {
211      try
212      {
213         //
214         // Falls das Referenz-Element das letzte Element sein sollte, ist nextSibling null, doch insertBefore
215         // deckt diesen Fall bereits ab und fügt das Element als letztes Element der Nodelist ein. 
216         //
217         if (parent.firstChild)
218            parent.insertBefore(element, parent.firstChild);
219         else
220            parent.appendChild(element);
221      }
222      catch (e)
223      {
224         if (typeof(HRLogError) === 'function')
225            HRLogError(e);
226      }
227   }
228   
229   /**
230    * Entfernt alle Kinder des übergebenen DOM-Elements.
231    * 
232    * @param element Der Knoten, dessen Kinder entfernt werden sollen.
233    */
234   static removeAllChildren(element)
235   {
236      try
237      {
238         if (element)
239         {
240            while (element.firstChild)
241            {
242               element.removeChild(element.lastChild);
243            }
244         }
245      }
246      catch (e)
247      {
248         if (typeof(HRLogError) === 'function')
249            HRLogError(e);
250      }
251   }
252   
253   /**
254    * Kopiert den übergebenen Text in die Zwischenablage.
255    * 
256    * @param txt Der zu kopierende Text.
257    */
258   static copyToClipboard(txt)
259   {
260      try
261      {
262         if (!txt)
263            txt = '';
264         
265         // Aus Sicherheitsgründen ist das clipboard-Objekt nur für https verfügbar... 
266         if (navigator.clipboard && typeof(navigator.clipboard.writeText) === 'function')
267            navigator.clipboard.writeText(txt);
268         else
269         {
270            // ... andernfalls bieten wir zunächst einfach das alte Workaround mit window-Prompt an.
271            window.prompt("Bitte kopieren Sie folgenden Text in die Zwischenablage (Strg+C):", txt);
272         }
273      }
274      catch (e)
275      {
276         if (typeof(HRLogError) === 'function')
277            HRLogError(e);
278      }
279   }
280   
281   /**
282    * Gibt an, ob das Element fokussierbar ist.
283    * 
284    * @param el Element
285    * @return True, Element ist fokussierbar.
286    */
287   static isFocusable(el)
288   {
289      if (el)
290      {
291         // Sichtbarkeit prüfen: Elemente müssen sichtbar sein.
292         if (el.style.display !== 'none' && el.style.visibility !== 'hidden' && !el.disabled && el.offsetParent !== null)
293         {
294            // Nur solche Elemente, die einen Tabindex haben.
295            if (parseInt(el.tabIndex) >= 0)
296            {
297               // Keine a-Tags mit ungültigen Eigenschaften oder hidden fields.
298               if ((el.tagName === 'A' && (el.rel === 'ignore' || !el.href)) || (el.tagName === 'INPUT' && el.type === 'hidden')) 
299                  return false;
300               
301               return true;
302            }
303         }
304      }
305      
306      return false;
307   }
308   
309   /**
310    * Ermittelt das erste fokussierbare Element unterhalb eines gegebenen HTML-Elements.
311    * 
312    * @param el Das zu prüfende Element.
313    * @return Gibt das erste fokussierbare Element zurück oder null, falls keines gefunden werden konnte.
314    */
315   static getFirstFocusableDescendant(el)
316   {
317      let focusableDescendant = null;
318      
319      try
320      {
321         if (el)
322         {
323            for (let i = 0; i < el.children.length; i++)
324            {
325               if (!focusableDescendant)
326               {
327                  if (this.isFocusable(el.children[i]))
328                     return el.children[i];
329                  else
330                     focusableDescendant = this.getFirstFocusableDescendant(el.children[i]);
331               }
332            }
333         }
334      }
335      catch (e)
336      {
337         if (typeof(HRLogError) === 'function')
338            HRLogError(e);
339      }
340      
341      return focusableDescendant;
342   }
343   
344   /**
345    * Ermittelt das letzte fokussierbare Element unterhalb eines gegebenen HTML-Elements.
346    * 
347    * @param el Das zu prüfende Element.
348    * @return Gibt das erste fokussierbare Element zurück oder null, falls keines gefunden werden konnte.
349    */
350   static getLastFocusableDescendant(el)
351   {
352      let focusableDescendant = null;
353      
354      try
355      {
356         if (el)
357         {
358            for (let i = el.children.length-1; i >= 0 ; i--)
359            {
360               if (!focusableDescendant)
361               {
362                  if (this.isFocusable(el.children[i]))
363                     return el.children[i];
364                  else
365                     focusableDescendant = this.getLastFocusableDescendant(el.children[i]);
366               }
367            }
368         }
369      }
370      catch (e)
371      {
372         if (typeof(HRLogError) === 'function')
373            HRLogError(e);
374      }
375      
376      return focusableDescendant;
377   }
378   
379   /**
380    * Sorgt dafür, dass der Tab-Fokus in dem übergebenen HTML-Container-Element gefangen bleibt.
381    * 
382    * @param el Das Container-Element (z.B. ein div), unter dem der Fokus gefangen sein soll.
383    */
384   static trapFocus(el)
385   {
386      try
387      {
388         const firstEl = this.getFirstFocusableDescendant(el);
389         const lastEl = this.getLastFocusableDescendant(el);
390         if (firstEl && lastEl)
391         {
392            if (lastEl !== firstEl)
393            {
394               this.addEventListener(firstEl, 'keydown', (event) => {
395                  if (event.shiftKey && event.key === 'Tab')
396                  {
397                     lastEl.focus();
398                     event.preventDefault();
399                  }
400               });
401               
402               this.addEventListener(lastEl, 'keydown', (event) => {
403                  if (!event.shiftKey && event.key === 'Tab')
404                  {
405                     firstEl.focus();
406                     event.preventDefault();
407                  }
408               });
409            }
410            else // Nur ein fokussierbares Element vorhanden.
411            {
412               this.addEventListener(firstEl, 'keydown', (event) => {
413                  if (event.key === 'Tab')
414                  {
415                     firstEl.focus();
416                     event.preventDefault();
417                  }
418               });
419            }
420         }
421      }
422      catch (e)
423      {
424         if (typeof(HRLogError) === 'function')
425            HRLogError(e);
426      }
427   }
428   
429   /**
430    * Prüft, ob das aktuelle window-Objekt in einem i-Frame geladen wird.
431    * 
432    * @returns true, falls es in einem i-Frame geladen wird.
433    */
434   static inIframe()
435   {
436      try
437      {
438          return window.self !== window.top;
439      }
440      catch (e)
441      {
442          return true;
443      }
444   }
445   
446   /**
447    * Erzeugt eine für uns statistisch ausreichend wahrscheinliche eindeutige ID.
448    */
449   static uniqueID()
450   {
451      return Math.floor(Math.random() * Date.now());
452   }
453   
454   /**
455    * Fügt die übergebene Funktion dem browserspezifischen Event für die Beendigung der 
456    * Transition bezüglich des übergebenen Elements hinzu. D.h. man kann eine Callback-
457    * Funktion für das Ende einer CSS-Transition angeben.
458    * 
459    * @param element Das Element, auf welches die Transition angewendet wird.
460    * @param onTransitionEndedFunction Die auszuführende Funktion nach Beendigung der Transition.
461    */
462   static addTransitionEndedEventListener(element, onTransitionEndedFunction)
463   {
464      try
465      {
466         //
467         // Ermittelt den korrekten Eventnamens des "transitioned"-Events zum aktuellen Browser.
468         //
469         const transitions = {
470            "transition"      : "transitionend",
471            "OTransition"     : "oTransitionEnd",
472            "MozTransition"   : "transitionend",
473            "WebkitTransition": "webkitTransitionEnd"
474         };
475         
476         let eventName;
477         for (let transition in transitions)
478         {
479             if (document.body.style[transition] != undefined)
480                eventName = transitions[transition];
481         }
482         
483         if (eventName)
484            HREventManager.addListener(element, eventName, onTransitionEndedFunction, {unique: true});
485      }
486      catch (e)
487      {
488         if (typeof(HRLogError) === 'function')
489            HRLogError(e);
490      }
491   }
492   
493   /**
494    * Prüft, ob ein Javascript-Include zu der übergebenen URL im HTML-Head existiert.
495    * 
496    * @param url Die zu ladende externe Ressource.
497    * @param searchDOM true, falls der Include im gesamten DOM gesucht werden soll. Default: Sucht nur im Head.
498    * @return true, falls es den Include gibt.
499    */
500   static containsScriptInclude(url, searchDOM)
501   {
502      var found = false;
503      
504      try
505      {
506         if (url)
507         {
508            var scripts;
509            if (searchDOM)
510               scripts = document.getElementsByTagName('script');
511            else
512            {
513               var head = document.getElementsByTagName('head')[0];
514               scripts = head.getElementsByTagName('script');
515            }
516            if (scripts)
517            {
518               var l = scripts.length;
519               for (let i = 0; i < l && !found; i++)
520               {
521                  if (scripts[i].src && scripts[i].src.length > 0 && url.indexOf(scripts[i].src) >= 0)
522                  {
523                     found = true;
524                     break;
525                  }
526               }
527            }
528         }
529      }
530      catch (e)
531      {
532         if (typeof(HRLogError) === 'function')
533            HRLogError(e);
534      }
535      
536      return found;
537   }
538   
539   /**
540    * Erzeugt, falls noch nicht vorhanden, einen Javascript-Include auf ein externes Javascript-File im HTML-Head der Seite. Das Laden erfolgt asynchron.
541    * 
542    * @param url Die zu ladende externe Ressource.
543    * @param onLoadFunction CallBack-Funktion, die aufgerufen wird, wenn das Script vollständig geladen wurde.
544    * @param searchDOM true, falls der Include im gesamten DOM gesucht werden soll. Default: Sucht nur im Head.
545    * 
546    * @return true, falls es zuvor noch keinen solchen Include gab.
547    */
548   static appendScriptIncludeToHead(url, onLoadFunction, searchDOM)
549   {
550      var found = this.containsScriptInclude(url, searchDOM);
551      
552      if (url)
553      {
554         var head = document.getElementsByTagName('head')[0];
555         if (!found)
556         {
557            //
558            // Im Head das neue Script erzeugen.
559            //
560            var script = document.createElement('script');
561            script.async = true;
562            script.src = url;
563            
564            if (onLoadFunction && typeof(onLoadFunction) === 'function')
565            {
566               script.onload = function() {
567                  try
568                  {
569                     onLoadFunction();
570                  }
571                  catch(e)
572                  {
573                     if (typeof(HRLogError) === 'function')
574                        HRLogError(e);
575                  }
576               };
577            }
578            head.appendChild(script);
579         }
580         else if (onLoadFunction && typeof(onLoadFunction) === 'function')
581            onLoadFunction();
582      }
583      
584      return !found;
585   }
586   
587   /**
588    * Prüft, ob ein CSS-Link-Include zu der übergebenen URL im HTML-Head existiert.
589    * 
590    * @param url Die zu ladende externe Ressource.
591    * @param searchDOM true, falls der Include im gesamten DOM gesucht werden soll. Default: Sucht nur im Head.
592    * @return true, falls es den Include gibt.
593    */
594   static containsCSSLinkInclude(url, searchDOM)
595   {
596      let found = false;
597      
598      try
599      {
600         if (url)
601         {
602            let links;
603            if (searchDOM)
604               links = document.getElementsByTagName('link');
605            else
606            {
607               const head = document.getElementsByTagName('head')[0];
608               links = head.getElementsByTagName('link');
609            }
610            if (links)
611            {
612               let i = 0;
613               const l = links.length;
614               for (i = 0; i < l && !found; i++)
615               {
616                  if (links[i].href && links[i].href.length > 0 && url.indexOf(links[i].href) >= 0)
617                  {
618                     found = true;
619                     break;
620                  }
621               }
622            }
623         }
624      }
625      catch (e)
626      {
627         if (typeof(HRLogError) === 'function')
628            HRLogError(e);
629      }
630      
631      return found;
632   }
633   
634   /**
635    * Erzeugt, falls noch nicht vorhanden, einen Link-Include auf ein externes CSS-Styling.
636    * 
637    * @param url Die URL zum externen Styling.
638    * @param searchDOM true, falls der Include im gesamten DOM gesucht werden soll. Default: Sucht nur im Head.
639    * 
640    * @return true, falls es zuvor noch keinen solchen Include gab.
641    */
642   static appendCSSLinkIncludeToHead(url, searchDOM)
643   {
644      let found = this.containsCSSLinkInclude(url, searchDOM);
645      if (url)
646      {
647         const head = document.getElementsByTagName('head')[0];
648         if (!found)
649         {
650            // Im Head den neuen Link erzeugen.
651            const link = document.createElement('link');
652            link.rel = 'stylesheet';
653            link.href = url;
654            head.appendChild(link);
655         }
656      }
657      
658      return !found;
659   }
660   
661   /**
662    * Dient dem Mischen der Default-Konfiguration mit der vom Nutzer eingegeben Konfiguration.
663    * Sollte der Nutzer eine Konfiguration getätigt haben, so wird die Default-Konfig. mit diesem
664    * Wert überschrieben.
665    * 
666    * @param defaultConfig Die Default-Konfiguration.
667    * @param userConfig Die vom Nutzer eingegebene Konfiguration.
668    * 
669    * @returns config Die neue Konfiguration oder null, falls etwas schiefgegangen ist.
670    */
671   static mergeConfigs(defaultConfig, userConfig)
672   {
673      const config = defaultConfig;
674      try
675      {
676         if (userConfig == null)
677         {
678            return defaultConfig;
679         }
680         else if (defaultConfig == null)
681         {
682            return userConfig;
683         }
684         else
685         {
686            for (let key in userConfig)
687            {
688               config[key] = userConfig[key];
689            }
690         }
691      }
692      catch(error)
693      {
694         return null;
695      }
696      return config;
697   }
698   
699   /**
700    * Funktion gibt die Scrolltiefe in Prozent zurück.
701    * Wird ein maximaler Wert übergeben, wird die Scrolltiefe
702    * nur zurückgegeben, wenn dieser überschritten wurde.
703    * Ansonsten wird der maximale Wert zurückgegeben.
704    * 
705    * @param maxValue Der maximale Wert (optional)
706    * @return Die Scrolltiefe oder der maximale Wert
707    */
708   static getScrollPercent(maxValue)
709   {
710       try
711       {
712           if (maxValue == null)
713               maxValue = 0;
714           var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
715           var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || document.body.offsetHeight;
716           var pageHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight);
717           var scrollBottom = windowHeight + scrollTop;
718           var scrollPercent = Math.round(scrollBottom * 100 / pageHeight);
719           if (scrollPercent > maxValue && scrollPercent <= 100)
720               return scrollPercent;
721           return maxValue;
722       }
723       catch (e)
724       {
725          if (typeof(HRLogError) == 'function')
726             HRLogError(e);
727       }
728       return 0;
729   }
730   
731   /**
732    * Liefert zu der übergebenen Id das passende Element-Objekt,
733    * allerdings nur, wenn das gesuchte Element ein Parent (oder
734    * Grandparent, usw.) des übergebenen Elements ist.
735    * 
736    * @param startElement Das Element dessen Parent mit der übergebenen id gesucht ist.
737    * @param idToFind Die Id, die das ParentElement haben muss.
738    * @returns
739    */
740   static getParentElementById(startElement, idToFind)
741   {
742      if (startElement && idToFind && typeof(idToFind) === 'string' && idToFind.length > 0)
743         return startElement.closest(`#${idToFind}`);
744         
745      return null;
746   }
747   
748   /**
749    * Prüft, ob unter ein Start-Element ein gewisses Parent-Element hat.
750    * 
751    * @param startElement Das Element, von dem aus mit der Suche gestartet werden soll.
752    * @param parentToFind Das zu ermittelnde Parent-Element.
753    * @return Das gesuchte Parent-Element oder null, falls dieses nicht gefunden wurde.
754    */
755   static isParentElement(startElement, parentToFind)
756   {
757      let elemFound = null;
758      
759      if (startElement && parentToFind)
760      {
761         let parentElem = startElement.parentNode;
762         let saveCount = 0;
763         while (elemFound == null && parentElem != null && parentElem.tagName && parentElem.tagName.toLowerCase() != "html" && saveCount < 100)
764         {
765            saveCount++;
766            if (parentElem == parentToFind)
767               elemFound = parentElem;
768            else
769               parentElem = parentElem.parentNode;
770         }
771      }
772      
773      return elemFound;
774   }
775   
776   /**
777    * Setzt den Wert einer Radiobutton-Gruppe. Wenn der Wert
778    * nicht existiert, wird die Gruppe zurückgesetzt.
779    * 
780    * @param radiobuttons Eine Radiobutton-Gruppe, genauer ein Array mit Radiobuttons des selben Namens.
781    * @param value Der Wert desjenigen Radiobuttons, der angehakt werden soll.
782    */
783   static checkRadioByValue(radiobuttons, value)
784   {
785      try
786      {
787         if (radiobuttons)
788         {
789            const radioLength = radiobuttons.length;
790            if (radioLength)
791            {
792               for (let i = 0; i < radioLength; i++)
793               {
794                  radiobuttons[i].checked = false;
795                  if (radiobuttons[i].value == value.toString())
796                     radiobuttons[i].checked = true;
797               }
798            }
799            else
800               radiobuttons.checked = (radiobuttons.value == value.toString());
801         }
802      }
803      catch (e)
804      {
805         if (typeof(HRLogError) === 'function')
806            HRLogError(e);
807      }
808   }
809   
810   /**
811    * Gibt aus einer Radiobutton-Gruppe den ausgewählten
812    * Wert zurück.
813    * 
814    * @param radioObj Die Radiobutton-Gruppe
815    * @return Der ausgewählte Wert oder null, wenn kein Element
816    * ausgewählt wurde oder keine Radiobuttons existieren
817    */
818   static getCheckedValue(radioObj)
819   {
820      try
821      {
822         if (radioObj)
823         {
824            var radioLength = radioObj.length;
825            if (radioLength)
826            {
827               for (let i = 0; i < radioLength; i++)
828               {
829                  if (radioObj[i].checked)
830                     return radioObj[i].value;
831               }
832            }
833            else if (radioObj.checked)
834               return radioObj.value;
835         }
836      }
837      catch (e)
838      {
839         if (typeof(HRLogError) === 'function')
840            HRLogError(e);
841      }
842      
843      return null;
844   }
845   
846   /**
847    * Ermittelt unter den Radioboxen des übergebenen Namens den Wert der ausgewählten Box.
848    * 
849    * @param name Der Name der relevanten Radioboxen.
850    * @erturn Der Wert der ausgewählten Radiobox oder eine leere Zeichenkette, falls keine Radiobox ausgewählt wurde.
851    */
852   static getSelectedRadioboxValue(name)
853   {
854      return getCheckedValue(document.getElementsByName(name));
855   }
856   
857   /**
858    * Schreibt die übergebene Zeichenkette in den Body.
859    * Kann insbesondere als Debugging-Hilfsmittel genutzt werden.
860    * 
861    * @param string Die im Body darzustellende Zeichenkette.
862    * @return Das am Body hängende Div mit der Zeichenkette.
863    */
864   static printToBody(string)
865   {
866      let tmpDiv = document.getElementById('hr_tmp_div');
867      if (!tmpDiv)
868      {
869         tmpDiv = document.createElement('div');
870         document.body.appendChild(tmpDiv);
871         tmpDiv.id = 'hr_tmp_div';
872      }
873      tmpDiv.appendChild(document.createTextNode(string));
874      tmpDiv.appendChild(document.createElement('br'));
875      
876      return tmpDiv;
877   }
878   
879   /**
880    * Getter für den Wert eines Formularelements (Eingabefeld, Radiobutton, Checkbox, Dropdown).
881    * 
882    * @param elementName Der Name des Formularelements, dessen Wert ermittelt werden soll.
883    * @param formname Der Name des Formulars, unter dem das Element gesucht werden soll.
884    * @returns der Wert des gesuchten Formularelements oder eine leere Zeichenkette, falls das 
885    *          Element nicht gefunden werden konnte.
886    */
887   static getFormValueByName(elementName, formname)
888   {
889      try
890      {
891         var theForm = null;
892         if (!elementName || elementName == "")
893            return "";
894         
895         if (document.forms.length > 0)
896         {
897            if (formname && formname != "")
898               theForm = document.forms[formname];
899            
900            if (theForm == null)
901               theForm = document.forms[0];
902            
903            var element = theForm.elements[elementName];
904            if (!element)  // Vielleicht wurde auch eine ElementId angegeben...
905               element = document.getElementById(element);
906            
907            if (!element)
908               return "";
909            
910            if (element.length && element.length > 0)
911            {
912               if (element[0] == null || typeof(element[0].type) != "string" || (element[0].type.toLowerCase() != "hidden" && element[0].type.toLowerCase() != "text"))
913               {
914                  for (let i = 0; element[i]; i++)
915                  {
916                     if (element[i].checked || element[i].selected)
917                        return element[i].value;
918                  }
919               }
920               else
921               {
922                  return element[0].value;
923               }
924            }
925            else if (element.type.toLowerCase() == "radio" || element.type.toLowerCase() == "checkbox")
926            {
927               if (element.checked && element.value)
928                  return element.value;
929            }
930            else if (element.value)
931            {
932               return element.value;
933            }
934         }
935      }
936      catch (except)
937      {
938      }
939      
940      return "";
941   }
942   
943   /**
944    * Kopiert alle Attribute eines DOM-Elements zu einem anderen DOM-Element.
945    * 
946    * @param source Das HTML-Element, dessen Attribute kopiert werden sollen.
947    * @param target Das HTML-Element, das die kopierten Attribute erhalten soll.
948    */
949   static copyAttributes(source, target)
950   {
951      Array.from(source.attributes).forEach(attr => {
952         target.setAttribute(attr.name, attr.value);
953      });
954   }
955   
956   /**
957    * Prüft, ob zwei gegebene Objekte gleich sind. Methode kann benutzt werden, um zwei Objekte zu
958    * vergleichen, die nicht auf die selbe Memory location zeigen. 
959    * 
960    * @param obj1 Das erste zu prüfende Objekt.
961    * @param obj2 Das zweite zu prüfende Objekt.
962    * @return true, falls die Objekte gleiche Eigenschaften mit übereinstimmenden Werten haben.
963    */
964   static isEqual(obj1, obj2)
965   {
966      if (obj1 === obj2)
967         return true;
968      
969      if (!obj1 || !obj2)
970         return false;
971      
972      const entries1 = Object.entries(obj1);
973      const entries2 = Object.entries(obj2);
974      
975      if (entries1.length !== entries2.length)
976          return false;
977      
978      return entries1.every(([key, value]) =>
979          obj2.hasOwnProperty(key) && obj2[key] === value);
980  };
981  
982  /**
983   * Setzt den Wert eines HTML-Elements. Hier wird auch die 
984   * Ausgabe vom Edit-In-Place berücksichtigt.
985   * 
986   * @param el Das Element oder ein CSS-Selektor zum Element.
987   * @param value Der zu setzende Wert.
988   */
989  static setValue(el, value)
990  {
991     // Wenn el ein Selector-String ist, das Element finden.
992     if (typeof el === "string") 
993         el = document.querySelector(el);
994
995     if (!el)
996         return;
997
998     // Prüfen, ob Element überhaupt value besitzt.
999     if (!("value" in el))
1000         return;
1001
1002     // Wert des Elements setzen.
1003     el.value = value;
1004
1005     // Falls Edit-in-Place vorhanden ist, dann Ausgabe aktualisieren.
1006     const outputSpan = el.parentNode.querySelector('.edit-in-place-plain-text');
1007     if (outputSpan)
1008         outputSpan.textContent = value;
1009  };
1010}
1011
1012/**
1013 * @see HRDOM.addEventListener(elementOrId, eventName, listener)
1014 * 
1015 * @deprecaded.
1016 */
1017function HRAddEventListener(elementOrId, eventName, listener)
1018{
1019   HRDOM.addEventListener(elementOrId, eventName, listener);
1020}
1021
1022/**
1023 * @see HRDOM.removeEventListener(elementOrId, eventName, listener)
1024 * 
1025 * @deprecaded.
1026 */
1027function HRRemoveEventListener(elementOrId, eventName, listener)
1028{
1029   HRDOM.removeEventListener(elementOrId, eventName, listener);
1030}
1031
1032/**
1033 * @see HRDOM.addOnLoad(onLoadFunction)
1034 * 
1035 * @deprecaded.
1036 */
1037function HRAddOnLoad(onLoadFunction)
1038{
1039   HRDOM.addOnLoad(onLoadFunction);
1040}
1041
1042/**
1043 * @see HRDOM.addOnLoad(onLoadFunction)
1044 * 
1045 * @deprecaded.
1046 */
1047const HRAddOnAjaxLoad = function(sender, onLoadFunction)
1048{
1049   HRDOM.addOnAjaxLoad(sender, onLoadFunction);
1050}
1051
1052/**
1053 * @see HRDOM.addTransitionEnded(element, onTransitionEndedFunction)
1054 * 
1055 * @deprecaded.
1056 */
1057function HRAddTransitionEnded(element, onTransitionEndedFunction)
1058{
1059   HRDOM.addTransitionEndedEventListener(element, onTransitionEndedFunction);
1060}
1061
1062/**
1063 * @see HRDOM.getCookieValue(name)
1064 * 
1065 * @deprecaded.
1066 */
1067function HRGetCookieValue(name)
1068{
1069   return HRDOM.getCookieValue(name);
1070}
1071
1072/**
1073 * @see HRDOM.getScrollPercent(maxValue)
1074 * 
1075 * @deprecaded.
1076 */
1077function HRGetScrollPercent(maxValue)
1078{
1079   return HRDOM.getScrollPercent(maxValue);
1080}
1081
1082/**
1083 * @see HRDOM.mergeConfigs(defaultConfig, userConfig)
1084 * 
1085 * @deprecaded.
1086 */
1087function HRMergeConfigs(defaultConfig, userConfig)
1088{
1089   return HRDOM.mergeConfigs(defaultConfig, userConfig);
1090}
1091
1092/**
1093 * @see HRDOM.wrap(element, wrapper)
1094 * 
1095 * @deprecaded.
1096 */
1097function HRWrap(element, wrapper)
1098{
1099   HRDOM.wrap(element, wrapper);
1100}
1101
1102/**
1103 * @see HRDOM.insertAfter(element, referenceElement)
1104 * 
1105 * @deprecaded.
1106 */
1107function HRInsertAfter(element, referenceElement)
1108{
1109   HRDOM.insertAfter(element, referenceElement);
1110}
1111
1112/**
1113 * @see HRDOM.insertAsFirstChild(element, parent)
1114 * 
1115 * @deprecaded.
1116 */
1117function HRInsertAsFirstChild(element, parent)
1118{
1119   HRDOM.insertAsFirstChild(element, parent);
1120}
1121
1122/**
1123 * @see HRDOM.removeAllChildren(element)
1124 * 
1125 * @deprecaded.
1126 */
1127function HRRemoveAllChildren(element)
1128{
1129   HRDOM.removeAllChildren(element);
1130}
1131
1132/**
1133 * @see HRDOM.containsScriptInclude(url, searchDOM)
1134 * 
1135 * @deprecaded.
1136 */
1137function HRContainsScriptInclude(url, searchDOM)
1138{
1139   return HRDOM.containsScriptInclude(url, searchDOM);
1140}
1141
1142/**
1143 * @see HRDOM.appendScriptIncludeToHead(url, onLoadFunction, searchDOM)
1144 * 
1145 * @deprecaded.
1146 */
1147function HRAppendScriptIncludeToHead(url, onLoadFunction, searchDOM)
1148{
1149   return HRDOM.appendScriptIncludeToHead(url, onLoadFunction, searchDOM);
1150}
1151
1152/**
1153 * @see HRDOM.getParentElementById(startElement, idToFind)
1154 * 
1155 * @deprecaded.
1156 */
1157function HRGetParentElementById(startElement, idToFind)
1158{
1159   return HRDOM.getParentElementById(startElement, idToFind);
1160}
1161
1162/**
1163 * @see HRDOM.isParentElement(startElement, parentToFind)
1164 * 
1165 * @deprecaded.
1166 */
1167function HRIsParentElement(startElement, parentToFind)
1168{
1169   return HRDOM.isParentElement(startElement, parentToFind);
1170}
1171
1172/**
1173 * @see HRDOM.getSelectedRadioboxValue(name)
1174 * 
1175 * @deprecaded.
1176 */
1177function HRGetSelectedRadioboxValue(name)
1178{
1179   return HRDOM.getSelectedRadioboxValue(name);
1180}
1181
1182/**
1183 * @see HRDOM.getFormValueByName(elementName, formname)
1184 * 
1185 * @deprecaded.
1186 */
1187function HRGetFormValueByName(elementName, formname)
1188{
1189   return HRDOM.getFormValueByName(elementName, formname)
1190}

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.