Formulare in Stud.IP

In Stud.IP werden grundsätzlich HTML-Formulare verwendet. Das Stylesheet von Stud.IP bietet die Möglichkeit, dem Formular ein gewisses Standardaussehen aufzulegen. Dadurch fühlt sich ein Formular für die Nutzer immer irgendwie stimmig und optisch passend an.

Uns ist dabei klar, dass Formulare nicht in ein starres Korsett gedrängt werden sollten. Was ist mit Drag&Drop Formularelementen? Was ist mit komplexen Multiselects, die Bilder enthalten sollen? Das sind Spezialfälle, die wir nicht vorhersehen können. Deshalb beschränkt sich das Stylesheet von Stud.IP auf die Grundelemente eines Formulars und versucht diese ansprechend zu gestalten. Für alles, was darüber hinaus geht, muss der Entwickler dann wieder selbst Hand anlegen.

1.  Struktur

<form class="default">
    <section>
        <legend>Grunddaten</legend>
        <label>
            Name des Objektes
            <input type="text">
        </label>
        <label>
            Typ des Objektes
            <select>
                <option>Option 1</option>
                <option>Option 2</option>
                <option>Option 3</option>
            </select>
        </label>
        <label>
            <input type="checkbox">
            Objekt sichtbar schalten
        </label>
    </section>
</form>

Dies ist der grundlegende Aufbau eines HTML-Formulars in Stud.IP. Maßgeblich ist dabei vor allem die Klasse (class) des Formulars. Der Klassenname sollte dabei "default" sein. Diese Klassenname gibt dem Formular überhaupt erst das Aussehen, das es hat.

Darunter kann man eine oder mehrere fieldset-Elemente definieren. Solche Sektionen sollen laut HTML5 verwendet werden, um mehrere Formularelemente zu gruppieren, die zusammen hängen. In Stud.IP bekommt so ein Fieldset einen blauen Rahmen und wird passend eingerückt.

Unterhalb des fieldset-Elementes kann es ein legend-Element geben, das soetwas wie eine Überschrift für die fieldset beinhaltet. Man kann es auch weglassen, aber es sieht meist hübscher aus mit einem legend-Element.

Jetzt kommen meist die eigentlichen Formularelemente, die jeweils durch ein label-Element umschlossen werden. Diese Labels sind enorm wichtig, um das Formular barrierearm zu halten. Denken Sie dabei immer an die Menschen, die zum Beispiel einen Screenreader verwenden, weil sie halb- oder ganz blind sind! Auch diese Menschen können studieren und müssen Stud.IP fast vollumfänglich benutzen können. In der Praxis ist es nicht leicht, sich in einen solchen Menschen mit eingeschränktem Sehvermögen hineinzuversetzen. Aber das müssen Sie als Programmierer auch nicht. Sie müssen nur daran denken: jedes Formularelement wie <input> oder <textarea> muss ein Label haben. Auch ein placeholder-Attribut an einem input-Element ist kein Ersatz für ein Label.

Der Einfachheit halber schreiben Sie die @<label>@s wie oben angezeigt. Nur Radio-Buttons und Checkboxen sollten vor dem Label-Text stehen. Ansonsten steht der Labeltext vor dem Input-Element. Bei komplexen Eingabemöglichkeiten wie Komboboxen oder <input>s in einer Tabelle kann es sinnvoll sein, Label und Input-Element voneinander räumlich zu trennen. Das ist nicht verboten. Mit dem for-Attribut an dem Label können Sie dennoch Label-Text und <input> miteinander verbinden, sodass das Formular trotzdem barrierearm bleibt.

2.  Besonderheiten / Goodies

In Stud.IP haben wir bisher einige besondere Funktionen eingebaut, die einfach nett sind und dem Nutzer die Verwendung des Formulars einfacher machen.

2.1  Dateiauswähler

Es ist leider unmöglich, einen <input type="file">-Dateiauswähler komplett umzustylen, dass er auf allen Geräten gleich aussieht - es sei denn, man lässt ihn verschwinden. Daher haben wir das genau so gemacht! Allerdings braucht es eine weitere CSS-Klasse, um das zu erzeugen. Schreiben Sie dafür solch eine Struktur

<label class="file-upload">
    <input type="file">
    <?= _('Neues Avatarbild hochladen') ?>
</label>

In den meisten Fällen sollte der Dateiwähler dann recht gut aussehen und zu Stud.IP passen. Es wird ein zusätzliches Icon angezeigt und die ausgewählte Datei wird grau daneben angezeigt, damit der Nutzer sieht, ob er/sie irrtümlich eine falsche Datei ausgewählt haben könnte.

2.2  Einklappbare Fieldsets

Nichts ist schlimmer als Unordnung. Gerade in sehr großen Formularen wird es manchmal hektisch. Die Fieldsets geben schon eine gute Ordnung vor. Aber eventuell will man ganze Fieldsets einklappen und erst zeigen, wenn das gewünscht ist. Das geht mit der zusätzlichen Klasse collapsable, die man entweder an das Fieldset hängen kann oder gleich an das ganze Formular, sodass es für alle Fieldsets darin gilt.

<form class="default collapsable">
    <section>
        <legend>Grunddaten</legend>
        <label>
            Name des Objektes
            <input type="text">
        </label>
    </section>
    <section>
        <legend>Erweiterte Daten</legend>
        <label>
            Typ des Objektes
            <select>
                <option>Option 1</option>
                <option>Option 2</option>
                <option>Option 3</option>
            </select>
        </label>
        <label>
            <input type="checkbox">
            Objekt sichtbar schalten
        </label>
    </section>
</form>

2.3  Maximale Textlänge

Sowohl an <textarea> als auch an einem <input> kann man das Attribut maxlength anhängen. Der Browser beschränkt dann die Zeichenanzahl automatisch auf den angegebenen Wert. Stud.IP zeigt rechts unten des Formularelements zudem automatisch die verbleibenden Zeichen an, die einem bei der Eingabe noch bleiben. Die Anzeige der verbleibenden Zeichen kann durch die Angabe der CSS-Klasse no-hint unterdrückt werden.

<input type="text" maxlength="160">

2.4  Horizontale Anordnung

Stud.IP zeig die <label> Elemente und generell fast alles im Formular untereinander an. Das hat den Vorteil, dass wenig Platz in der Breite verwendet wird und das Formular sich sogar auf Smartphones gut benutzbar ist. Der Nachteil ist allerdings, dass man jetzt viel mehr scrollen muss als zuvor. Besonders bei Radio-Buttons mit wenig Text kann das absurd aussehen und nicht gewünscht sein. Bisher bietet Stud.IP dazu lediglich die Möglichkeit, ein Container-Element wie ein <div class="hgroup"> einzubauen. In so einer hgroup werden alle Kindelemente horizontal angeordnet und nicht vertikal wie sonst.

2.5  Einfache Auswahl mehrerer Checkbox-Elemente [data-shiftcheck]

Über das Attribut data-shiftcheck an dem Form-Element kann angegeben werden, dass es möglich sein soll, eine Menge von Checkboxen zu markieren, indem man die erste Checkbox aktiviert/deaktiviert, die Shift-Taste gedrückt hält und die letzte zu markierende Checkbox klickt. Alle Checkboxen zwischen der ersten und der letzten werden dann auf den Status gesetzt, den die letzte Checkbox erhält.

3.  Weitere Möglichkeiten

Nicht mit der CSS-Klasse form verbunden sind folgende Möglichkeiten:

3.1  Bestätigung einer Aktion [data-confirm]

Über das Attribut data-confirm an einem Link, Button oder einem Formular können Sie sich eine Bestätigung der Aktion einholen. Der Wert des Attributes sollte die Frage sein, die dem Anwender gestellt wird.

Beachten Sie, dass dies nicht die serverseitige Validierung der Eingaben ersetzen sollte. Weiterhin ist zu beachten, dass sämtliche Variablen, die in data-confirm gesteckt werden, mit htmlReady() bearbeitet werden müssen.

3.2  Datepicker [data-date-picker, data-time-picker, data-datetime-picker]

Sie können einem <input type="text"> die Möglichkeit geben, einen Datepicker zu bekommen, um Datumsangaben besser eingeben zu können, indem Sie dem Element das Attribut data-date-picker mitgeben. Analoges gilt für Timepicker (data-time-picker) bzw. Datetimepicker (data-datetime-picker).

Bedenken Sie, dass HTML5 dafür eigentlich ein <input type="date"> vorsieht. Dieses Element wäre normalerweise die bessere Alternative. Aber dabei gibt es leider Probleme, dass es in einigen Browsern nicht unterstützt wird. Daher kann man sich noch nicht darauf verlassen, dass die Eingabe auch immer gut funktioniert. Auf keinen Fall sollten Sie eine Kombination aus dem jQuery-Datepicker oben mit <input type="date"> probieren. Bei Browsern, die <input type="date"> verstehen, werden die Datepicker beide auftauchen und den Nutzer komplett verwirren.

Der Wert des Attributs darf leer sein. Sie können aber auch für jedes der date-...-picker-Attribute ein JSON-Objekt als Wert angeben, in welcher Relation dieses Element zu einem anderen Objekt stehen soll. Es kann angegeben werden, ob der Wert des aktuellen Elements kleiner, kleiner gleich, größer gleich oder größer als der eines anderen Elements sein muss. Dies wird bei der Auswahl innerhalb des Pickers dann entsprechend berücksichtigt und die entsprechende Zeitspanne davor/danach ist nicht wählbar. Ebenso werden ungültige Werte in dem verbundenen Element angepasst.

Die entsprechenden Elemente werden durch einen CSS-Selector angegeben. Folgend ein Beispiel für den Beginn der Veranstaltungszeit, welcher zwischen Semesterstart und Semesterende liegen muss:

<label>
    <?= _('Semesterstart') ?>
    <input type="text" name="semester-start" id="semester-start"
           data-datepicker='{"<":"#semester-end"}'>

</label>

<label>
    <?= _('Semesterende') ?>
    <input type="text" name="semester-end" id="semester-end"
           data-datepicker='{">":"#semester-start"}'>
</label>

<label>
    <?= _('Vorlesungsbeginn') ?>
    <input type="text" name="lecture-start" id="lecture-start"
           data-datepicker='
{">="semester-start","<":"#semester-end"}'>
</label>

3.3  Proxy-Elemente [data-proxyfor]

Über das Attribut data-proxyfor an einer Checkbox kann ein CSS-Selector angegeben, der bestimmt, für welche anderen Checkboxen dieses Elements als "Proxy" dienen soll. So können mehrere Checkboxen über eine einzelne aktiviert oder deaktiviert werden.

3.4  Aktivieren/Deaktivieren von Elementen [data-activates, data-deactivates]

Über das Attribut data-activates bzw. data-deactivates an einer Checkbox/Radiobox kann ein CSS-Selector angegeben werden, der bestimmt, welche anderen Element durch den Status dieses Elements aktiviert bzw. deaktiviert werden. data-activates kann auch an ein Select-Element gehängt werden und kann somit ein Element aktivieren sobald ein Wert ausgewählt wurde, der ungleich dem leeren String ist.

An den Elemente, die so aktiviert bzw. deaktiviert werden sollen, kann der Status noch feiner gesteuert werden über das Attribut data-activates-condition bzw. data-deactivates-condition, welche einen CSS-Selector erwarten und den Status nur dann setzen, wenn dieser Selector mindestens einen Treffer hat.

3.5  Vergleich zweier Werte [data-must-equal]

Über das Attribut data-must-equal an einem Element kann sichergestellt werden, dass die Werte in zwei Elementen identisch sind (beispielsweise bei einer Passworteingabe). An das zweite Bestätigungsfeld setzt man das Attribut mit einem CSS-Selector als Wert, der das Element bestimmt, welches identisch sein muss:

<label>
    <?= _('Passwort') ?>
    <input type="password" name="password" id="password">
</label>

<label>
   <?= _('Passwort bestätigen') ?>
   <input type="password" name="password-confirm" data-must-equal="#password">
</label>

3.6  Formsaver (data-confirm)

Mit dem Attribut "data-secure" können Formulare oder Formularelementen durch Anzeige einer Warnung beim Verlassen der Seite geschützt werden, wenn es ungespeicherte Änderungen gibt.

Fügen Sie das Datenattribut "data-secure" zu einem beliebigen "form"- oder "input"-Element hinzu und wenn die Seite neu geladen wird oder der umgebende Dialog geschlossen wird, erscheint ein Bestätigungsdialog.

Es gibt zwei Konfigurationsoptionen für dieses Attribut:

  • always: Sichert das Element unabhängig von seinem Zustand. Wenn ein Formular immer gesichert werden soll, verwenden Sie diese Option. Wenn Sie ein Element von der Sicherheitsprüfung ausschließen möchten, setzen Sie dort den Attributwert auf "false" (aber Sie sollten die Kurzform `data-secure="false"` verwenden).
  • exists: Dynamisch hinzugefügte Knoten können nicht erkannt werden und werden daher niemals berücksichtigt, wenn sich deren Inhalt geändert hat. Geben Sie einen CSS-Selektor an, der präzise alle erforderlichen Elemente identifiziert.

Diese Optionen können als json-kodiertes Array wie dieses übergeben werden:

<form data-secure='{always: false, existiert: "#foo > .bar"}'>

Da Sie aber wahrscheinlich nie beide Optionen gleichzeitig benötigen werden, können Sie entweder nur einen booleschen Wert an das "data-secure" Attribut zum Setzen der Option "always" oder einen anderen Nicht-Objektwert für die Option "exists" verwenden:

<form data-secure="true">
 ist gleichwertig mit
<form data-secure='{always: true}'>

und

<form data-secure="#foo .bar">
 ist gleichwertig mit
<form data-secure='{exists: "#foo .bar"}'>

Letzte Änderung am August 28, 2020, at 09:22 AM von mlunzena.