Ankündigung

Einklappen
Keine Ankündigung bisher.

Daten über Ajax im Javascriptformular

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Daten über Ajax im Javascriptformular

    Hey Gemeinde,

    ich habe nach unzähligen Google-Attacken in diversen Foren immer noch keine Lösung für mein Problem gefunden. Ich hoffe ich komme durch Euer Wissen auf einen grünen Pfad.

    Kurz zur Erklärung:
    Ich habe ein Formular welches durch Eingabe einer zuvor selbst gewählten Bezeichnung (Artikelcode o.ä.) im ersten Feld den Rest via Ajax nachlädt. Bedeutet ich gebe im ersten Feld als Beispiel "A123" ein, lädt es den Nettopreis und die Bezeichnung aus mySQL in die zugehörigen Felder. Funktioniert auch super. Nach Eingabe der Menge im entsprechenden Feld gibt es auch über Javascript den Gesamtpreis im letzten Feld aus. Funktioniert auch anstandsfrei. Da ich nicht weiß wieviel Posten der Nutzer am Ende hat, kann er sich über einen Button eine neue Zeile hinzufügen für den nächsten Artikel. Das habe ich über Javascript gelöst. (siehe Quellcode). Mein Problem ist, dass Ajax in der neu erstellten Zeile nichts ausfüllt wenn man im ersten Feld (Code) die Artikelbezeichnung eingibt. Die erste Zeile für den ersten Artiekl ist fixes html, also nicht über Javascript erzeugt. Nur dort lädt Ajax die Daten nach, im per Javascript erzeugten Code nicht. Woran liegt das? Habe ich etwas nicht beachtet?

    Die html:

    HTML-Code:
    <form name="formu" id="formu" action="angeboterstellen.php" method="post">
    <div id='TextBoxesGroup'>
        <div id="TextBoxDiv1">
            <label>Position 1 : </label><input type="text" id="code" name="code" class="form-control" placeholder="Artikel 1" autocomplete="off" >&nbsp;&nbsp;<input type="text" id="bezeichnung1" name="bezeichnung1" class="form-control" placeholder="Bezeichnung" readonly>&nbsp;&nbsp;<input type="text" id="preisnetto1" name="preisnetto1" class="form-control" placeholder="Preis Netto" readonly >&nbsp;&nbsp;<input type="text" id="anzahl1" name="anzahl1" class="form-control" placeholder="Anzahl" >&nbsp;&nbsp;<input type="text" id="gesamt1" name="gesamt1" class="form-control" placeholder="Gesamt Netto" readonly ><div id="error1"></div> 
        </div>
    <script type="text/javascript">
    
    $(document).ready(function(){
    
        var counter = 2;
    
        $("#addButton").click(function () {
    
        if(counter>500){
                alert("Es sind nur 500 Positionen m&ouml;glich.");
                return false;
        }   
    
        var newTextBoxDiv = $(document.createElement('div'))
             .attr("id", 'TextBoxDiv' + counter);
    
        newTextBoxDiv.after().html('<label>Position '+ counter + ' : </label>' + '<input type="text" name="code' + counter + '" id="code' + counter + '" placeholder="Artikel ' + counter + '" >&nbsp;' + '&nbsp;<input type="text" name="bezeichnung' + counter + '" id="bezeichnung' + counter + '" placeholder="Bezeichnung" readonly >&nbsp;' + '&nbsp;<input type="text" name="preisnetto' + counter + '" id="preisnetto' + counter + '" placeholder="Preis Netto" readonly >&nbsp;' + '&nbsp;<input type="text" name="anzahl' + counter + '" id="anzahl' + counter + '" placeholder="Anzahl" >&nbsp;' + '&nbsp;<input type="text" name="gesamt' + counter + '" id="gesamt' + counter + '" placeholder="Gesamt Netto" readonly ><div id="error' + counter + '"></div>');
    
        newTextBoxDiv.appendTo("#TextBoxesGroup");
    
    
        counter++;
         });
    
         $("#removeButton").click(function () {
        if(counter==1){
              alert("Es sind keine Positionen mehr zum Löschen vorhanden.");
              return false;
           }   
    
        counter--;
    
            $("#TextBoxDiv" + counter).remove();
    
         });
    
         $("#getButtonValue").click(function () {
    
        var msg = '';
        for(i=1; i<counter; i++){
             msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
        }
              alert(msg);
         });
      });
    </script>
    </div>
    <input type='button' value='Position hinzuf&uuml;gen' id='addButton'>
    <input type='button' value='Position entfernen' id='removeButton'>
    </form>
    <?php
    include("js/ajax.php");
    ?>
    Die ajax.php:

    HTML-Code:
    <script>
     $(document).ready(function(){
        $('#code').on("keyup",function(){
                var code = $("#code").val();
    
                if(code==="")
                {
                    $("#error1").html("Feld verpflichtend");
                    $("#posten1").trigger("reset");
                    return false;
                }
                    else
                {
                    $("#error1").html("");
                    $.ajax({
                           url:"stmmaction/stmmaction1.php",
                           method:"POST",
                           data: {code:code},
                           success:function(data)
                           {
                               var fdata=$.trim(data);
                               var sp=fdata.split(",");
                               $("#bezeichnung1").val(sp[1]);
                               $("#preisnetto1").val(sp[2]);
                               $("#preisbrutto1").val(sp[3]);
                               $("#lagerbestand1").val(sp[4]);
                           }
                           });
                }
            });
        });
     </script>
    <script>
      $(document).ready(function(){
        $('#code2').on("keyup",function(){
                var code2 = $("#code2").val();
    
                if(code2==="")
                {
                    $("#error2").html("Feld verpflichtend");
                    $("#posten2").trigger("reset");
                    return false;
                }
                    else
                {
                    $("#error2").html("");
                    $.ajax({
                           url:"stmmaction/stmmaction2.php",
                           method:"POST",
                           data: {code2:code2},
                           success:function(data)
                           {
                               var fdata=$.trim(data);
                               var sp=fdata.split(",");
                               $("#bezeichnung2").val(sp[1]);
                               $("#preisnetto2").val(sp[2]);
                               $("#preisbrutto2").val(sp[3]);
                               $("#lagerbestand2").val(sp[4]);
                           }
                           });
                }
            });
        });
     </script>
    
    ....und so weiter.

    Die stmmaction2.php:

    HTML-Code:
    <?php
        session_start();
        $connect = mysqli_connect("localhost", "main", "*********", "main");
    
        $code = $_POST["code2"];
    
                    $query = "SELECT * FROM `datensatz` WHERE code = '$code' ";
                    $result = mysqli_query($connect, $query);
                        while($erg = mysqli_fetch_assoc($result))
                            echo $erg["code"] . "," . $erg["bezeichnung"] . "," . $erg["preisnetto"] . "," . $erg["preisbrutto"] . "," . $erg["lagerbestand"];
    ?>
    Wie bereits erwähnt funktioniert die Konstruktion ja bereits, jedoch nur im fixen html-Teil.

    Am Ende möchte ich es noch so gestalten, dass ich nicht für jeden Artikel ein Script haben möchte, da ich ja selbst nicht weiß wieviel Artikel der Nutzer anlegen möchte. Hinweise auf Anfängerfehler sind gern willkommen, ich bin Neuling auf diesem Gebiet.

    Danke vorab

  • #2
    Mein Problem ist, dass Ajax in der neu erstellten Zeile nichts ausfüllt wenn man im ersten Feld (Code) die Artikelbezeichnung eingibt. Die erste Zeile für den ersten Artiekl ist fixes html, also nicht über Javascript erzeugt. Nur dort lädt Ajax die Daten nach, im per Javascript erzeugten Code nicht. Woran liegt das? Habe ich etwas nicht beachtet?
    kann das am deinem event listener liegen? hö,rt sich so an.

    wobei ich ganz ehrlich auch nicht so richtig durchblicke bei konstrukten wie :
    HTML-Code:
       var code = $("#code").val();
    kann man so infos nicht in einer varibale speichern, oder notfalls in einem data attribut ?
    kann auch dran liegen, dass du überall id verwendest, falls id nicht eindeutig ist.

    wie sieht denn das generirete html aus ?

    Kommentar


    • #3
      Man kann den EventListener erst binden, wenn das Element im DOM vorhanden ist. Du bindest den Listener an code2 schon vorher. Deshalb geht es nicht.

      Das ist aber auch unschön, mann kann EventListener auch an mehrere Elemente binden, z.b. über eine Klasse.

      Kommentar


      • #4
        Zitat von cheeeez Beitrag anzeigen
        Ich habe ein Formular welches durch Eingabe einer zuvor selbst gewählten Bezeichnung (Artikelcode o.ä.) im ersten Feld den Rest via Ajax nachlädt. Bedeutet ich gebe im ersten Feld als Beispiel "A123" ein, lädt es den Nettopreis und die Bezeichnung aus mySQL in die zugehörigen Felder. Funktioniert auch super. […] Mein Problem ist, dass Ajax in der neu erstellten Zeile nichts ausfüllt wenn man im ersten Feld (Code) die Artikelbezeichnung eingibt. Die erste Zeile für den ersten Artiekl ist fixes html, also nicht über Javascript erzeugt. Nur dort lädt Ajax die Daten nach, im per Javascript erzeugten Code nicht. Woran liegt das?
        Daran dass du für die erzeugten Zeilen keine EventListener hat: du setzt für die schon bestehende Zeile einen (auch wenn keyup als Event falsch ist, richtig wäre input wobei es nicht unbedingt sinnvoll ist bie jedem Zeichen zu feuern), für die dann erzeugten aber nicht mehr. Am einfachsten wäre wohl Event-Bubbling zu verwenden, also ein EventListener für das übergeordnete Element das auch bei enthaltenen Elementen feuert (welches Element das Event ausgelöst hat lässt sich abfragen). Ob das für input-Events auch funktioniert bin ich mir jetzt nicht sicher, einfach mal ausprobieren.

        Allerdings hat dein Code noch einige Probleme die du zum Teil erst angehen musst:
        1. vergiss jQuery, das ist heutzutage nicht mehr notwendig und kann ersatzlos entfallen (VanillaJS reicht völlig)
        2. deine input-Elemente brauchen eine Beschriftung (nein, placeholder-Attribute sind keine). Ein label-Element hast du zwar immerhin, ohne for-Attribut weiß der Browser aber nicht wozu es gehört.
        3. die input-Elemente mit readonly-Attribut wären wohl gerne output-Elemente
        4. als Name der input-Elemente wäre wohl sowas wie name="code[counter]" besser um es dann serverseitig zu verarbeiten
        5. es gibt keinen Grund Umlaute zu verst&uuml;mmeln
        6. für die einzufügende Zeile würde ich ein template-Element verwenden, dann steht das HTML nicht im JS-Code
        7. die add- und remove-Buttons sollten nicht mehr zu sehen sein wenn sie überflüssig sind (also wenn bereits 500 bzw. 0 Zeilen da sind); alert ist auch wenig geeignet um Fehlermeldungen auszugeben (ein div für Fehlermeldungen hast du doch schon)
        8. warum das split auf die Rückgabe vom Server im Ajax-Request? Lass den Server gleich json zurückliefern
        9. dein PHP-Code ist gefährlich: du behandelst den Kontextwechsel zu SQL nicht
        10. Umkopieren von Werten aus $_POST o.ä. (hier: $code = $_POST["code2"] war schon immer sinnfrei
        11. warum mysqli? PDO ist wesentlich einfacher …
        12. wofür die while-Schleife wenn du nur einen Datensatz erwartest? Zudem solltest du um Blöcke (hier: das was innerhalb der while-Schleife ausgeführt wird) immer geschweifte Klammern setzen

        Kommentar


        • #5
          Vorgesagtem kann man nur zustimmen.

          Immer dann, wenn man anfängt irgendetwas fortlaufend zu nummerieren, sollte man sofort damit aufhören.

          jQuery ist Geschmackssache, aber hierfür wirklich nicht nötig.

          Diese .html() Geschichte würde ich überdenken.

          Nachfolgend mal ein Beispiel zur grundsätzlichen Vorgehensweise.

          Beispiel Datei 'ajaxsample.php'
          Code:
          <?php
          function JsonOut($myMessage){
              header('Content-Type: application/json');
              echo json_encode($myMessage);
              exit;
          }
          function ErrorOut($errorMessage){
              JsonOut(['status' => 'ERROR','message' => $errorMessage]);
          }
          function htmlOut ($val){
            return htmlspecialchars($val, ENT_COMPAT | ENT_HTML5, "UTF-8");
          }
          
          //build some Data
          $myCSV = <<<endCSV
          Matnummer,Bezeichnung
          1214,"Maulschlüssel 14"
          1217,"Maulschlüssel 17"
          1236,"Hydrauliköl"
          1239,"Bitburger Pils"
          endCSV;
          $rows = array_map('str_getcsv', explode("\n", $myCSV));
          $keys = array_shift($rows);
          
          foreach ($rows as $row)
            $myData[$row[0]] = array_combine($keys, $row);
          
          $action = $_POST['action'] ?? '';
          
          if ($action=='searchmat'){
            if (isset($myData[$_POST['matnummer']])){
              JsonOut([
                'status' => 'OK',
                'bezeichnung' => htmlOut($myData[$_POST['matnummer']]['Bezeichnung'])
              ]);
            } else {
              ErrorOut('Materialnummer nicht vorhanden');
            }
          }
          
          if (!empty($_POST)){
            ErrorOut('fehlerhafter Aufruf');
          }
          ?>
          <!DOCTYPE html>
          <html lang="de">
          <head>
            <meta charset="UTF-8">
            <title>Document</title>
            <meta name=viewport content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="https://unpkg.com/bamboo.css/dist/light.min.css">
            <style>
              td:first-of-type{width:150px;}
            </style>
          </head>
          <body>
          <hgroup>
           <h1>Ajax-Test</h1>
           <h2>Positionserfassung</h2>
          </hgroup>
          <table>
            <thead>
              <tr>
                <th>Mat.-Nummer</th>
                <th>Bezeichnung</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>    
          <button>neue Position</button>
          
          <script>
            "use strict";
            const button = document.querySelector('button')
            const tbody = document.querySelector('tbody')
            const matInput = document.createElement('input')
                  matInput.dataset.active = 'false'
            function createNewRow(tbody){
              if (matInput.dataset.active=='false'){
                let newRow = document.createElement('tr')
                let matNr = document.createElement('td')
                let matBez = document.createElement('td')
                newRow.append(matNr)
                matNr.append(matInput)
                newRow.append(matBez)
                tbody.append(newRow)
                matInput.dataset.active='true'
                matInput.focus()
              }
            }
            function hideInput(){
              if (matInput.value=='') {
                matInput.focus()
                return
              }
              let myForm = new FormData()
              myForm.append('action', 'searchmat')
              myForm.append('matnummer', matInput.value)
              fetch ('ajaxsample.php' , {method: 'POST', body: myForm})
              .then( r => r.json())
              .then ( data => {
                let aktTd = matInput.parentElement
                if (data.status == 'OK'){
                  let aktVal = matInput.value;
                  matInput.value=''
                  matInput.dataset.active='false'
                  aktTd.removeChild(matInput)
                  aktTd.innerText=aktVal
                  aktTd.nextElementSibling.innerText=data.bezeichnung
                }
                if (data.status == 'ERROR'){
                  aktTd.nextElementSibling.innerText=data.message
                  matInput.value=''
                  matInput.focus()
                }
              })
              .catch(error => console.log(error))
            }
            button.addEventListener('click', () => createNewRow (tbody) )
            matInput.addEventListener('blur', () => hideInput())
          </script>
          </body>
          </html>

          Kommentar


          • #6
            Zitat von jonas3344 Beitrag anzeigen
            Man kann den EventListener erst binden, wenn das Element im DOM vorhanden ist. Du bindest den Listener an code2 schon vorher. Deshalb geht es nicht.

            Das ist aber auch unschön, mann kann EventListener auch an mehrere Elemente binden, z.b. über eine Klasse.
            oder man bindet den event listener ans parent element

            https://molily.de/js/event-handling-effizient.html

            Kommentar


            • #7
              falscher thread...

              Kommentar

              Lädt...
              X