Rolf B: in Textarea strings sammeln, dannach in die Zwischenablage kopieren

Beitrag lesen

Hallo Joachim,

wenn Du auf zentrale Wartung Wert legst, dann solltest Du vielleicht noch etwas länger nachdenken, bevor Du loslegst. Du hast - wie es scheint - für jedes Material den Text, der zum Button / zur Checkbox gehört, und du hast den Text, der in der Doku erscheinen soll. Diese Texte sind nicht die Gleichen, wenn ich mir dein Beispiel zu Anfang anschaue.

Im schlimmsten Fall hast Du pro Checkbox 3 Werte: Eine ID, eine Checkbox-Beschriftung und einen Dokumentationseintrag. Wenn ich dein Eingangsbeispiel anschaue, wäre eine solche Dreiergruppe zum Beispiel "afa2", "flow 2" und "flow a2 lot: 12345". Oder "afa35", "flow a3,5 lot: 34567".

So etwas kann man in einem Objekt speichern:

const materialListe = {
   "afa2":  { label: "flow 2",   text: "flow a2, lot: 12345" },
   "afa3":  { label: "flow 3",   text: "flow a3, lot: 23456" },
   "afa35": { label: "flow 3,5", text: "flow a3,5, lot: 34567" },
   // und so weiter
};

Wenn Du deine Checkboxen (oder Radiobuttons) nach einem einheitlichen Schema im HTML aufbaust, zum Beispiel so:

<label><input type="checkbox" name="afa2"></label>
<label><input type="radio" name="afa47"></label>

dann kann man dafür sorgen, dass die Anzeigetexte aus dem Materialienobjekt automagisch eingesteuert werden. Dazu entfernt man die Texte aus dem HTML und setzt einen leeren span an ihre Stelle:

<label><input type="checkbox" name="afa2"><span></span></label>
<label><input type="radio" name="afa47"><span></span></label>

Man könnte den Span auch weglassen und im JavaScript Text anhängen. Ein Span schafft aber einen klarer definierten Platzhalter für den Text.

Mit einer Prise JavaScript setzt man die Texte ein:

for (let materialElement of materialWähler()) {
   materialElement.element
      .closest("label")
      .querySelector("span").textContent = materialElement.material.label;
}

function* materialWähler(checkedOnly = false) {
   let selektor = "label > input[name]";
   if (checkedOnly)
      selektor += ":checked";

   for (let element of document.querySelectorAll(selektor)) {
      let material;

      if (element.type == "checkbox")
         material = materialListe[element.name];
      else if (element.type == "radio")
         material = materialListe[element.value];
         
      if (material)
         yield { element, material };
   }
}

materialWähler ist als function* definiert, das ist eine Generator-Funktion. Ein Generator kann in einer Schleife eine Liste von Werten zurückgeben, die zum Beispiel in einer (for...of) Schleife verarbeitet werden können. Generatoren sind ungemein praktisch, um Erzeugung und Verarbeitung einer Liste von Werten sauber zu trennen, ohne die Liste dafür zwischenspeichern zu müssen. Mehr dazu im verlinkten Wiki-Artikel.

materialWähler baut zunächst einen CSS Selektor für die gesuchten Input-Elemente auf. Das ist zunächst "label > input[name]", also alle input-Elemente mit einem name-Attribut, die ein label als Elternelement haben. Wird der Funktion true übergeben, wird noch ein :checked hinzugefügt, d.h. nur die Checkboxen oder Radiobuttons ausgewählt, die angehakt sind. Dadurch kannst Du die Funktion wahlweise für alle Inputs oder nur für die gerade ausgewählten Inputs verwenden.

Anhand des erzeugten CSS Selectors sucht materialWähler mittels querySelectorAll die Input-Elemente heraus. Die Zuordnung zum Material unterscheidet sich bei Checkbox und Radiobuttons, weil in einer Gruppe Radiobuttons alle inputs den gleichen Namen haben. Darum wird für Checkboxen über name gesucht und für Radiobuttons über value. Ist es keins von beiden, bleibt material leer. Wurde ein Material zum input Element gefunden, wird ein kleines Objekt aufgebaut, das Element und Material enthält, und per yield bereitgestellt.

Die for...of Schleife im Hauptprogramm durchläuft die vom Generator bereitgestellten Ergebnisse. Jeder Treffer ist ein Pärchen aus Element und Materialdefinition, und nun muss nur noch das span-Element gesucht werden und der Label-Text eingetragen werden. Dafür wird zunächst mit closest zum Label navigiert und von dort mit querySelector zum span.

Später, wenn der "Dokumentation generieren" Button geklickt wird, rufst Du materialWähler(true) auf, gehst die Ergebnisse ebenfalls mit for...of durch und baust die Inhalte der text-Eingeschaft aus der Materialliste zusammen.

Hier das Ganze in einem Fiddle: https://jsfiddle.net/Rolf_b/qb5dtysc/

Rolf

--
sumpsi - posui - obstruxi