Webprogrammierung — 10. Lektion

Aktionen auf Tastaturereignisse

Zur textuellen Interaktion mit dem Nutzer werden Eingabefelder genutzt, wie sie bei Formularen auftreten. Dabei kann man ein Eingabefeld direkt in dem betreffenden Element mit einer Aktion bei einem Ereignis verknüpfen oder man stellt die Verknüpfungen in einer Funktion her, die nach Laden des Dokumentes ausgeführt wird. Die Auswertung von Eingaben kann auch über mehrere Eingabefelder hinweg erfolgen. Dazu folgen Beispiele im Abschnitt zum Auswerten eines Formulars.
Im Zusammenhang mit einem Textfeld gibt es verschiedene Ereignisse. Ein Ereignis davon tritt ein, wenn eine Eingabe abgeschlossen wird (durch Enter bei einem einzeiligen Textfeld oder durch Verlieren des Fokus). Direkt am Eingabefeld wird eine Aktion über das Attribut onchange definiert. Über die Variable value wird auf den Inhalt des Textfeldes zugegriffen. In folgendem Beispiel wird nach einer abgeschlossenen Eingabe in das Textfeld der Inhalt des Bereiches mit der ID gruss erneuert. Die Funktion html() unterscheidet sich von text() dadurch, dass die übergebene Zeichenkette als HTML interpretiert wird (bei text('<h1>Hallo</h1>') werden die Tags ausgegeben und wirken nicht). Das Attribut autofocus bewirkt, dass dieses Eingabefeld nach dem Laden den Fokus erhält, so dass man nicht erst in das Feld klicken muss, um etwas einzugeben. Dies funktioniert jedoch in dem verwendeten Inline Frame nicht (Beispieldatei in einem eigenen Tab laden, um den Effekt zu sehen).
Wenn die auszuführende Aktion mehr als eine Anweisung umfasst, sollte man eine Funktion schreiben und diese aufrufen. In folgendem Beispiel gibt es nach dem Gruß noch einen weiteren Bereich, der am Anfang nicht zu sehen ist und erst aufgedeckt wird, wenn ein Name eingegeben worden ist.
Im folgenden Beispiel geht es um ein mehrzeiliges Textfeld, in das eine Nachricht mit maximal 400 Zeichen eingetragen werden darf. Damit der Nutzer nicht selbst mitzählen muss und nicht vom plötzlichen Ende überrascht wird, soll angezeigt werden, wie viele Zeichen er noch eingeben darf. Diese Anzeige muss zweckmäßigerweise nach jedem Tastendruck aktualisiert werden. Eine Aktion, die bei jeder einzelnen Tastatureingabe ausgeführt wird, ist im Attribut oninput anzugeben. In der Funktion wird erst das Attribut maxlength von dem Textfeld ausgelesen, davon die Länge der aktuellen Eingabe abgezogen (value der Eingabe wird an Fuktion count übergeben und landet dort auf dem Argument s; die Länge steht auf s.length) und diese Zahl dann im Text (im Zeilenabschnitt mit der ID anz) angezeigt. Die Maximallänge sollte nur an einer Stelle in der Datei stehen, da es sonst bei Änderungen leicht zu Inkonsistenzen kommt (weil man vielleicht nicht an allen Stellen die Änderung vornimmt). Für alle anderen Stellen im Dokument sollte dann auf diese Stelle zurückgegriffen werden. Das ist hier mit dem Attribut maxlength des Textfeldes realisiert. Die Funktion zum Ermitteln der restlichen Anzahl benötigt diesen Wert und am Anfang soll die Anzahl auch angezeigt werden. Letzteres ist im Beispiel dadurch gelöst, dass nach Laden des Dokumentes ebenfalls das Attribut maxlength abgefragt und der Wert in den Text hineingeschrieben wird.
Neben den hier vorgestellten Attributen onchange und oninput gibt es noch weitere, z.B. onblur, onfocus, onkeydown, onkeyup, onkeydown
(siehe https://www.w3schools.com/js/js_events_examples.asp).
Abschließend wird hier noch das letzte Beispiel abgeändert zu einer Variante ohne das Attribut oninput. In dieser Variante wird die Bindung zum Ereignis input erst erzeugt, wenn das Dokument vollständig geladen ist. Allgemein wird mit der Funktion bind für das Element, für das die Funktion aufgerufen wird, bei einem Ereignis (angegeben als erster Parameter) eine Aktion (Funktion als zweiter Parameter) definiert (also Element, Ereignis und Aktion verbunden). Mit $(this) wird das Element ausgewählt, für welches das Ereignis eingetreten ist (der Selektor vor bind könnte auch mehrere Elemente einer Klasse oder eines Typs ausgewählt haben und nicht nur eines wie hier im Beispiel); mit der Funktion val() wird der Wert (value) des Elementes abgefragt.

Formular auswerten

Andere Eingabemöglichkeiten als Textfelder werden im Allgemeinen in Formularen verwendet. Bevor Daten an einen Server übertragen werden, findet häufig eine Plausibilitätsprüfung beim Client statt. Manche Eingaben können bereits mit HTML-Mitteln überprüft werden (z.B. durch Verwenden der Attribute required und pattern oder durch Nutzen unterschiedlicher Typen wie time, date, email). Bei Abhängigkeiten mehrerer Eingaben untereinander funktioniert dies jedoch nicht. Mit JavaScript eröffnen sich aber auch dafür neue Möglichkeiten. Hier können wir allerdings auch nur einen kleinen Ausschnitt zeigen.

Zahleneingabe

Im ersten Beispiel sollen zwei vom Nutzer eingegebene Zahlen addiert werden. Eingaben sind immer Zeichenketten. Eine Operation mit + würde also die Aneinanderreihung von Zeichenketten sein, nicht die Addition von Zahlen. Für letzteres müssen die Eingaben erst in Zahlen umgewandelt werden. Dies geschieht mit den Funktionen parseInt() für ganze Zahlen und parseFloat() für Gleitkommazahlen. Die Arbeitsweise der Funktionen ist beschrieben auf den Seiten https://www.w3schools.com/jsref/jsref_parseint.asp bzw. https://www.w3schools.com/jsref/jsref_parsefloat.asp. Vor der Umwandlung wird im Beispiel überprüft, ob beide Eingabefelder etwas enthalten. Falls eine Eingabe fehlt, wird diesem Eingabefeld der Fokus gegeben.

Teil-Zeichenketten

Im nächsten Beispiel soll die kleinste Differenz zweier vom Nutzer eingegebener Zeiten berechnet werden. Dazu werden die Zeichenketten der Eingaben in natürliche Zahlen für die Stunden und Minuten umgewandelt, die Differenz ausgerechnet (die zweite Zeit wird als später, möglicherweise am nächsten Tag, angenommen), und als Uhrzeit ausgegeben. Vor der Umwandlung wird überprüft, ob beide Eingabefelder etwas enthalten. Falls eine Eingabe fehlt, wird diesem Eingabefeld der Fokus gegeben.

Auswahlfelder

Im abschließenden Beispiel wird gezeigt, wie auf die Daten von Auswahlelementen (Einfachauswahl, Mehrfachauswahl, Drop-Down-Menüs) zugegriffen wird.

Einfachauswahl

Zusammengehörende Eingabe-Elemente einer Einfachauswahl (Radiobuttons) haben den gleichen Wert des Attributes name. Mit dem Selektor
input[name="Wert"]
werden alle input-Elemente mit dem angegebenen name-Attribut ausgewählt. Auf ein spezielles Element kann man mittels
$('input[name="Wert"]')[Index]
zugreifen. Dabei hat das erste Element den Index 0. Der Wert des Attributes value eines solchen Elementes steht auf der Variablen value. Auf der Variablen checked steht, ob das jeweilige Element angeklickt wurde:
$('input[name="Wert"]')[Index].value
$('input[name="Wert"]')[Index].checked
Man kann auch auf das angeklickte Element direkt zugreifen, ohne sich durch die Liste durcharbeiten zu müssen. Gemeinsam mit der Pseudoklasse checked wird jenes Element ausgewählt, das angeklickt ist (falls eines angeklickt ist). Somit liefert der Aufruf
$('input[name="Wert"]:checked').val()
jenen Wert, den das Attribut value des angeklickten Elementes hat, oder undefined, falls kein Element angeklickt ist.

Mehrfachauswahl

Wie bei einer Einfachauswahl haben zusammengehörende Eingabe-Elemente einer Mehrfachauswahl (Checkboxen) den gleichen Wert des Attributes name. Mit dem Selektor
input[name="Wert"]
werden alle input-Elemente mit dem angegebenen name-Attribut ausgewählt. Auf ein spezielles Element kann man mittels
$('input[name="Wert"]')[Index]
zugreifen. Dabei hat das erste Element den Index 0. Der Wert des Attributes value eines solchen Elementes steht auf der Variablen value. Auf der Variablen checked steht, ob das jeweilige Element angeklickt wurde:
$('input[name="Wert"]')[Index].value
$('input[name="Wert"]')[Index].checked
Der Aufruf
$('input[name="Wert"]:checked').val()
liefert im Falle von Mehrfachauswahl nur vom ersten angeklickten Element den Wert des Attributes value (oder undefined, falls kein Element angeklickt ist). Um die Werte aller angeklickten Elemente zu erhalten, muss man alle Elemente durchgehen und die Werte aufsammeln. Dazu kann man die Funktion each verwenden:
$('input[name="Wert"]:checked').each(function(){Anweisungen});
Damit wird über die Folge iteriert und für jedes einzelne Element die angegebene Funktion ausgeführt. Innerhalb der Funktion kann man mittels $(this) auf das aktuelle Element zugreifen. Eine Möglichkeit, die jeweiligen Werte abzuspeichern und später auf verschiedene Weise zu nutzen, ist, sie in einem Feld (Array) abzulegen. Mit der Anweisung
var k=[];
wird eine Variable k deklariert und mit einem leeren Feld initialisiert. Mit den Funktionen push und pop wird ein Wert in das Feld am Ende hineingeschrieben bzw. das letzte Element aus dem Feld gelöscht. Ein Hilfsmittel, um die gespeicherten Werte anzuzeigen, ohne das Feld selbst zu durchlaufen, ist die Funktion join. Sie setzt die Elemente des betreffenden Feldes zu einer Zeichenkette zusammen, wobei je zwei Elemente durch die der Funktion join übergebenen Zeichenkette getrennt werden. Auf der Variablen length steht die Länge des Feldes (die Anzahl der Elemente). Zum Durchlaufen eines Feldes gibt es neben den JavaScript-Schleifen (for usw.) auch eine Möglichkeit mit jQuery: Mittels
$.each(Feld,Funktion);
wird über das angegebene Feld iteriert und bei jedem Eintrag die angegebene Funktion ausgeführt. Der Funktion werden der aktuelle Index und der Wert des Feldelementes an der aktuellen Stelle übergeben. Ein Beispiel zum Anzeigen aller Einträge im Feld k mit ihrem Index:
$.each(k,function(index,wert){ alert(index + ":" + wert); });

Drop-Down-Menü

Ein Auswahlmenü wird über ein select-Element realisiert, in dem option-Elemente die einzelnen Optionen anzeigen. Das Auswahlmenü sollte einen Namen (Attribut name) haben, um auf die getroffene Auswahl zuzugreifen (auch wenn es über die ID möglich ist, ist das name-Attribut spätestens dann nötig, wenn Daten an einen Server gesendet und dort ausgewertet werden). Mittels
$('select[name="Wert"] option:selected')
wird das Auswahlmenü mit dem angegebenen Namen ausgewählt und dann auf die ausgewählen Optionen eingeschränkt (eine Angabe von option:selected allein liefert alle ausgewählten Optionen auf der Seite ohne Berücksichtigung des Menüs). Beim Durchlaufen aller ausgewählten Optionen (mit each) kann wieder mittels $(this) auf die jeweilige Option zugegriffen werden. Die Funktion val() liefert den bei value angegebenen Wert; die Funktion text() liefert den Text, der innerhalb des option-Elementes steht (also dem Nutzer im Menü angezeigt wird).

Im Beispiel sind alle Auswahlmöglichkeiten implementiert. Mit den Knöpfen am Ende wird das Formular ausgewertet oder auf die Anfangssituation zurückgesetzt. Zu jedem Auswahlbereich gibt es eine (am Anfang leere) Box, die den Text der Auswertung beinhaltet. Beim Zurücksetzen soll auch die letzte Auswertung verschwinden. Das Zurücksetzen der Auswahl geschieht automatisch, da der Knopf mit der Aufschrift „Neu” vom Typ reset ist. Das Leeren der Auswertungsboxen geschieht, da es im Attribut onclick angegeben ist und deshalb beim Anklicken ausgeführt wird (der Text einer jeden Auswertungsbox wird mit der leeren Zeichenkette überschrieben).

Formulardaten setzen

Mit JavaScript können nicht nur Formulardaten ausgelesen, sondern auch gesetzt werden. In dem folgenden Beispiel kann man einen Tippschein selbst ausfüllen oder zufällig ausfüllen lassen. Außerdem kann man eine Ziehung von Zahlen simulieren lassen und bekommt angezeigt, wie viele Zahlen richtig getippt waren. Neben dem Setzen von Formulardaten werden in diesem Abschnitt auch Zufallszahlen behandelt. Mit
Math.random()
erhält man zufällig eine Gleitkommazahl im Intervall [0,1) (die 0 ghört dazu, die 1 nicht). Die Funktion
Math.floor()
liefert zu einer übergebenen Zahl die größte ganze Zahl, die kleiner oder gleich dem übergebenen Wert ist.
So wie die Variable checked von einem Eingabefeld abgefragt werden kann, kann sie auch mit true oder false belegt werden. Wird zu einem Textfeld die Funktion val() aufgerufen, so erhält man den Inhalt des Eingabefeldes. Wird der Funktion val() jedoch ein Parameter übergeben, so wird das Eingabefeld auf diesen Wert gesetzt und der Wert in dem Eingabefenster automatisch angezeigt.
Mit der Funktion includes() zu einem Feld wird überprüft, ob der übergebene Wert in dem Feld vorkommt. Die Funktion sort() zu einem Feld sortiert das Feld am Ort (danach ist das Feld sortiert). Standardmäßig werden die Werte als Zeichenketten angesehen und es wird aufsteigend alphabetisch (lexikografisch) sortiert. Damit steht die Zahl 10 vor der Zahl 4 (weil '1' vor '4' kommt). Man kann der Funktion sort() jedoch eine Sortierfunktion übergeben, die zwei Parameter a und b erhält und einen Rückgabewert kleiner, gleich oder größer 0 hat. Ist der Rückgabewert kleiner als 0, kommt a vor b. Ist er größer, kommt a nach b. Ist der Rückgabewert gleich 0, werden die Parameter a und b als gleichwertig angesehen.
Um in dem Beispiel nicht nur zufällig anzukreuzen sondern auch ein Textfeld zu füllen, wurden am Anfang sechs Namen festgelegt, von denen einer zufällig ausgewählt wird und auf dem Tippschein eingetragen wird. Die Namen stehen in einem Array namen. Über einen Index von 0 bis (in diesem Falle) 5 in eckigen Klammern wird auf einen Eintrag zugegriffen.