HTML
-Benutzereingaben
- Benutzereingaben im Web funktionieren über bekannte Bedienelemente
- Vornehmlich Textfelder, allerdings mit zunehmender Spezialisierung
- Gruppiert Eingabeelemente die logisch zusammengehören
- Alle aktiven Kinder-Eingabeelemente eines Formulars werden übertragen
- Gibt Übertragungsmethode vor:
method
-Attribut
HTTP
-Verben GET
und POST
mit unterschiedlicher Semantik
- Gibt Übertragungsziel vor:
action
-Attribut
- Angabe einer
URL
Eingabeelemente
- Typischstes Eingabelemenet ist
<input type="text">
für Tastatureingaben
- Kann anhand des
type
-Attributes für bestimmte Eingaben spezialisiert werden
- Benötigtes Attribut:
name
-
- Unter diesem Namen wird der vom Benutzer eingetragene Wert an den Server verschickt
- Wenn dieses Attribut fehlt, wird der Wert nicht übermittelt
- Hilfreiches Attribut:
value
-
- Ändert sich durch Benutzereingaben
- Kann zur Vergabe von Standardwerten genutzt werden
Texteingaben mit <input type="text">
- Einzeiliges Eingabeelement
- Mögliche Zeilenumbrüche werden vor dem Abschicken entfernt
- Knopf zum Abschicken des Formulars
- Dargestellter Text kann mit dem
value
-Attribut beeinflusst werden
- Nur der Wert des gedrückten Knopfes wird übertragen
- Auch die anderen Knöpfe über einen Namen verfügen sollten, gilt nur einer dieser Knöpfe als aktiv
- Formular überträgt die Eingabeelemente innerhalb des Formulars als Teil der
URL
- Ziel wird durch
action
definiert und soll in diesem Fall die Werte einfach nur ausgeben
- Problem: Das Eingabefeld für Kreditkartennummern hat keinen Namen
- Wird daher nicht übertragen, wird aber dennoch angezeigt
- Ziel
/form
: Nimmt beliebige Parameter entgegen und zeigt Sie in JSON
-Darstellung an
-
- Werte im
query
-Objekt stehen für GET
-Parameter
- Werte im
body
-Objekt stehen für POST
-Parameter
HTML
-Eingabeelemente
- Wesentliche verfügbare Eingabeelemente
- Im Rahmen dieser Vorlesung kein Anspruch auf Vollständigkeit, relevante Elemente sind aber:
- Einige “typische” Bedienelemente fehlen allerdings und müssen mit
HTML
, SVG
und JavaScript nachgebaut werden
-
- Baumartige Strukturen können nicht mit einem
TreeControl
(oder ähnlich) angezeigt werden
- Es gibt keine Visualierungen für Diagramme
- DropDown-Menüs können nur sehr eingeschränkt optisch angepasst werden
- …
- Große Auswahl an Bibliotheken mit Bedienelementen
- Sowohl quelloffen als auch kommerziell
Vergabe von Beschriftungen mit dem <label>
-Element
- Zusammenhang zwischen einem beschreibenden Text und dem beschrieben Bedienelement
- Semantische Beziehung herstellen
-
- Möglichkeit: Herstellung des Zusammenhangs über Eltern-Kind Beziehung
- Ein
<label>
-Element fungiert als Beschriftung für ein Kind-Eingabeelement
-
- Möglichkeit: Herstellung des Zusammenhangs über das
id
-Attribut
- Das referenzierte Element muss über eine
id
verfügen, auf die das <label>
-Element mit dem Attribut for
verweisen kann.
- Auszeichnung mit
<label>
-Elementen erleichert Bedienung
-
- Notwendige Angabe für Screenreader
- Klick auf das
<label>
hebt Eingabeelement hervor
Vergabe von Platzhaltertexten
- Zweck: Beispielhafte Eingabeformate verdeutlichen
- Ersetzen keinesfalls ein beschreibendes
<label>
- Der Text des
placeholder
-Attributs wird bei leerem value
-Attribut angezeigt
- Platzhalter wird keinesfalls übertragen
- Motivation: Benutzer so früh wie möglich auf Fehler hinweisen
- Dank
HTML5
auch ohne JavaScript möglich
- Allerdings: Trotzdem serverseitige Validierung nötig
- Validierung im Browser ist ein Komfortgewinn, keine Sicherheitsmaßnahme
Eingaben als verplfichtend markieren mit required
- Attribut
required
funktioniert auf allen Eingabeelementen
- Verpflichtet den Benutzer zur Eingabe, Formular lässt sich teilweise ausgefüllt nicht abschicken
- Standardmäßige Hervorhebung von nicht (oder falsch) ausgefüllten Feldern
- In vielen Browsern: Kurzer Texthinweis zur Art des Fehlers
- Begrenzung der Eingabelänge mit dem Attribut
maxlength
- Angabe als Ganzzahl, blockiert weitere Eingaben wenn diese Länge erreicht wurde
- Eingabe auf bestimmte Muster beschränken mit dem
pattern
-Attribut
- Angabe eines regulären Ausdrucks
- Vorsicht:
required
häufig immer noch nötig um leere Eingaben abzufangen
pattern
-Attribut wird z.B. für leere Eingaben ignoriert
Numerische Eingaben
- Eingabe über ein
<input>
-Element vom Typ number
-
- Wird in einigen Desktop-Browsern ähnlich wie ein Spinner-Element dargestellt
- Wird bei einigen mobilen Browsern mittels spezieller Eingebamethoden umgesetzt (Zifferntastatur, Ziffernräder, …)
- Angabe von Grenzen mit den Attributen
min
und max
- Beide Grenzen sind inklusiv
- Angabe von vorgeschriebenen Schrittweiten mit
step
- Beschränkt die Eingabe auf Werte, die sich ausgehend vom Minimum mit der Schrittweite erreichen lassen
Datums- und Zeiteingaben
- Datumsangaben (ohne Zeit) mit
type="date"
- Alternativ existiert noch
datetime-local
für Angaben ohne Zeitzone
- Zeitangaben (ohne Datum) mit
type="time"
- Stets ohne Angabe einer Zeitzone
- Keinerlei festgelegte Darstellung
- Lückenhafte Unterstützung auf dem Desktop, gute Unterstützung bei mobilen Geräten
Emails
- Angabe von Emails mit
type="email"
-
- Validiert grundsätzliche Struktur der Adresse, nicht aber tatsächliche Existenz des Postfachs
- Erzwingt keine top level domain,
a@b
ist technisch gesehen eine valide Addresse
- Auf Mobilgeräten: Anpassungen an der virtuellen Tastatur
Farben
- Angabe von Farbwerten mit
type="color"
- Bei unterstützten Browsern: Nutzung eines nicht näher spezifizierten Dialogs
Mehrzeilige Eingaben mit <textarea>
- Anders als
<input>
: Start- und End-Tag notwendig
- Kein
value
-Attribut, enthaltener Text ist der angezeigte und der übermittelte Text
- Vorsicht: Text wird exakt so angezeigt wie er im Quelltext notiert ist
- Inklusive aller einrückungs-bedingten Leerzeichen
- Breite und Höhe bestimmen mit den Attributen
cols
und rows
-
- Müssen ganzzahlige Werte > 0 sein
- Alternativ normal über die
CSS
-Eigenschaften width
und height
- Übertragung des
value
-Attributes erfolgt nur, wenn der Benutzer die Checkbox angewählt hat
- Vorauswahl mit dem leeren
checked
-Attribut möglich
- Das
input
-Element steht nur für das Checkbox-Bedienelement, nicht für Text
- Verwendung eines Labels sinnvoll
1-aus-N-Auswahl mit dem select
-Element
<select>
-Element mit <option>
-Elementen als Kinder
-
- Text im
<option>
-Element wird angezeigt, keine untergeordneten HTML
-Elemente zulässig
- Attribut
value
des <option>
-Elements legt den tatsächlich übertragenen Wert fest
- Identische
name
-Attribute bestimmen aus welchen Gruppen nur ein Element ausgewählt werden darf
- Unterscheidung des gewählten Elements über das
value
-Attribut
Vorschläge für Texteingaben mit <datalist>
- Erweitert 1-aus-N-Auswahl um beliebige Eingaben
- Funktioniert ohne JavaScript
<datalist>
mit <option>
-Kindern wie bei <select>
- Allerdings nur Wertangaben möglich, keine Texte für Benutzer
Übergabe von großen Datenmengen mit POST
-Anfragen
- Problem: Upload von Dateien über die
URL
ist nicht wirklich praktikabel
- De facto limitiert auf 2000 Zeichen
- Daher: Übergabe von Daten im Rumpf einer
POST
Anfrage
- Größenlimitierung erfolgt dann durch den Webserver
- Darüber hinaus:
POST
-Anfragen stehen für Veränderungen
- Im Rahmen des
CRUD
-Zyklus für CREATE
und häufig auch für UPDATE
- Erneutes Problem: In welchem Format sollen die Name-Wert-Paare des Formulars kodiert werden?
- Und wie soll dabei mit binären Daten wie Dateien umgegangen werden?
- Angabe eines Encoding mit dem
enctype
-Attribut des Formulars
-
- Bestimmt auf welche Art und Weise der Browser die Daten überträgt
- “Wie genau sieht der String aus der verschickt wird?”
- Die Standardlösung:
application/x-www-form-urlencoded
- Encoding wie in
URL
s, nur möglicherweise länger
- Für Binärdaten:
multipart/form-data
-
- Encoding in einem textbasierten Format, dass sich dennoch für Binärdaten eignet
- Praktisch Pflicht für Upload von Dateien
Formular mit method="POST"
- Zwei Veränderung im
HTML
-<form>
-Element
-
method
-Attribut des form
-Elements ist nun POST
- Zu Demonstrationszwecken:
action
-Attribut um URL
-Parameter erweitert
- Alle
<input>
-Elemente können unverändert bleiben
- Passende Serialisierung übernimmt der Browser automatisch
- Für weitere
GET
-Parameter: Manuelle Kodierung im action
-Attribut
- Gemischte Übertragung (z.B. individuell je nach
<input>
-Element) nicht möglich
Anlegen von neuen Datensätzen (I)
- Beispiel: Beim Absenden des Formulars neuen Datensatz anlegen und alle Datensätze anzeigen
- Exakt eine Seite und exakt eine Route, reagieren auf
GET
- und auf POST
-Anfragen
- Problem: Neu-Laden der Seite erzeugt einen neuen Datensatz
-
- Grundsätzlich beim tatsächlichen “Neu Laden” (F5)
- Möglicherweise beim Navigieren mit den Vor- und Zurück-Funktionen
-
framework_projects/vorlesung/controller/post-create-v1.js
const fhwWeb = require('fhw-web');
module.exports = {
"index": function(data) {
const ratings = fhwWeb.loadJson("ratings");
const rating = data.request.post.rating;
const name = data.request.post.name;
if (name && name.length > 2 && !isNaN(rating)) {
ratings.push({
"name": name,
"rating": +rating
});
fhwWeb.saveJson("ratings", ratings);
}
return ({
"page": "form-post-create-problem",
"data": {
"ratings": ratings
}
});
}
}
Anlegen von neuen Datensätzen (II)
- Verbesserung: Nutzung einer Umleitung
-
- Eine
GET
-Route mit dem Formular und der Übersicht aller Bewertungen
- Eine
POST
-Route zum Anlegen des Datensatzes, danach Umleitung auf die Ursprungsseite
-
framework_projects/vorlesung/controller/post-create-v2.js
const fhwWeb = require('fhw-web');
module.exports = {
"index": function(data) {
const ratings = fhwWeb.loadJson("ratings");
return ({
"page": "form-post-create-redirect",
"data": {
"ratings": ratings
}
});
},
"create": function(data) {
const ratings = fhwWeb.loadJson("ratings");
const rating = data.request.post.rating;
const name = data.request.post.name;
if (name && name.length > 2 && !isNaN(rating)) {
ratings.push({
"name": name,
"rating": +rating
});
fhwWeb.saveJson("ratings", ratings);
}
return ({
"redirect": "/api/handlebars/post-create/v2"
});
}
}
- Erfordert spezielles Encoding für Binärdaten:
multipart/form-data
-
- Breite Unterstützung von allen Browsern 🙂
- Serverseitige Unterstützung kompliziert 🙄
- Wesentliche Frage für alle Webserver: Wohin mit den Dateien vor der eigentlichen Verarbeitung?
-
- Ablage im Hauptspeicher bei großen Uploads nicht praktikabel
- Ablage im Dateisystem braucht einen dezidierten, sicheren Ort
Framework unterstützt keine Datei-Uploads!
Exkurs: CSS
-Selektoren und Eingabeelemente
- Spezielle Selektoren für einige Eingabeelemente
-
- Pseudo-Klasse
:invalid
für invalide Eingaben
- Pseudo-Klasse
:checked
für selektierte Checkboxen
Spoiler (oder ähnliches) mit der :checked
-Pseudoklasse
-
<div class="spoiler">
<input type="checkbox" id="spoiler-01">
<label for="spoiler-01">
Spoiler Anzeigen
</label>
<div class="text">
Dark Helmet is Lone Star's father's brother's
nephew's cousin's former roommate! 😲
</div>
</div>
-
/* Wird nach der Vorlesung veröffentlicht */