Jens Arnols: select input Feld per ajax hinzugefügt aber keine daten Übergabe bei Post

Hi,
ich habe ein älteres Java Programm mal wieder aktiviert und habe folgenden Fehler ( bin mir eigentlich sicher das es mal funktionierte ).

Wenn ich das erste Select ändere wird per ajax das 2 ersetzt durch:

<select size="1" name="Daten2" id="select1">  
<option value="H2">Datenneu</option>  
</select>

Wen ich den Speichern Button drücke taucht das 2te Select nicht in den post daten auf (bzw. Firefox > Netzwerkanalyse > Anfrage). Wenn ich ohne Ajax Aufruf (keine Änderung des ersten Select's) den Speicher Butten drücke ist das 2 select in den Post Daten.

Was muss ich machen das das zweite select nach dem laden per ajax und einfügen mit document.getElementById(Where).innerHTML vom Formular erkannt wird. Muss ich noch was Aktivieren oder es anders einbinden ?

<form method='POST' name='testit' action='Index'>  
<select size='1' name='Daten1' id="select0"  >onchange="AJAX('FeldAJAX',this.form.Daten1.value,'Daten')" >  
<option value='D1'>Nr1</option>  
<option value='D2'>Nr2</option>  
</select>
</BR>  
<div id="FeldAJAX">  
<select size='1' name='Daten2' id="select1" >  
<option value="H1">Datenneu</option>  
</select>
</BR>  
<input onclick="senden()" type="button" name="Klickit" value="Speichern">   
</form>  
<SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
function senden() {
    this.testit.submit();  
}  
var http;  
var Where;  
function AJAX(WhereToPrint,Value,Daten)  
{
	Where = WhereToPrint;  
	if (window.XMLHttpRequest)  
	{  
		http = new XMLHttpRequest();  
	} else if (window.ActiveXObject)  
	{  
		http = new ActiveXObject("Microsoft.XMLHTTP");  
	}  
	if (http != null)  
	{  
		http.open("GET", "AJAX?VALUE=" + Value + "&Daten=" + Daten, true);  
		http.onreadystatechange = AJAX_Output;  
		http.send(null);  
	}  
}  
function AJAX_Output()  
{  
	if (http.readyState == 4)  
	{  
		document.getElementById(Where).innerHTML = http.responseText;  
	}  
}  
</SCRIPT>

Danke im voraus für eure Hilfe. Jens

  1. Herzlich willkommen Jens,

    Hi,
    ich habe ein älteres Java Programm mal wieder aktiviert und habe folgenden Fehler ( bin mir eigentlich sicher das es mal funktionierte ).

    Wie Du schon sagst, ist dein JavaScript älter.

    function AJAX(WhereToPrint,Value,Daten)  
     {
     	Where = WhereToPrint;  
     	if (window.XMLHttpRequest)  
     	{  
     		http = new XMLHttpRequest();  
     	} else if (window.ActiveXObject)  
     	{  
     		http = new ActiveXObject("Microsoft.XMLHTTP");  
     	} 
    

    Der Internet Explorer ist glücklicherweise tot und daher kann ActiveX weg!

    Zeit für einen modernen Neuanfang:

    <form method='POST' name='testit' action='Index'>
       <select ... id="select0"  >onchange="AJAX('FeldAJAX',this.form.Daten1.value,'Daten')" >
    

    Funktioniert das onchange nach dem Winkel?

    HTML

    Ich würde das Formular neu aufbauen:

    <form method='POST' name='testit' action='Index'>  
      <select size='1' name='Daten1' id="select0"  >  
        <option value='D1'>Nr1</option>  
        <option value='D2'>Nr2</option>  
      </select>
    
      <select size='1' name='Daten2' id="select1" >  
        <option value="H1">Datenneu</option>  
      </select>
      
      <button type="button" id="Klickit">Speichern</button>   
    </form>  
    

    br und div würde ich weglassen und das Formular mit CSS formatieren.

    Mach doch erst mal ne Pause vom Programmieren und lies diese Kurse durch:

    JavaScript

    Anstelle der onclick- und onchange-Attribute kannst du EventListener verwenden:

    <script>
    document.addEventListener('DOMContentLoaded', function () {
    
      document.testit.addEventListener('change', function (event) {
      ...
    
    	});
    
    
    });
    </script>
    

    Danke im voraus für eure Hilfe. Jens

    Herzliche Grüße

    Matthias Scharwies

    --
    Ich habe heute rausgefunden, dass in das Pizzafach meines Rucksacks auch ein Laptop passt!
    1. @@Matthias Scharwies

      Ich würde das Formular neu aufbauen:

      Vieles richtig, was du sagst, aber …

      <form method='POST' name='testit' action='Index'>  
        <select size='1' name='Daten1' id="select0"  >  
          <option value='D1'>Nr1</option>  
          <option value='D2'>Nr2</option>  
        </select>
      
        <select size='1' name='Daten2' id="select1" >  
          <option value="H1">Datenneu</option>  
        </select>
        
        <button type="button" id="Klickit">Speichern</button>   
      </form>  
      

      … die Formularfelder unbeschriftet zu lassen gibt einen Minuspunkt.

      Alle Formularfelder brauchen eine Beschriftung: möglichst mit label; zur Not mit aria-label, was aber gegen die erste Direktive verstößt.

      <form method='POST' name='testit' action='Index'>  
        <label for="select0">ein Auswahlfeld</label>
        <select size='1' name='Daten1' id="select0"  >  
          <option value='D1'>Nr1</option>  
          <option value='D2'>Nr2</option>  
        </select>
      
        <label for="select1">noch ein Auswahlfeld</label>
        <select size='1' name='Daten2' id="select1" >  
          <option value="H1">Datenneu</option>  
        </select>
        
        <button type="button" id="Klickit">Speichern</button>   
      </form>  
      

      🖖 Живіть довго і процвітайте

      --
      „Ukončete, prosím, výstup a nástup, dveře se zavírají.“
      1. Auch dir liebe Ostern,

        lass doch die Leute mal die Tutorials lesen, anstatt immer den Tüpfelscheisser zu spielen und alles rot zu markieren!

        Herzliche Grüße

        Matthias Scharwies

        --
        Ich habe heute rausgefunden, dass in das Pizzafach meines Rucksacks auch ein Laptop passt!
        1. @@Matthias Scharwies

          lass doch die Leute mal die Tutorials lesen

          Meine Einschätzung: Die hier im Forum Fragenden wollen meist schnelle Antworten auf ihre Fragen, nicht dreiundzwölzig Tutorials lesen und sich die Antworten auf ihre aktuellen Probleme heraussuchen müssen.

          Dass dir die Einschätzung nicht gefällt, macht sie nicht falsch.

          anstatt immer den Tüfelscheisser zu spielen und alles rot zu markieren!

          Ich markiere schlechten Code als schlechten Code – so wie das dafür vorgesehen ist. Wenn dir das Rot nicht gefällt, beschwer dich beim Autor des Stylesheets.

          🖖 Живіть довго і процвітайте

          --
          „Ukončete, prosím, výstup a nástup, dveře se zavírají.“
          1. Hi,

            Danke schonmal für die Antworten.

            ich habe versucht in dem Beispiel da Formular auf das minimale zu reduzieren um das Problem aufzuzeigen, auch daran zu erkennen das ich alles Nötige durch dummy Daten ersetzt habe.

            Ich vermute das das Problem irgendwie durch das ersetzen des select per Ajax das neue selectfeld nicht vom Formular erkannt wird.

            Jens

    2. hi,

      Der Internet Explorer ist glücklicherweise tot und daher kann ActiveX weg!

      Zeit für einen modernen Neuanfang:

      <form method='POST' name='testit' action='Index'>
         <select ... id="select0"  >onchange="AJAX('FeldAJAX',this.form.Daten1.value,'Daten')" >
      

      Funktioniert das onchange nach dem Winkel?

      das Fehlerhafte/zusätzliche > ist mir beim editieren des Artikel dazwischengekommen Sorry.

      HTML

      Ich würde das Formular neu aufbauen:

      <form method='POST' name='testit' action='Index'>  
        <select size='1' name='Daten1' id="select0"  >  
          <option value='D1'>Nr1</option>  
          <option value='D2'>Nr2</option>  
        </select>
      
        <select size='1' name='Daten2' id="select1" >  
          <option value="H1">Datenneu</option>  
        </select>
        
        <button type="button" id="Klickit">Speichern</button>   
      </form>  
      

      br und div würde ich weglassen und das Formular mit CSS formatieren.

      Bei den br's stimme ich dir zu waren nur im code zu meiner Lesbarkeit bei meinem Test. Das div ist natürlich essenziell weil ich das innerhtml diese div's durch Ajax ersetze, womit ich ja derzeit das Problem habe.

      Jens

  2. @@Jens Arnols

    <input onclick="senden()" type="button" name="Klickit" value="Speichern">   
    </form>  
    <SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
    function senden() {
        this.testit.submit();  
    }  
    

    Das macht keinen Sinn, einen Button zum Absenden eines Formulars nicht als Submit-Button zu machen und dann das Absenden des Formulars mit JavaScript nachzubauen.

    Hättest du

    <input type="submit" name="Klickit" value="Speichern">   
    

    geschrieben, hättest du dir die senden()-Funktion gleich sparen können.

    Aber wie es Matthias schon verbessert hatte: für Buttons ist das button-Element da. Warum button besser ist als input, hatte ich mal aufgeschrieben.


    LANGUAGE="JavaScript1.1" war noch nie sinnvoll; kann weg.

    TYPE="text/javascript" ist nicht mehr nötig; kann auch weg.

    Dein Code sieht aus, als wäre er aus verschiedenen Stellen im Web zusammenkopiert. Mal Großschreibung von Element- und Attributbezeichnern und -werten; mal Kleinschreibung. Auch wenn HTML nicht case-sensitiv ist, sollte man das gleich handhaben. Kleinschreibung ist üblich.

    🖖 Живіть довго і процвітайте

    --
    „Ukončete, prosím, výstup a nástup, dveře se zavírají.“
  3. Lieber Jens,

    Wenn ich das erste Select ändere wird per ajax das 2 ersetzt durch:

    <select size="1" name="Daten2" id="select1">  
    <option value="H2">Datenneu</option>  
    </select>
    

    warum? Was genau(!) tust Du da eigentlich(!)? Und warum braucht es AJAX dafür? Kann das Dokument nicht alle Möglichkeiten bereits vorsehen und ohne AJAX-Telefonie das Formular anpassen?

    Es ist problematisch, wenn man innerHTML verwendet, um Formularelemente zu verändern, weil damit die EventListener oder EventHandler verloren gehen.

    Zeig doch mal, was Du wirklich tun willst, dann kann man Dir auch wirklich helfen.

    Liebe Grüße

    Felix Riesterer

    1. Hi,

      die Daten für das 2te select werden aus einer Datenbank dynamisch nachgeladen und sind zu Groß um sie im ersten Aufruf mitzuliefern.

      Wen ich die Zeile z = document.testit einbaue und z debugge sehe ich das nach dem einfügen des innerHTML ein Element weniger vorhanden ist.

      Ich weis das ich mit createElement und dann add das select in Einzelschritten erstellen kann ich würde es aber vorziehen einen html String direkt anzufügen.

      Kann man den EventListener oder EventHandler wieder aufbauen bzw. das neue Ajax beim Einfügen parsen zu lassen.

      Ich weis das es möglich ist mit cloneNode und insertAdjacentElement Formular Elemente so zu kopieren das sie im post erscheinen.

      1. Hallo Jens Arnols,

        das Problem der verlorengehenden Eventlistener hast Du nicht. Zum einen verwendest Du keine Eventlistener, die über addEventListener registriert werden, zum anderen verarbeitest Du für dein Daten2-Select keine Events.

        Ich vermute das das Problem irgendwie durch das ersetzen des select per Ajax das neue selectfeld nicht vom Formular erkannt wird.

        Ich auch. Was Du uns bisher nicht gezeigt hast, ist, wie das HTML-Fragment aussieht, das Du vom Server bekommst und in das FeldAJAX-div einsetzt. Deswegen diese Frage:

        Durch die Zuweisung an innerHTML entfernst Du das alte <select>-Element und erzeugst ein neues. Besitzt dieses neue <select>-Element ein name-Attribut? Dann und nur dann wird es beim nächsten Submit übermittelt.

        Dein JavaScript-Code ist sehr umständlich.

        1. Selbst der Internet Explorer kennt seit Version 10 den XMLHttpRequest (und der IE ist mittlerweile tot und ausgemustert). Daher ist der ActiveX-Fallback hyperfluid.
        2. Der dritte Parameter von open besagt, ob XMLHttpRequest asynchron arbeiten soll. true heißt: Ja, soll er. Und das ist der Default, das kannst Du also weglassen
        3. Die globalen Variablen http und Where brauchst Du, weil Du AJAX_Output als separate Funktion notiert hast. Das geht besser - man kann Funktionen schachteln, wodurch die innere Funktion Zugriff auf alle Variablen der äußeren Funktion hat. Das gilt selbst dann, wenn die innere Funktion als Eventhandler verwendet wird und ihr Aufruf erst erfolgt, wenn die äußere Funktion eigentlich längst beendet wurde. Der Aufrufkontext bleibt aber erhalten. Stichwort zum Nachlesen: Closure.
        function AJAX(WhereToPrint,Value,Daten)  
        {
          let http = new XMLHttpRequest();  
          http.open("GET", "AJAX?VALUE=" + Value + "&Daten=" + Daten);  
          http.onreadystatechange = AJAX_Output;  
          http.send(null);  
        
          function AJAX_Output() {  
            if (http.readyState == 4) {  
              document.getElementById(WhereToPrint).innerHTML = http.responseText;  
            }  
          }  
        }  
        

        Das kann man noch weiter treiben und einen Funktionsausdruck verwenden. Der erzeugt eine anonyme Funktion, die man wie ein ganz normales Objekt herumreichen kann. Achte auf das Semikolon hinter dem }, das ist jetzt wichtig.

        function AJAX(WhereToPrint,Value,Daten)  
        {
          let http = new XMLHttpRequest();  
          http.open("GET", "AJAX?VALUE=" + Value + "&Daten=" + Daten);  
          http.onreadystatechange = function() {
            if (http.readyState == 4) {  
              document.getElementById(WhereToPrint).innerHTML = http.responseText;  
            }  
          };
          http.send(null);  
        }  
        

        Die modernere Variante wäre das fetch-API. Der Internet Explorer kann das nicht - aber wie gesagt, der ist tot. Mit fetch wird AJAX ein Dreizeiler.

        function AJAX(WhereToPrint,Value,Daten)  
        {
          fetch("AJAX?VALUE=" + Value + "&Daten=" + Daten)
          .then(response => response.text())
          .then(html => document.getElementById(WhereToPrint).innerHTML = html);
        }  
        

        Problem bei fetch ist, dass es auf Promises basiert und man die erstmal kapieren muss, bevor man fetch wirklich kapiert.

        Unser Wiki ist bezüglich fetch leider noch sehr schwach bestückt, ich habe es noch nicht geschafft, meine Baustelle dort fertigzustellen. Wenn Du englisch kannst, probier's bei Mozilla.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hi

          Danke für die Tipps ich werde den JS code mal aufräumen.
          Der von Web Server zurückgegebene Text ist:

          <select size="1" name="Daten2" id="select1">
          <option value="H2">Datenneu</option>
          </select>

          1. Hallo Jens Arnols,

            ich habe das gerade mal versucht nachzubauen. Ohne Ajax, einfach nur mit dem HTML in einem String.

            Es gibt keinen Grund, warum korrekt eingesetztes HTML nicht gepostet werden sollte. Der Fehler liegt an der Art, wie Du das einsetzt. Oder das, was Du einsetzt, ist nicht genau das, was Du geschrieben hast.

            Dein Beispiel enthält aber 2 relevante HTML Fehler:

            • Du schreibst </br>. Also ein br End-Tag, das eigentlich ohnehin überflüssig ist, und ein <br> Anfangstag ist nirgends zu sehen. Mein Browser macht ein <br> daraus und das DOM bleibt halbwegs korrekt strukturiert. Was Dein Browser tut, weiß ich nicht. Schreibe nie </br>. Höchstens <br>.
            • Dein FeldAJAX Div hat kein Ende-Tag. Bei mir im jsFiddle führt das zum Untergang, weil sowohl der Submit-Button wie auch das JavaScript dadurch eliminiert weren. Du brauchst ein </div> hinter dem </select>

            Sind das Fehler bei der Übertragung ins Forum? Oder hast Du auf deiner Seite ähnliche Merkwürdigkeiten?`

            Wie sieht das DOM bei Dir aus, nachdem die AJAX-Funktion gelaufen ist? Hast Du das mit den Browser-Entwicklertools (Taste F12 oder Strg++I überprüft? Befindet sich das select-Element nach der Überzeugung des Browsers im Form? Das sind Dinge, die Du debuggen musst. Die Browser-Entwicklerwerkzeuge sind dafür unabdingbar. Heißt natürlich, dass Du mit einem Desktop-Gerät debuggen musst. Android- oder iOS-Browser haben keine Entwicklerwerkzeuge eingebaut.

            Kontrolliere auch das HTML, das bei Dir ankommt. Im Netzwerk-Tab der Entwicklerwerkzeuge siehst Du jeden Serverzugriff. Du kannst Header, gesendete Daten und empfangene Daten genau überprüfen. Nutze diese Tools!

            Rolf

            --
            sumpsi - posui - obstruxi
      2. Lieber Jens,

        Du hast also ein Formular, dessen verkettete Auswahlmöglichkeiten so viele sind, dass Du sie nicht von Anfang an in das Dokument schreiben willst. Können könntest Du schon, aber wollen willst Du nicht. Diese Entscheidung hat selbstverständlich einen Sinn, bedeutet aber auch, dass die dynamische Umgestaltung des Formulars gut überlegt sein will.

        Fragen:

        1. Was genau sendet der Server auf Deinen AJAX-Request als Antwort?
        2. Wonach entscheidet Dein JavaScript, was genau im DOM des Formulars wie geändert werden muss?

        Meiner Vorstellung nach sollte der Server keinesfalls HTML-Code auf den AJAX-Call liefern, sondern besser Rohdaten, anhand derer JavaScript dann passende Elementknoten ins DOM schreibt. Das propagiere ich deswegen, weil nach dem initialen HTML-Dokument, welches der Server an den Browser sendet, aus Sicht des Servers keine Gewähr mehr ist, dass das DOM zur Zeit des AJAX-Calls genau so geblieben ist, wie es der Server im HTML-Dokument ursprünglich vorgesehen hat. Wenn JavaScript das DOM umbauen soll, dann muss auch JavaScript entscheiden, was es in welchem Fall genau tut. Also soll der Server keinen HTML-Code nachsenden, sondern Rohdaten, wie z.B. im JSON-Format. Das könnte dann so aussehen:

        [
          ["id": "abc", "text": "alle benutzten Computer"],
          ["id": "agb", "text": "allgemeine Geschäftsbedingungen"],
          ["id": "xyz", "text": "x oder y, aber nicht z"]
        ]
        

        Wenn Du das nicht mit fetch machen willst, sondern weiterhin an Deinem XMLHttpRequest-Objekt festhalten willst, dann geht das auch. Danach hast Du aber ein Array mit key-value-Paaren, welches Du dazu verwenden kannst, die <option>-Elemente in Dein <select> einzufügen.

        Die dazu notwendigen Umbauten mögen vielleicht lästig sein, dafür aber hast Du ein modernisiertes Script, dessen Funktionsweise Du verstanden hast (und für die Zukunft hoffentlich entsprechend auskommentiert!), und dessen Funktionalität weniger störanfällig ist, weil das serverseitige Script nichts mehr vom DOM verstehen muss.

        Es bleibt nur noch die vielleicht unterschiedliche Performance zwischen dem Setzen der innerHTML-Eigenschaft und dem dynamischen Erzeugen der Elementknoten zu prüfen. Auf leistungsschwächeren Systemen (wie z.B. alten Smartphones) würde sich das schon bemerkbar machen. Aber der Browser muss ja ohnehin Elementknoten erzeugen. Ob er das implizit oder explizit tut, sollte kein Performanceunterschied sein.

        Liebe Grüße

        Felix Riesterer