hmm: Dynamische Auswahlbox in Tabelle reinbauen

Sobald die HTML Seite geladen wurde, wird ein array mit daten befüllt:

array = [paar daten]

im anschluss kann der benutzer der html seite per knopfdurck tabellen zeilen erzeugen. bei jedem knopfdurck wird folgende funktion ausgefuehrt:

function addTableRow() {
    var tempTr = $('<tr><td><input type="number" id="mid_' + i + '" class="form-control" disabled/></td><td><input type="text" id="name_' + i + '" class="form-control"/></td><td><input type="text" id="skill_' + i + '" class="form-control" /><td><input type="text" id="subskill_' + i + '" class="form-control" /></td><td><input type="number" id="nivau_' + i + '" min="0" max="5" class="form-control" /></td><td><span class="glyphicon glyphicon-minus addBtnRemove" id="addBtnRemove"></span></td></tr>');
    $("#tableAddRow").append(tempTr);
    $('.addBtnRemove').click(function () {
        removeIndex[removeIndex.length] = i;
        $(this).closest('tr').remove();  
    });
    i++;
}

ich hätte gerne, das jedes <input id="skill_"...> feld eine auswahlbox bekommt deren inhalt genau der inhalt des arrays ist.

wie bau ich das am besten ein? muss ich das input feld gegen ein select-feld tauschen oder geht das besser?

  1. Hey,

    wie wärs mit select. Also ja und dann eine Schleife über die Array daten.

    Gruß
    Jo

    1. joa

      function addTableRow() {
          var tempTr = $('<tr><td><input type="number" id="mid_' + i + '" class="form-control" disabled/></td><td><input type="text" id="name_' + i + '" class="form-control"/></td><td><select id="skill_' + i + '" class="form-control" /><td><input type="text" id="subskill_' + i + '" class="form-control" /></td><td><input type="number" id="nivau_' + i + '" min="0" max="5" class="form-control" /></td><td><span class="glyphicon glyphicon-minus addBtnRemove" id="addBtnRemove"></span></td></tr>');
          $("#tableAddRow").append(tempTr);
          var option = new Option("Test");
          document.getElementById("skill_" + i) = option;
          $('.addBtnRemove').click(function () {
              removeIndex[removeIndex.length] = i;
              $(this).closest('tr').remove();  
          });
          i++;
      }
      

      wenn iuch die richtige syntax für

      var option = new Option("Test"); document.getElementById("skill_" + i) = option;

      finde gehts. aber ist das sinnvoll das so zu machen? der code wird immer beschissener

      1. das geht nicht:

        var option = document.createElement("option");
            option.setAttribute("value", "test");
            option.innerHTML = "test";
            document.getElementById("skill_" + i).append(option);
        
        1. so gehts, ich muss mir mal sone ide besorgen

          function addTableRow() {
              var tempTr = $('<tr><td><input type="number" id="mid_' + i + '" class="form-control" disabled/></td><td><input type="text" id="name_' + i + '" class="form-control"/></td><td><select id="skill_' + i + '" class="form-control" /><td><input type="text" id="subskill_' + i + '" class="form-control" /></td><td><input type="number" id="nivau_' + i + '" min="0" max="5" class="form-control" /></td><td><span class="glyphicon glyphicon-minus addBtnRemove" id="addBtnRemove"></span></td></tr>');
              $("#tableAddRow").append(tempTr);
              
              for(var n = 0; n < zulaessigeSkills.length; n++) {
                  var option = document.createElement("option");
                  option.setAttribute("value", zulaessigeSkills[n]);
                  option.innerHTML = zulaessigeSkills[n];
                  document.getElementById("skill_" + i).appendChild(option);
              }
              
              $('.addBtnRemove').click(function () {
                  removeIndex[removeIndex.length] = i;
                  $(this).closest('tr').remove();  
              });
              i++;
          }
          
          1. @@hmm

            so gehts

            Nein.

            <span class="glyphicon glyphicon-minus addBtnRemove" id="addBtnRemove"></span>
            
                $('.addBtnRemove').click(function () {
            

            Das kann gar nicht gehen. Ein span ist kein interaktives Element, also nicht anclickbar (außer für einen Teil der Nutzer).

            Merke: Niemals nicht-interaktive Elemente als Target für click-Events vorsehen. Für sowas sind buttons zu verwenden.

            Und eine Beschriftung sollte der Button natürlich auch haben.

            LLAP 🖖

            --
            “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
      2. Hallo hmm,

        du musst die Options nicht von Hand hinzufügen. Du kannst das auch direkt ins HTML reinsetzen.

        Und wenn Du dieses manuelle Templating beschissen findest - dann gebe ich Dir augenblicklich recht. Abgesehen von Template-Libraries kannst Du auch die Template-Strings aus ECMAScript 2015 verwenden, verlierst dann aber den Support für den Internet Explorer.

        Die handgemachte, aber übersichtlichere Lösung ist, das template nicht in einer Zeile zusammen zu bauen, sondern schrittweise als Array, das man am Ende mit join('') verklebt.

        var html = [ '<tr>' ];
        html.push('<td><input type="number" id="mid_' + i + '" class="form-control" disabled/></td>');
        html.push('<td><input type="text" id="name_' + i + '" class="form-control"/></td>');
        html.push('<td><select id="skill_' + i + '" class="form-control" />');
        html.push('<td><input type="text" id="subskill_' + i + '" class="form-control" /></td>');
        html.push('<td><input type="number" id="nivau_' + i + '" min="0" max="5" class="form-control" /></td>');
        html.push('<td><span class="glyphicon glyphicon-minus addBtnRemove" id="addBtnRemove"></span></td>');
        html.push('</tr>');
        
        var tempTr = $(html.join(''));
        

        Dann fällt auch gleich auf, dass das <td> mit dem <select> darin kein Ende-Tag hat.

        Die Zeile, wo das <select>-Statement aufgebaut wird, kannst Du weiter untergliedern. Statt einer for(i=0...) Schleife verwende ich mal die Array-Methode .forEach:

        var skillSelect = [ '<select id="skill_' + i + '" class="form-control">' ];
        zulaessigeSkills.forEach(function(skill) {
           skillSelect.push('<option value="' + skill + '">' + skill + '</option>');
        });
        skillSelect.push('</select>');
        html.push(skillSelect.join(''));
        

        Im übrigen solltest Du Dir überlegen, die Klasse form-control nicht den <td>, sondern der <tr> zuzuordnen. Dann hast Du die class-Angabe nur einmal im HTML stehen und dein Template wird viel kleiner. In deinem Stylesheet ersetzt Du dann

        td.form-control { ... }
        

        durch

        tr.form-control > td { ... }
        

        und bist fertig. Den > Kombinator kannst Du auch weglassen, wenn Du keine geschachtelten Tabellen hast (und wer hat die heute noch, außer hartgesottenen Table-Layout Fans).

        Man kann noch einiges in diesem Script durch moderne Syntax ersetzen (Template-Strings, Arrow-Functions für den forEach Callback), das hab ich erst mal weggelassen. Falls es dich interessiert: Mit JavaScript Template-Strings (und herausgezogener form-control Klasse) sähe einer der push-Aufrufe so aus:

        html.push(`<td><input type="number" id="mid_${i}" disabled/></td>`);
        

        Der Unterschied ist, dass der Template-String in Backticks (dem Gravis-Akzent) eingeschlossen wird statt in Hochkomma oder Anführungszeichen. Was dann in ${...} steht, wird als Javascript-Ausdruck interpretiert.

        Der Aufbau der Optionen sähe mit Arrow-Function und Template-String so aus:

        zulaessigeSkills.forEach(skill => skillSelect.push(`<option value="${skill}">${skill}</option>`));
        

        Rolf

        --
        Dosen sind silbern
        1. @@Rolf B

          Abgesehen von Template-Libraries kannst Du auch die Template-Strings aus ECMAScript 2015 verwenden, verlierst dann aber den Support für den Internet Explorer.

          […] Man kann noch einiges in diesem Script durch moderne Syntax ersetzen (Template-Strings, Arrow-Functions für den forEach Callback)

          … verlierst dann aber den Support für den Internet Explorer.

          Die handgemachte, aber übersichtlichere Lösung ist, das template nicht in einer Zeile zusammen zu bauen, sondern schrittweise als Array, das man am Ende mit join('') verklebt.

          Wirklich? Ich würde sagen: die übersichtlichere Lösung ist, das template-Element zu verwenden.

          LLAP 🖖

          --
          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory