apfelsine: Keyup Event Syntax Verständnisproblem

Hallo,

ich habe einen Javascript Code für eine Textbox geschrieben. Es geht eigentlich um Autovervollständigung - Es soll eine Dropdownliste mit Suchergebnissen angezeigt werden. Dazu wird ein AJAX POST an den Server gesendet, wo ein C# Controller die Ergebnisliste zurückliefern soll. Leider wird die Funktion im Controller aber nicht aufgerufen. Ich vermute, das Keyup Event wird nicht ausgelöst.

In den Beispielen die ich gefunden habe, gibt es unterschiedliche Herangehensweisen ein Keyup Event an eine Textbox zu koppeln.

In meinem Code funktionieren diese aber nicht und ich verstehe nicht wieso. Es sind JQuery Erweiterungen und ich hab meine Schwierigkeiten dahinter zu steigen, wann das funktioniert.

In meinem Fall funktioniert keins von beiden. Es wäre schön wenn mich jemand aufklären könnte. Ich bin für jeden Tip dankbar.

lg

apfelsine

 $(document).ready()
{
//Version 1
 $("#SelectedStationStart").on("keyup", function(){ 
//... some code
}

//Version 2 
$("#SelectedStationStart").keyup(function () { 
//...
}
}

Mein Code sieht so aus:

<body>
<!--...some code… -->
<!--Javascript hier (siehe  unten)-->
<div id="targetDiv"><input type="text" id="SelectedStationStart" /><input type="hidden" id="StartId" /></div>
</body>
 <script type="text/javascript">
 $(document).ready()
            {
                $("#SelectedStationStart").on("keyup", function(){
                    //$("#SelectedStationStart").keyup(function () {
                    //get value from input textbox
                    var query = $(this).val();
                    //fetch values for searchterm
                    getItems(query);
                });

                function getItems(query) {
                    //handle search from inputfield
                    
                    var postData = {
                        searchvalue: request.term
                    };
                    addAntiForgeryToken(postData);

                    $.ajax({
                        cache: false,
                        type: 'POST',
                        url: '@Url.Action("SelectStation", "TicketSystem")',
                        data: postData,
                        dataType: 'json',
                        success: function (response) {
                            if (response.Data != null) {
                                if ($("#targetDiv") != undefined) {
                                    $("#targetDiv").remove();
                                }
                                data = response.Data;
                                //append data to div
                                $("#targetdiv").append($("<ul id='targetUI'></ul>"));
                                //removing previously added li
                                $("#targetdiv").find("li").remove();
                                //iterate trough list and 
                                $.each(data, function (i, value) {
                                    //stringvalue should be: id;stationname
                                    item = value.split(";");
                                    //on click call method
                                    $("#targetUI").append($("<li id='' onclick='javascript:setStartStation(" + item[0] + ",this)'>" + item[1] + "</li>"));
                                });
                            }
                            else {
                                //if data is null remove all items
                                $("#targetUI").find("li").remove();
                                $("#targetUI").remove();

                            }
                        },
                        error: function (xhr, status, error) {
                            alert(error);
                        }
                    });
                    
                }


                function setStartStation(id, value) {

                    $("#StartId").val = id;
                    $("#SelectedStationStart").val = value;
                    //remove dropdownlist
                    $("#targetUI").remove();
                }
}

</script>

akzeptierte Antworten

  1. Hello,

    ich habe einen Javascript Code für eine Textbox geschrieben. Es geht eigentlich um Autovervollständigung - Es soll eine Dropdownliste mit Suchergebnissen angezeigt werden. Dazu wird ein AJAX POST an den Server gesendet, wo ein C# Controller die Ergebnisliste zurückliefern soll. Leider wird die Funktion im Controller aber nicht aufgerufen. Ich vermute, das Keyup Event wird nicht ausgelöst.

    Das kannst Du z. B. beim Firefox wunderbar mit der Kontroll-Konsole (F12) und der Registerkarte "Netzwerkanalyse" überprüfen.

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es
    Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
    1. Den hab ich schon erfolglos benutzt. Ich bin scheinbar zu doof dafür. Ich sehe da rein garnichts. Haltepunkt in das Event gesetzt. läuft nicht rein . Nichtmal eine kleine Fehlermeldung. Das beantwortet mir aber auch leider nicht die Frage, wo denn nun der Unterschied zwischen den beiden Syntax ist. Beide habe ich in Beispielen die angeblich funktionieren gefunden und keins von beiden funktioniert bei mir. Ich finde die Jquery "Syntax" schwer zu durchschauen.

  2. Tach!

    Dazu wird ein AJAX POST an den Server gesendet, wo ein C# Controller die Ergebnisliste zurückliefern soll. Leider wird die Funktion im Controller aber nicht aufgerufen. Ich vermute, das Keyup Event wird nicht ausgelöst.

    Was hast du bereits unternommen, um deine Vermutungen bestätigt oder widerlegt zu bekommen? Sowohl Browser in ihren Entwickler-Tools als auch C# im Visual Studio haben Debugger an Bord. Damit kann man nachvollziehen, was da konkret abläuft, inklusive möglicher Fehlermeldungen.

    In den Beispielen die ich gefunden habe, gibt es unterschiedliche Herangehensweisen ein Keyup Event an eine Textbox zu koppeln.

    In meinem Code funktionieren diese aber nicht und ich verstehe nicht wieso.

    Kontrolliere, ob der Aufruf des Eventhandler bereits schon nicht stattfindet oder wenn doch, wo genau die Ausführung hängt.

    Es sind JQuery Erweiterungen und ich hab meine Schwierigkeiten dahinter zu steigen, wann das funktioniert.

    Die müssen so funktionieren, wie in deren Dokumentation beschrieben. Zu wissen, was da konkret im Hintergrund stattfindet, ist nicht unbedingt nötig. Du weißt ja auch nicht unbedingt, was der Compiler konkret aus deinem Code erzeugt und wie der Prozessor das dann abarbeitet. Trotzdem kann man funktionierende Programme schreiben.

    In meinem Fall funktioniert keins von beiden. Es wäre schön wenn mich jemand aufklären könnte.

    In erster Linie sollte das der Debugger sein. Bei konkreten Fragen, die sich nicht aus dem Debugging-Vorgang heraus erklären, kannst gern nochmal nachfragen. Aber Debugging ist ein grundlegendes Handwerkszeug eines Programmierers und deshalb möchte ich dir diesen Vorgang und die dabei zu sammelnden Erfahrungen nicht abnehmen. Auch wenn du Fragen zum Debugger/Debugging hast, kannst du die gern stellen.

    dedlfix.

    1. Was hast du bereits unternommen, um deine Vermutungen bestätigt oder widerlegt zu bekommen?

      Wenn der Debugger mir etwas sagen würde, das ich erkennen kann, die Haltepunkte funktionieren nicht. Daraus schließe ich, das es nicht in das Eventhandling läuft.

      aber ich bin wahrscheinlich schon zu lange dran. Ich sehe es nicht. vielleicht bin ich schon blind. Es gibt auch keine Fehlermeldung. Und es erklärt immernoch nicht den Unterschied zwischen beiden Zeilen. Denn sie funktionieren ja nicht.

      1. Was hast du bereits unternommen, um deine Vermutungen bestätigt oder widerlegt zu bekommen?

        ein im Code angebrachtes alert("test") wird nicht angezeigt

         $("#SelectedStationStart").on("keyup", function(){
                            //$("#SelectedStationStart").keyup(function () {
                            //get value from input textbox
                            alert("keyup");
                            var query = $(this).val();
                            //fetch values for searchterm
                            getItems(query);
                        });
        
      2. Tach!

        Was hast du bereits unternommen, um deine Vermutungen bestätigt oder widerlegt zu bekommen? Wenn der Debugger mir etwas sagen würde, das ich erkennen kann, die Haltepunkte funktionieren nicht. Daraus schließe ich, das es nicht in das Eventhandling läuft.

        Es läuft schon viel früher nicht wie geplant. Aber der Reihe nach, aber erstmal eher stichpunkthaft als in ganzen Sätzen: Event wird nicht ausgelöst, Debugger springt nicht bei einem Breakpoint im Eventhandler an. Wird das Setzen des Eventhandlers überhaupt aufgerufen? Breakpoint in die Zeile mit der Zuweisung setzen. Auch kein Anspringen? Der Code wird gar nicht ausgeführt. Aber der <script>-Block wird beachtet? Kontrollausgabe darein schreiben. Wird ausgeführt. Hmm, stimmt was mit dem $(document).ready() nicht?

        Die Antwort darauf lautet ja. Das Hauptproblem ist falsche Syntax, die aber keinen Fehler erzeugt, weil sie formal richtig ist.

         $(document).ready()
        {
          // ...
        }
        

        Du rufst $(document).ready() auf und anschließend hast du einen Block innerhalb der {}-Klammern notiert, der nicht weiter ausgeführt wird. Der Block muss stattdessen der Körper einer Funktion sein, und die musst du mit function() einleiten. Zudem muss diese Funktion als Parameter von ready() übergeben werden.

        $(document).ready(function() {
            console.log( "ready!" );
        });
        

        So muss das Grundgerüst aussehen, damit das was in dem Funktionskörper steht (hier das console.log), zum Zeitpunkt des Document-Ready-Eregnisses ausgeführt wird. Und nun müssen auch die Breakpoints bremsen.

        Und noch ein Punkt: In Javascript ist das Semikolon optional. Das heißt, dass es am Zeilenende in einigen Fällen als implizit vorhanden angenommen wird. Wenn du die {-Klammer nicht in die nächste Zeile geschrieben hättest, hättest du einen Syntaxfehler zu sehen bekommen. Es ist besser, in Javascript den 1TBS-Style zu verwenden, um zumindest eine Fehlerstelle für automatisches Semikolon zu vermeiden.

        dedlfix.

        1. Hi,

          Und nun müssen auch die Breakpoints bremsen.

          brechen. (to break = brechen, to brake = bremsen)

          cu,
          Andreas a/k/a MudGuard

          1. Tach!

            Und nun müssen auch die Breakpoints bremsen.

            brechen. (to break = brechen, to brake = bremsen)

            Ich bremse auch für Breakpoints.

            dedlfix.

          2. Hallo,

            Und nun müssen auch die Breakpoints bremsen.

            brechen. (to break = brechen, to brake = bremsen)

            brechen: to throw up also Punkte hochwerfen

            Gruß
            Kalk

        2. Hi,

          danke, das klärt es auf :-)

          lg apfelsine

        3. Nachtrag zur Info, weil ich dieses kleine Detail wichtig finde und eben auch mich in die Irre geführt hat.

          Das Hauptproblem ist falsche Syntax, die aber keinen Fehler erzeugt, weil sie formal richtig ist.

           $(document).ready()
          {
            // ...
          }
          

          Du rufst $(document).ready() auf und anschließend hast du einen Block innerhalb der {}-Klammern notiert, der nicht weiter ausgeführt wird. Der Block muss stattdessen der Körper einer Funktion sein, und die musst du mit function() einleiten. Zudem muss diese Funktion als Parameter von ready() übergeben werden.

          Ein Test im Browser (Edge und Firefox) ergab, das ein eingefügtes Alert

          $(document).ready() { alert("test");

          in dieser fehlerhaften Funktion dennoch ausgeführt wird. Nur die Funktionalität die mit $(document).ready eigentlich angesprochen werden sollte, die darauf angewiesen ist, das es zur Zeit der Initialisierung geschieht, wird nicht ausgeführt. Was nach deiner Ausführung ja auch Sinn macht :-)

          Also das alert "test" erscheint aber "keyup" wird in dieser Ausführung dann auch nicht angezeigt:

          $(document).ready()
                      {
                          alert("test");
          
                          $("#SelectedStationStart").keyup(function () {
                              //get value from input textbox
                              alert("keyup");
          }}
          
          1. Hallo apfelsine,

            dass der alert kommt, ist logisch. Das Problem wird deutlicher, wenn man den Code noch etwas erweitert.

                $(document).ready()
                {
                    alert("Yahoo!");
                    $("#foo").on("click", function() { /* some handler */ });
                }
            
            1. Aufruf der ready-Funktion auf dem wrapped set um das document Objekt, ohne Übergabe eines Parameters. D.h. du sagst jQuery: Registriere bitte ein NICHTS als ErrorHandler. Ok. Tut es. Fertig. Oh, da fehlt ein Semikolon! Macht nichts. JavaScript verzeiht es Dir (einer der häßlichsten Schwachpunkte von JavaScript, den man ihm selbst im strict mode nicht abgewöhnen kann).
            2. Nun kommt ein Statement-Block, bestehend aus dem Aufruf der alert-Funktion, und einer qQuery Eventregistrierung. Da dieser Block kein if oder so vor sich hat, werden die Statements darin ausgeführt, und zwar genau an der Stelle, wo er geschrieben ist. HTML, dass nach ihm folgt, hat sich der Browser noch keines Blickes gewürdigt. Eine Blockbildung dieser Art ist syntaktisch erlaubt, wenn auch sinnlos in älterem JavaScript. In neuerem JavaScript (ES6) könnte man darin lokale Variablen kapseln (let Befehl).

            D.h. der alert() wird problemlos ausgeführt. Ob die Eventregistrierung funktioniert, hängt davon ab, wo der Script-Block steht. Befindet er sich unterhalb des Elements mit id="foo", funktioniert er. Befindet er sich oberhalb (z.B. im head), liefert $("#foo") ein leeres wrapped set. Eine jQuery-Funktion, die auf einem leeren wrapped set aufgerufen wird, tut einfach gar nichts.

            Rolf

            --
            Mimosen sind grün
          2. Tach!

            Das Hauptproblem ist falsche Syntax, die aber keinen Fehler erzeugt, weil sie formal richtig ist.

             $(document).ready()
            {
              // ...
            }
            

            Du rufst $(document).ready() auf und anschließend hast du einen Block innerhalb der {}-Klammern notiert, der nicht weiter ausgeführt wird. Der Block muss stattdessen der Körper einer Funktion sein, und die musst du mit function() einleiten. Zudem muss diese Funktion als Parameter von ready() übergeben werden.

            Ein Test im Browser (Edge und Firefox) ergab, das ein eingefügtes Alert

            $(document).ready() { alert("test");

            in dieser fehlerhaften Funktion dennoch ausgeführt wird.

            Entschuldigung, mein Fehler. Der Block wird natürlich ausgeführt, nur nicht zum Zeitpunkt des Document-Ready, sondern bereits dann, wenn der Browser den Code parst.

            Nur die Funktionalität die mit $(document).ready eigentlich angesprochen werden sollte, die darauf angewiesen ist, das es zur Zeit der Initialisierung geschieht, wird nicht ausgeführt. Was nach deiner Ausführung ja auch Sinn macht :-)

            Die beiden Funktionen werden angelegt, auch das $("#SelectedStationStart") wird aufgerufen, aber da kein Element mit dieser ID zu dem Zeitpunkt vorhanden ist, kann dem kein Event-Handler angehängt werden. Zumindest gilt das, wenn der fragliche Javascript-Code im Header steht oder von dort referenziert wird und dabei keine Ausführungsverzögerung angegeben ist (defer). Steht er am Dokumentende, sind die HTML-Elemente bereits im DOM vorhanden und der Eventhandler sollte erfolgreich angehängt werden können, auch ohne dass der Document-Ready-Handler funktioniert.

            dedlfix.

            1. Hallo dedlfix,

              highfive - wir haben den Synchronpost minutengenau geschafft 😂

              Rolf

              --
              Dosen sind silbern
  3. Hallo apfelsine,

    $(document).ready(function() {
       //Version 1
       $("#SelectedStationStart").on("keyup", function(){ 
         //... some code
       }
    
       //Version 2 
       $("#SelectedStationStart").keyup(function () { 
         //...
       }
    }
    

    Dazu folgende Verständnishinweise. Beachte auch meine Links in die jQuery API Doku, lesen bildet 😉.

    1. jQuery bietet etliche Varianten an, wie man Code für den Zeitpunkt hinterlegen kann, zu dem das DOM bereit ist. $(document).ready(...) ist eine davon. Wenn Du mit jQuery 3 arbeitest, ist diese Variante allerdings veraltet, bzw. missbilligt („deprecated“), statt dessen soll man den Ready-Handler direkt an die $ Funktion übergeben.
      Und als ob das noch nicht genug wäre, haben die jQuery-Kameraden ab Version 3 noch was GANZ neues eingefüht: Das $.ready Promise - damit kann man das Laden des DOM mit ein paar parallelen Ajax-Requesten ausbremsen.
      Wenn Du den kursiven Teil nicht verstanden hast, ignoriere ihn ;)

    2. Genau wie bei den Ready-Handlern ist auch das Event-Handling in jQuery ein Wirrwarr aus Altlasten und Neubauten. Hier ist eine Übersicht. Wie man sieht, ist die Hälfte deprecated oder removed.
      $(selector).keyup(function) und $(selector).on("keyup", function) sind synonym. .keyup stammt aus jQuery 1.0, .on aus jQuery 1.7. Seit es .on gibt, verweist .keyup nur noch darauf.

    Rolf

    --
    Dosen sind silbern
    1. Das ist super! Danke für das entwirren :-D <3 Du ahnst ja nicht wieviele Textlawinen ich schon gelesen habe.

  4. Ich hatte eine Idee und habe mein Problem in eine einfache HTML Seite verlagert, um zu sehen, ob ich der Wurzel etwas näher komme.

    Offenbar funktionieren grundsätzlich in der Tat beide Aufrufe. Aber nicht, wenn ich sie in die

    **$(document).ready() ** Funktion packe. Vielleicht ein Syntaxfehler… [edit] oder falsche Jquery Version [/edit]

    Danke für eure Antworten, es hat mir geholfen. Ich sitze wohl echt schon zu lange dran.

    <html>
    <head><meta http-equiv="Content-type" content="text/html;charset=UTF-8">
    <link href="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Content/jquery-ui-themes/smoothness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" type="text/css">
     
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/jquery.validate.min.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/jquery-migrate-1.2.1.min.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/public.common.js" type="text/javascript"></script>
    <script src="file:///C:/Daten/Onlinesourcen/NopCommerce_3.90/Presentation/Nop.Web/Scripts/public.ajaxcart.js" type="text/javascript"></script>
    <body>
     <script type="text/javascript">
                
                $(function () {
    
                    /* funktioniert
                    $("#SelectedStationStart").keyup(function () {
                        //get value from input textbox
                        alert("keyup");
                    
                    });*/
    
    				//funktioniert
    				$("#SelectedStationStart").on("keyup", function(){
                        //$("#SelectedStationStart").keyup(function () {
                        //get value from input textbox
                        alert("keyup");
                        var query = $(this).val();
    					alert(query);
                        //fetch values for searchterm
                        //getItems(query);
                    });
    
    				});
    				
    			$(document).ready()
                {
                    **funktioniert nicht???**	
    
    
    			};
    				</script>
    			
    
    
    <div id="targetDiv"><input type="text" id="SelectedStationStart" /><input type="hidden" id="StartId" /></div>			
    </body>
    
    </html>
    
    1. Hallo apfelsine,

      nur mal so als Anregung (auch für andere Leser), es führen viele Wege nach Rom, nur manche schwer, manche leichter. Du nutzt hier ein Monster an Frameworks und vielleicht, kenne ja nicht alle deine Ansprüche, geht es einfacher zu realisieren. Oder für ganz wenige Ansprüche.

      Gruss
      Henry

      1. Ich bin deiner Meinung. In diesem Fall jedoch ist es ist eine nicht ganz kleine Shopanwendung die auf NopCommerce basiert. Mit zahlreichen Plugins und unzählige ineinander verschachtelte Views. Ich hab einfach nur den Header aus der kompilierten Seite kopiert damit es prinzipiell funktioniert. Was davon tatsächlich verwendet wird und von welchem Plugin..... es fehlt mir aktuell die Zeit und der Nerv dem nachzugehen. Vielleicht später. Sicher hätte ich für meinen Test lediglich 2 Zeilen benötigt von den 10 😂