dynamisches Rechnungsformular mit vielen Aktionen

wireless-dj

Grünschnabel
Ja, das war ja das bisherige Experiment.
Und für einen Eintrag funktionierte das.

Es sollen ja aber mehrere werden, deswegen mache ich das natürlich wie vorgeschlagen.
Ich verstehe aber noch nicht, was genau nun in der get-article-data.php stehen muss.
Das Template und das Javascript habe ich jetzt in der Hauptdatei, aber mehr ist es dann doch auch eigentlich nicht, oder?
 

Sempervivum

Erfahrenes Mitglied
Was die get-article-data-php betrifft, so brauchst Du die jetzt gar nicht mehr, da deine Lösung ohne Ajax funktioniert.

Das Template und das Javascript habe ich jetzt in der Hauptdatei, aber mehr ist es dann doch auch eigentlich nicht, oder?
Ja, so weit ich das im Moment überblicke, brauchst Du nicht mehr.
 

wireless-dj

Grünschnabel
OK, jetzt bin ich komplett verwirrt.
Wie mache ich das denn jetzt???

Meine bisherigen Ansätze funktionierten ja nur für einen Eintrag -
und das in der feststehenden Tabelle.
Mach ich jetzt auf der Basis weiter, oder mit fetch()?

Wenn ich jetzt die 3 "Positionszeilen" in ein Template schreibe,
dann muss dieses Template sich ja bei jeder Auswahl mit den
neuen Variablen füllen, und an die richtige Stelle in der Tabelle
schreiben.

Code:
<table width="1000" border="1">
    <tr>
        <td>Pos:</td>
        <td>Menge:</td>
        <td>Einheit:</td>
        <td>Artikel:</td>
        <td>MwSt:</td>
        <td>Netto:</td>
        <td>Gesamt:</td>
        <td>Optionen:</td>
    </tr>
    

<? // ----- Hier stehen die Positionen ?>


    <tr>
        <td colspan="8">
            <select  id="tr-select-article" style="textbox" name="">
            <option value="artikel">Artikel wählen:</option>
            <?php

            foreach($artikels as $artikel) {

             echo '<option value="'.$artikel['id'].';'.$artikel['name'].';'.$artikel['kurz'].';'.$artikel['einheit'].';'.$artikel['preis_netto'].';'.$artikel['lang'].' ">'.$artikel['name'].'</option>';
            }

    ?>
    <script>
    $("#tr-select-article").select2();

     /* // Read selected option
      $('#tr-select-article').change(function(){
         let value = $('#tr-select-article').val();
         let parts = value.split(';');
          $('#ArtikelId').val(parts[0]);        // = '.$artikel['id'].'
          $('#ArtikelName').val(parts[1]);        // = '.$artikel['name'].'
          $("#ArtikelKurz").val(parts[2]);        // = '.$artikel['kurz'].'
          $("#ArtikelEinheit").val(parts[3]);    // = '.$artikel['einheit'].'
          $("#ArtikelNetto").val(parts[4]);        // = '.$artikel['preis_netto'].'
          $("#ArtikelLang").text(parts[5]);        // = '.$artikel['lang'].'
      });
     */
    
    
        // Eventlistener für Klick auf den Erstellen-Button registrieren:
        document.getElementById('erstellen').addEventListener('click', event => {
            // ID des Artikels aus dem Eingabefeld lesen:
            let value = $('#tr-select-article').val();
             let parts = value.split(';');
              $('#ArtikelId').val(parts[0]);        // = '.$artikel['id'].'
            // const id = document.getElementById('input-article').value;
            // Jetzt kommt der Teil mit Ajax:
            // Neues FormData-Objekt erzeugen:
            const params = new FormData();
            // ... und die ID, die übertragen werden soll, eintragen:
            params.append('id', id);
            // Parameter mit der Methode POST an das Skript get-article-data.php schicken:
            fetch('temp2.php', {
                method: 'post',
                body: params
            }).then(res => {
                // Die Antwort vom Server ist angekommen,
                // wir werten sie als JSON aus:
                return res.json();
            }).then(data => {
                // data enthält jetzt die dekodierte Antwort vom Server
                // als Javascript-Objekt:
                console.log(data);
                
                // Jetzt das HTML aus dem Template lesen
                // und die Platzhalter durch die Daten vom Server ersetzen
                // wie früher gepostet

                // Und das Ergebnis vor der Tabellenzeile für die Auswahl
                // des Artikels einfügen:
                document.getElementById('tr-select-article')
                    .insertAdjacentHTML('beforebegin', htmlPos);
            });
        });
    </script>
    
     <input type="button" id="erstellen" value="Eintragen"></td>
        
    </tr>
</table>

<template id="tpl-pos">
<tbody>
    <tr>
        <td><input type="text" size="10" id="ArtikelId" name="id" value=""></td>
        <td><input type="text" size="10" id="ArtikelMenge" name="menge" value=""></td>
        <td><input type="text" size="10" id="ArtikelEinheit" name="id" value=""></td>
        <td><input type="text" size="50" id="ArtikelName" name="name" value=""></td>
        <td><input type="text" size="10" id="ArtikelMwSt" name="mwst" value="19"></td>
        <td><input type="text" size="20" id="ArtikelNetto" name="netto" value=""></td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><input type="text" size="50" id="ArtikelKurz" name="kurz" value=""></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><textarea cols="48" rows="6" id="ArtikelLang" name="lang"></textarea></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
</tbody>
</template>
 

Sempervivum

Erfahrenes Mitglied
Nein, das fetch kannst Du jetzt vergessen, da Du ja alle Parameter im value des Select hast.
Im Template nur die Tabellenzeile ohne <body>, sie soll ja in die vorhandene Tabelle eingefügt werden.
Code:
<template id="tpl-article">
    <tr>
        <td><input type="text" size="10" id="ArtikelId" name="id" value="{{artikel-id}}"></td>
        <td><input type="text" size="10" id="ArtikelMenge" name="menge" value="{{menge}}"></td>
        <td><input type="text" size="10" id="ArtikelEinheit" name="id" value="{{einheit}}"></td>
        <!-- In den weiteren Elementen genau so die Platzhalter einfügen -->
        <td><input type="text" size="50" id="ArtikelName" name="name" value=""></td>
        <td><input type="text" size="10" id="ArtikelMwSt" name="mwst" value="19"></td>
        <td><input type="text" size="20" id="ArtikelNetto" name="netto" value=""></td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><input type="text" size="50" id="ArtikelKurz" name="kurz" value=""></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><textarea cols="48" rows="6" id="ArtikelLang" name="lang"></textarea></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
</template>
Und das Javascript nach dem HTML einschl. Template weil die Elemente ja schon zur Verfügung stehen müssen, wenn es ausgeführt wird.
Code:
    <script>
    $("#tr-select-article").select2();

     /* // Read selected option
      $('#tr-select-article').change(function(){
         let value = $('#tr-select-article').val();
         let parts = value.split(';');
          $('#ArtikelId').val(parts[0]);        // = '.$artikel['id'].'
          $('#ArtikelName').val(parts[1]);        // = '.$artikel['name'].'
          $("#ArtikelKurz").val(parts[2]);        // = '.$artikel['kurz'].'
          $("#ArtikelEinheit").val(parts[3]);    // = '.$artikel['einheit'].'
          $("#ArtikelNetto").val(parts[4]);        // = '.$artikel['preis_netto'].'
          $("#ArtikelLang").text(parts[5]);        // = '.$artikel['lang'].'
      });
     */
  
  
        // Eventlistener für Klick auf den Erstellen-Button registrieren:
        document.getElementById('erstellen').addEventListener('click', event => {
              // value des Artikels aus dem Eingabefeld lesen:
              let value = $('#tr-select-article').val();
              // und in seine Bestandteile zerlegen:
              let parts = value.split(';');
              // HTML des Templates ermitteln und Platzhalter ersetzen:
              let htmlArticle = document.getElementById('tpl-article')
                  .replace('{{artikel-id}}', parts[0]),
                  .replace('{{menge}}', parts[1]),
                  // usw. für die weiteren Parameter des Artikels
 
                 // Und das Ergebnis vor der Tabellenzeile für die Auswahl
                 // des Artikels einfügen:
                 document.getElementById('tr-select-article')
                    .insertAdjacentHTML('beforebegin', htmlArticle);
            });
        });
    </script>
 

wireless-dj

Grünschnabel
hmmm..... irgendwas mache ich offenbar komplett falsch.
das DropDown sieht nicht aus, wie bei select2(),
und es passiert auch tatsächlich nichts, wenn ich auf den Eintragen Button klicke.

Was habe ich jetzt vergessen / falsch gemacht?
Wo muss das select2() stehen? In der <tr>-id, oder in der <select>-id?

Code:
<table width="1000" border="1">
    <tr>
        <td>Pos:</td>
        <td>Menge:</td>
        <td>Einheit:</td>
        <td>Artikel:</td>
        <td>MwSt:</td>
        <td>Netto:</td>
        <td>Gesamt:</td>
        <td>Optionen:</td>
    </tr>
   

<? // ----- Hier stehen die Positionen ?>
<script>
             document.getElementById('tr-select-article')
            .insertAdjacentHTML('beforebegin', htmlArticle);
</script>

    <tr>
        <td colspan="8">
            <select  id="tr-select-article" style="textbox" name="">
            <option value="artikel">Artikel wählen:</option>
            <?php

            foreach($artikels as $artikel) {

             echo '<option value="'.$artikel['id'].';'.$artikel['name'].';'.$artikel['kurz'].';'.$artikel['einheit'].';'.$artikel['preis_netto'].';'.$artikel['lang'].' ">'.$artikel['name'].'</option>';
            }
    ?>
   
     <input type="button" id="erstellen" value="Eintragen"></td>
       
    </tr>
</table>
   
<template id="tpl-article">
    <tr>
        <td><input type="text" size="10" id="ArtikelId" name="id" value="{{artikel-id}}"></td>
        <td><input type="text" size="10" id="ArtikelMenge" name="menge" value="{{menge}}"></td>
        <td><input type="text" size="10" id="ArtikelEinheit" name="id" value="{{einheit}}"></td>
        <td><input type="text" size="50" id="ArtikelName" name="name" value="{{name}}"></td>
        <td><input type="text" size="10" id="ArtikelMwSt" name="mwst" value="19"></td>
        <td><input type="text" size="20" id="ArtikelNetto" name="netto" value="{{preis_netto}}"></td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><input type="text" size="50" id="ArtikelKurz" name="kurz" value="{{kurz}}"></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td colspan="3">&nbsp;</td>
        <td><textarea cols="48" rows="6" id="ArtikelLang" name="lang"><? echo ("{{lang}}"); ?></textarea></td>
        <td colspan="3">&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
</template>

 <script>
    $("#tr-select-article").select2();

      /* // Read selected option
      $('#tr-select-article').change(function(){
         let value = $('#tr-select-article').val();
         let parts = value.split(';');
          $('#ArtikelId').val(parts[0]);        // = '.$artikel['id'].'
          $('#ArtikelName').val(parts[1]);        // = '.$artikel['name'].'
          $("#ArtikelKurz").val(parts[2]);        // = '.$artikel['kurz'].'
          $("#ArtikelEinheit").val(parts[3]);    // = '.$artikel['einheit'].'
          $("#ArtikelNetto").val(parts[4]);        // = '.$artikel['preis_netto'].'
          $("#ArtikelLang").text(parts[5]);        // = '.$artikel['lang'].'
      });
     */
   
        // Eventlistener für Klick auf den Erstellen-Button registrieren:
        document.getElementById('erstellen').addEventListener('click', event => {
              // value des Artikels aus dem Eingabefeld lesen:
              let value = $('#tr-select-article').val();
              // und in seine Bestandteile zerlegen:
              let parts = value.split(';');
              // HTML des Templates ermitteln und Platzhalter ersetzen:
              let htmlArticle = document.getElementById('tpl-article')
                  .replace('{{artikel-id}}', parts[0]),
                  .replace('{{name}}', parts[1]),
                  .replace('{{kurz}}', parts[2]),
                  .replace('{{einheit}}', parts[3]),
                  .replace('{{netto}}', parts[4]),
                  .replace('{{lang}}', parts[5])
                  // usw. für die weiteren Parameter des Artikels
 
                 // Und das Ergebnis vor der Tabellenzeile für die Auswahl
                 // des Artikels einfügen:
        });
    </script>
 

Sempervivum

Erfahrenes Mitglied
Da gab es jetzt ein Missverständnis. Mit diesem:
// Und das Ergebnis vor der Tabellenzeile für die Auswahl
// des Artikels einfügen:
meinte ich nicht, dass der Javascript-Abschnitt vor die Tabellenzeile gestellt werden soll sondern ich wollte beschreiben, was diese Skriptzeile tut. Also diese Zeile dort lassen wo sie in meinem Posting steht.
 

wireless-dj

Grünschnabel
Ok, habe ich dann falsch verstanden.
Zuviel zwischen den Zeilen gelesen… ;-)

aber, selbst wenn ich die beiden Zeilen dort lasse,
funktioniert es nicht…

irgendwas scheint bei mir noch verkehrt zu sein…
 

Sempervivum

Erfahrenes Mitglied
Wie / womit rufe ich denn in der Tabelle das Template auf?
Hiermit wird das HTML des Templates gelesen und die Platzhalter darin ersetzt:
Code:
              // HTML des Templates auslesen:
              let htmlArticle = document.getElementById('tpl-article')
                  // und die Platzhalter darin ersetzen:
                  .replace('{{artikel-id}}', parts[0]),
                  .replace('{{name}}', parts[1]),
                  .replace('{{kurz}}', parts[2]),
                  .replace('{{einheit}}', parts[3]),
                  .replace('{{netto}}', parts[4]),
                  .replace('{{lang}}', parts[5])
 
                 // Und das Ergebnis vor der Tabellenzeile für die Auswahl
                 // des Artikels einfügen:
                 document.getElementById('tr-select-article')
                    .insertAdjacentHTML('beforebegin', htmlArticle);
Nachdem das Ganze jetzt im wesentlichen fertig ist, könnte es helfen, wenn ich mir es in Aktion ansehe. Aber das scheint etwas berufliches zu sein und u. U. nicht für die Öffentlichkeit? Sonst könntest Du die URL posten.
 

wireless-dj

Grünschnabel
Das läuft lokal auf meiner Synology....
Dieses Script jetzt ist auch nur ein temp.php, losgelöst von dem Rest.
Es gibt nicht mehr Code - außer das Auslesen der Datenbank....
Ich kann Dir aber eine PN schicken, wenn Du erlaubst?