Announcement

Collapse
No announcement yet.

OptGroup.length 0 bei zweitem Select

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • OptGroup.length 0 bei zweitem Select

    Hallo, ich habe einen Dynamic Dropdown, der nur beim ersten Select funktioniert. Beim zweiten und jedem weiteren Select gibt es keine Options mehr. Wenn ich in der ersten Zeile document.getElementById("pos_select") wegnehme, funktioniert alles perfekt.

    Da ich einen zweiten Dropdown im DOM habe, brauche ich die Einschränkung auf den DIV.


    var optgroups = document.getElementById("pos_select").getElementsB yTagName('optgroup');
    let sel = document.getElementById('candidate_functionalarea_ id');
    sel.addEventListener ("change", function () {
    var e = document.getElementById("candidate_functionalarea_ id");
    var functionalarea_id = e.options[e.selectedIndex].value;
    var funcarea_text = e.options[e.selectedIndex].text;
    var options;
    for (var i = 0; i < optgroups.length; i++) {
    if (optgroups[i].label == funcarea_text) {
    options = optgroups[i].innerHTML;
    }
    }
    document.getElementById('candidate_positioncategor y_id').innerHTML = options;
    });

  • #2
    "Da ich einen zweiten Dropdown im DOM habe, brauche ich die Einschränkung auf den DIV."
    Warum?
    Alle Elemente so auch die Dropdowns müssen unterschiedliche ID haben
    Christian

    Comment


    • #3
      Genau, deshalb habe ich ja document.getElementById("pos_select"). Wenn ich das weglasse, läuft es mit einem Dropdpwn perfekt. Sobald ich den zweiten Dropdown dann hinzunehme geht natürlich nichts mehr, weil
      getElementsByTagName('optgroup') sich dann auf beide DIVs bezieht.

      Ich hab das nochmals geändert und wollte sicherstellen, dass optgroups noch den gleichen Inhalt hat wie beim Laden. Aber das geht nicht. Sobald ich einen neuen Wert für die functionalarea_id selektiere ist optgroups_loaded leer.


      let optgroups_loaded = "";

      window.addEventListener("load", function() {
      optgroups_loaded = document.getElementById("pos_select").getElementsB yTagName('optgroup');
      });

      let sel = document.getElementById('candidate_functionalarea_ id');
      sel.addEventListener ("change", function () {
      let optgroups = optgroups_loaded;
      let e = document.getElementById("candidate_functionalarea_ id");
      let funcarea_text = e.options[e.selectedIndex].text;

      let options;
      for (let i = 0; i < optgroups.length; i++) {

      if (optgroups[i].label == funcarea_text) {
      options = optgroups[i].innerHTML;
      }
      }

      document.getElementById('candidate_positioncategor y_id').innerHTML = options;
      });
      Zuletzt editiert von Stonebreaker82; 06.04.2021, 20:20.

      Comment


      • #4
        Jede ID hier pos_select, darf auf einer Seite (im DOM Baum) nur einmal vorkommen. Sofern also das 2. Dropdown ebenfalls in einem 2. DIV Names pos_select liegt ist das unzulässig.
        Liegt es im gleichen DIV wäre ein firstChild, lastChild, nextSibling o.a. zu nutzen.
        Weiterhin prüfen ob dem Element

        document.getElementById("pos_select").getElementsB yTagName('optgroup');
        welches per TAG gesucht wird nicht eine ID zugeordnet werden kann und damit dann mit .getElementById genutzt werden kann. Das 2. Dropdown bekommt dann dort eine andere ID
        Zuletzt editiert von Christian Marquardt; 06.04.2021, 20:54.
        Christian

        Comment


        • #5
          Vielen Dank versteh ich alles, bringe es aber trotzdem nicht zum Ticken. Ich habe jetzt:

          const div_content = document.getElementById("candidate_positioncategor y_id");

          let sel = document.getElementById('candidate_functionalarea_ id');

          sel.addEventListener ("change", function () {

          optgroups = div_content.getElementsByTagName('optgroup');

          console.log(optgroups);

          let e = document.getElementById("candidate_functionalarea_ id");

          let funcarea_text = e.options[e.selectedIndex].text;

          let options;

          for (let i = 0; i < optgroups.length; i++) {

          if (optgroups[i].label == funcarea_text) {
          options = optgroups[i].innerHTML;
          }

          }

          document.getElementById('candidate_positioncategor y_id').innerHTML = options;
          });

          Nach dem Laden funktioniert das einmal. In der Console sehe ich:
          HTMLCollection { 0: optgroup, 1: optgroup, 2: optgroup, length: 3 }

          Beim zweiten Select sind die Options leer. In der Console sehe ich:
          HTMLCollection { length: 0 }

          Mein Problem scheint zu sein, dass ich mit
          ​​​​​​optgroups_loaded = document.getElementById("candidate_positioncategor y_id").getElementsB yTagName('optgroup');

          alle Options bekomme und dann den Inhalt des divs mit

          document.getElementById('candidate_positioncategor y_id').innerHTML = options;

          überschreibe, was ja gewollt ist bei einem Dynamic Dropdown.

          Wenn ich dann einen anderen Select mache, gibt es die ursprünglichen Options nicht mehr, obwohl ich diese mit

          const div_content = document.getElementById("candidate_positioncategor y_id");

          definiert habe.

          Comment


          • #6
            const verhindert nur ein ändern der Variable innerhalb des Blockes in dem sie definiert ist. Wenn dasw Ganze in einer Funktion liegt, wird div_content bei jedem Aufruf neu gesetzt
            Christian

            Comment


            • #7
              Ein bisschen weiter bin ich jetzt schon. Ich habe um die Select noch zwei DIVs mit unterschiedlichen IDs gebaut. Und beim Aufrufen werden die beiden Optgroups Optgroup1 und Optgroup2 auch mit den richtigen Inhalten gesetzt.

              Sobald ich aber einen Select mache, sind die Optgroups leer, obwohl ich sie innerhalb der Funktionen nicht verändere. Irgendwie habe ich ein gravierendes Verständnisproblem.

              const optgroups1 = document.getElementById('pos_select').getElementsB yTagName('optgroup');

              let sel = document.getElementById('candidate_functionalarea_ id');
              sel.addEventListener ("change", function () {
              let e = document.getElementById("candidate_functionalarea_ id");
              let funcarea_text = e.options[e.selectedIndex].text;
              let options1;
              for (let i = 0; i < optgroups1.length; i++) {
              if (optgroups1[i].label == funcarea_text) {
              options1 = optgroups1[i].innerHTML;
              }
              }
              document.getElementById('candidate_positioncategor y_id').innerHTML = options1;
              });

              const optgroups2 = document.getElementById('tag_select').getElementsB yTagName('optgroup');

              let sel2 = document.getElementById('candidate_function_id');
              sel2.addEventListener ("change", function () {
              let e2 = document.getElementById("candidate_function_id");
              let function_text = e2.options[e2.selectedIndex].text;
              let options2;
              for (let i = 0; i < optgroups2.length; i++) {
              if (optgroups2[i].label == function_text) {
              options2 = optgroups2[i].innerHTML;
              }
              }
              document.getElementById('candidate_tag_id').innerH TML = options2;
              });

              Comment


              • #8
                Ich verstehe das ganze Programmkonstrukt nicht.
                Man schreibt keine 2 fast identische Methoden, sondern lieber eine und übergibt dann ggf. Objekte als Parameter.
                Wo wird das Ganze aufgerufen?
                Warum liegen die Optionen (optgroup) irgnewo im HTML-Quelltext rum und werden dann candidate_positioncategor y_id zugeordnet?
                Warum bekommt das 2. Select die gleichen optgroups?
                ...
                Christian

                Comment


                • #9
                  Ich bin entwickle seit 12 Jahren in Rails und habe bisher nur ein paar Kleinigkeiten in JQuery gemacht, so z. B. die Dynamic Dropdowns. Nun kommt Bootstrap 5 ohne JQuery und ich bin gezwungen, den JQuery Code zu migrieren. Insofern ist das mein erster Javascript Versuch.

                  Das Script habe ich am Ende des Formulars per script eingebunden. Das Formular ist Teil einer Rails-Anwendung. Ich könnte es auch im Javascript-Ordner der Rails Anwendung ablegen.

                  Die Options kommen per Rails aus der Datenbank und liegen deshalb im HTML-Quelltext, weil sie von Rails so generiert werden.

                  Der 2. Select hat andere Optgroups, das sehe ich auch im console.log. Das stelle ich sicher durch den div id="tag_select" , der die Options umgibt. Die erste Optgroup wird durch den div id="pos_select" abgegrenzt.

                  ​​​​​​Ich will mal versuchen, das Ganze in eine Methode zu bekommen.

                  Comment


                  • #10
                    Das ist aber kein JQuery.
                    Es sollte in JQuery in der Document.Ready Funktion landen.
                    Events sollten mit JQuery an Objekte gebunden werden
                    Christian

                    Comment


                    • #11
                      Es soll ja auch kein JQuery mehr sein, das hatte ich ja vorher. In Bootstrap 5 gibt es kein JQuery mehr.

                      Das Ganze sieht jetzt so aus. Viel einfacher ist es nicht geworden. Und es tritt genau das gleiche Problem auf. Beim Aufrufen des Formulars sind in optgroups 1 und optgroups2 exakt die Objekte drin, wie erwartet. Sobald ein zweites mal selektiert wird, sind die Optgroups empty, es ist kein einziges Objekt mehr drin.

                      Code:
                      const optgroups1 = document.getElementById('pos_select').getElementsByTagName('optgroup');
                      let sel = document.getElementById('candidate_functionalarea_id');
                      sel.addEventListener("change", function () {
                        let evnt = document.getElementById("candidate_functionalarea_id");
                        let options = dyndrop(optgroups1, evnt);
                        document.getElementById('candidate_positioncategory_id').innerHTML = options;
                      });
                      
                      const optgroups2 = document.getElementById('tag_select').getElementsByTagName('optgroup');
                      let sel2 = document.getElementById('candidate_function_id');
                      sel2.addEventListener("change", function () {
                        let evnt2 = document.getElementById("candidate_functionalarea_id");
                        let options = dyndrop(optgroups2, evnt2);
                        document.getElementById('candidate_positioncategory_id').innerHTML = options;
                      });
                      
                      function dyndrop(optgroups, evnt) {
                        let option_text = evnt.options[evnt.selectedIndex].text;
                        let option_id = evnt.options[evnt.selectedIndex].value;
                        let options;
                        for (let i = 0; i < optgroups.length; i++) {
                          if (optgroups[i].label == option_text) {
                            options = optgroups[i].innerHTML;
                          }
                        }
                       return options;
                      };
                      
                      ​​​​​​

                      Comment


                      • #12
                        Ich gebe es auf.
                        Es ist immer noch vollkommen unklar wann und wo das aufgerufen wird. Das irgendwo in die Seite zu setzen birgt die Gefahr, das die Seite noch gar nicht fertig geladen ist, und der Code schon ausgeführt wird.
                        Das gehört dann in ein onload des Body oder eben in ein document.ready von JQuery
                        Was bewirkt werden soll wurde immer noch nicht gesagt.
                        https://jquery.com/
                        kann man runterladen
                        Christian

                        Comment


                        • #13
                          Das Script steht an derselben Stelle wie vorher das JQuery-Script - unterhalb eines Forms. JQuery will ich nicht mehr benutzen, weil es in Bootstrap 5 durch VanillaJS ersetzt wurde.

                          Bei JQuery sah es übrigens wie folgt aus:

                          Code:
                              jQuery(function() {
                                var positioncategories;
                                positioncategories = $('#candidate_positioncategory_id').html();
                                return $('#candidate_functionalarea_id').change(function() {
                                  var escaped_functionalarea, functionalarea1, options;
                                  functionalarea1 = $('#candidate_functionalarea_id :selected').text();
                                  escaped_functionalarea = functionalarea1.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
                                  options = $(positioncategories).filter("optgroup[label='" + escaped_functionalarea + "']").html();
                                  if (options) {
                                    $('#candidate_positioncategory_id').html(options);
                                    return $('#candidate_positioncategory_id').parent().show();
                                  } else {
                                    $('#candidate_positioncategory_id').empty();
                                    return $('#candidate_positioncategory_id').parent().hide();
                                  }
                                });
                              });

                          Comment


                          • #14
                            Am Rande:
                            Wo der Code steht ist bei dem Jquerycode egal. Das ist eine Funktion.
                            Dein Code ist keine Funktion. Der wird sofort ausgeführt
                            Christian

                            Comment


                            • #15
                              Das ist mir schon klar. Das sehe ich ja auch im console.log, wenn ich mir den Inhalt von optgroup1 und optgroup2 anzeigen lasse. Da passiert aber nicht viel, weil da nur die beiden optgroups gesetzt werden. Der Hauptteil - der Code innerhalb der addEventListener wird natürlich erst beim Selektieren ausgeführt.

                              Um zu verhindern, dass etwas ausgeführt wird, bevor die Seite geladen ist, habe ich noch document.addEventListener('DOMContentLoaded', function () dazugefügt. Geholfen hat es nicht. Es passiert immer noch, dass optgroups1 und optgroups2 re-assigned wird, obwohl sie mit const definiert werden. const verhindert das deshalb nicht, weil optgroup1 und optgroup2 Objekte sind und Object-Properties können wohl jederzeit re-assiged werden.

                              Wenn ich mir den Inhalt von optgroup1 und optgroup2 anzeigen lasse, dann sehe ich, dass die beiden Variablen beim ersten Select der candidate_functionalarea_id noch richtig gefüllt sind ( HTMLCollection { 0: optgroup, 1: optgroup, 2: optgroup, length: 3 } ). Alles läuft perfekt. Sobald ich aber danach eine andere candidate_functionalarea_id selektiere, gibt es in optgroup1 und optgroup2 keine Properties mehr (Inhalt: HTMLCollection { length: 0 }).

                              Wenn es eine Möglichkeit gäbe, dass optgroup1 und optgroup2 nicht verändert werden kann, hätte ich das Problem gelöst.

                              Code:
                              document.addEventListener('DOMContentLoaded', function () {
                              
                              const optgroups1 = document.getElementById('pos_select').getElementsByTagName('optgroup');
                                let sel = document.getElementById('candidate_functionalarea_id');
                                sel.addEventListener("change", function () {
                                  let evnt = document.getElementById("candidate_functionalarea_id");
                                  let options = dyndrop(optgroups1, evnt);
                                  document.getElementById('candidate_positioncategory_id').innerHTML = options;
                                });
                              
                                const optgroups2 = document.getElementById('tag_select').getElementsByTagName('optgroup');
                                let sel2 = document.getElementById('candidate_function_id');
                                sel2.addEventListener("change", function () {
                                  let evnt2 = document.getElementById("candidate_functionalarea_id");
                                  let options = dyndrop(optgroups2, evnt2);
                                  document.getElementById('candidate_positioncategory_id').innerHTML = options;
                                });
                              
                                function dyndrop(optgroups, evnt) {
                                  let option_text = evnt.options[evnt.selectedIndex].text;
                                  let option_id = evnt.options[evnt.selectedIndex].value;
                                  let options;
                                  for (let i = 0; i < optgroups.length; i++) {
                                    if (optgroups[i].label == option_text) {
                                      options = optgroups[i].innerHTML;
                                    }
                                  }
                                  return options;
                                };
                              });
                              Zuletzt editiert von Stonebreaker82; 09.04.2021, 12:24.

                              Comment

                              Working...
                              X