SideBarMenu

Modaler Dialog

§

1.  Serverseitige erzeugte Abfragen (createQuestion)

Um einen modalen Dialog zu erzeugen, kann man ganz einfach die Funktion createQuestion() (lib/visual.inc.php) verwenden.

Die Funktion benötigt mindestens 2, maximal 4 Parameter.

1.1  Parameter

  • $question: Der Text, welcher im Dialiog erscheinen soll
  • $approveParams: Link Parameter für den URLHelper im Falle einer positiven Antwort, in der Form array('name' => wert, 'name2' => wert2).
  • [$disapproveParams]: optional, Link Parameter für den URLHelper im Falle einer negativen Antwort. Wird nichts angeben, so wird man bei einer negativen Antwort auf die aktuelle Seite ohne Parameter weitergeleitet.
  • [$baseUrl]: optional, Basis-URL für den URLHelper. Wird z.B. für den Einsatz in Plugins benötigt.

Zurück bekommt man einen String mit fertigem Dialog, den man einfach irgendwo rein-echo-t.

1.2  Beispiel

  1. echo createQuestion('Wollen Sie dies wirklich löschen?', array('delete' => true));

1.3  Screenshot

§

2.  Clientseitige Dialoge (data-dialog") [ab Stud.IP 3.1]

Seit Stud.IP 2.4 gab es bereits die Möglichkeit, Dialoge ohne viel Overhead über die Angabe eines HTML-Attributs zu steuern, allerdings war diese Möglichkeit sehr limitiert und wurde daher zu Stud.IP 3.1 ausgebaut. Die Ziele dahinter sind sowohl ein einheitliches Verhalten von Dialogen innerhalb von Stud.IP als auch eine Erleichterung für den Entwickler. Im Idealfall muss kein JavaScript mehr angefasst werden, um Dialoge zu nutzen. Die einzige Anpassung auf Serverseite ist das Auszeichnen des HTML mit entsprechenden Attributen und das Entfernen des umgebenden Layouts, so dass nur der wirklich relevante Inhalt zurückgegeben wird.

Zu beachten: Vor Stud.IP 3.1 wurde das HTML-Attribut rel="lightbox" verwendet. Dies führte zu invalidem HTML-Code. Mit dem Umbau wurde daher auf das HTML5-Data-Attribut data-dialog umgestellt, welches für zukünftige Entwicklungen ausschliesslich genutzt werden soll. Der alte Mechanismus wird aus Kompatibilitätsgründen noch einige Zeit nach Stud.IP 3.1 unterstützt werden.

2.1  Einbindung

Dialoge können im HTML an den Tags <a>, <button> und <form> über das Attribut data-dialog gesteuert werden. Derart ausgezeichnete Elemente werden bei aktivertem Javascript ihre Inhalte in einem modalen Dialog anzeigen. Die Inhalte werden dabei per AJAX nachgeladen und mittels jQuery UI's Dialog-Widget angezeigt. Auf Serverseite kann ein Aufruf, der aus einem solchen Dialog erfolgte, an dem HTTP-Header X-Dialog erkannt werden.

Sollte bereits ein Dialog geöffnet sein und ein entsprechend ausgezeichnetes Element innerhalb des Dialogs aufgerufen werden, so wird der aktuelle Dialog aktualisiert, man verbleibt also im Dialog.

Zu beachten: In der Rückgabe enthaltene <script>-Tags werden gefiltert und ausgeführt. Dies ist kein Standardverhalten von jQuery UI's Dialog und sollte beachtet werden (auch wenn derartiges Inline-Javascript im Idealfall vermieden und stattdessen auf globale Handler zurückgegriffen werden sollte).

2.2  Parameter

Der Dialog kann über verschiedene Attributangaben oder HTTP-Header gesteuert werden, welche im Folgenden erläutert werden. Dabei gilt, dass die Attributangaben auch beliebig miteinander kombiniert werden können, bspw. data-dialog="title=foo;size=auto;buttons=false".

Titel

Der Titel eines Dialogs ist standardmässig der Inhalt des title-Attributs des zugrundeliegenden Elements (sofern vorhanden) und fällt bei den Tags <a> und <button> auf den Textinhalt des Elements zurück. Der Titel kann über verschiedene Parameter gesteuert werden:

data-dialog="title='Test Titel'"Setzt den Titel auf Test Titel
HTTP-Header X-Title: Test Titel 2Setzt den Titel auf Test Titel 2

Größe

Die Größe des Dialogs ist standardmässig 2/3 der Breite und Höhe und des Browserfensters. Dieser Wert kann über optionale Parameter gesteuert werden, wobei die minimale Größe des Dialogs auf 320x200 Pixel festgesetzt wurde:

data-dialog="width=X"Setzt die Breite des Dialogs auf X Pixel
data-dialog="height=Y"Setzt die Höhe des Dialogs auf Y Pixel
data-dialog="size=XxY"Fasst die Angabe der Breite von X Pixeln und Höhe von Y Pixeln zusammen
data-dialog="size=X"Erzeugt einen quadratischen Dialog mit X Pixeln Breite und Höhe
data-dialog="size=auto"Versucht, die Größe des Dialogs an den geladenen Inhalt anzupassen.

Buttons

Standardmässig enthält jeder Dialog einen Button Abbrechen am unteren Rande des Dialogs, welcher den Dialog schliesst.

Es wird auch versucht, Buttons aus der Rückgabe zu extrahieren, damit diese sich ebenfalls in der Buttonleiste des Dialogs einreihen können. Dabei werden nur die Tags <a> und <button> berücksichtigt, welche entweder direkt mit dem Attribut data-dialog-button ausgezeichnet sind oder sich unterhalb eines Elements befinden, welche mit dem Attribut data-dialog-button ausgezeichnet wurde.

Sowohl Links als auch Formulare können auf diese Weise aufgerufen werden. Dies bedeutet im Besonderen dass, sich auch ein Speichern-Button eines Formulares am unteren Rande des Dialogs befinden kann.

Zu beachten ist, dass ein vorhandener Link/Button mit dem Inhalt Abbrechen mit dem Standardbutton überschrieben wird, welcher den Dialog schliesst. Dieses Verhalten ist gewollt und sollte beim Entwickeln berücksichtigt werden.

Die Buttonleiste kann über die folgenden Mechanismen komplett ausgeschaltet werden, was auch bedeutet, dass die Buttons nicht aus dem zurückgegebenen Inhalt extrahiert werden:

  • data-dialog="buttons=false"
  • HTTP-Header X-No-Buttons

Weitere Optionen

Ein Dialog kann über die folgenden Mechanismen geschlossen werden:

  • data-dialog="close"
  • HTTP-Header X-Dialog-Close

Bei der Auswertung einer Rückgabe kann auch ein Verweis auf eine andere Seite angegeben werden, welche den Dialog verlässt. Dies geschieht über folgenden Mechanismus:

  • HTTP-Header X-Location: <url>
Ab Stud.IP 3.2 stehen die folgenden weiteren Optionen zur Verfügung.

Die den Dialog umgebende Seite kann beim Schliessen des Dialogs automatisch neu geladen werden:

  • data-dialog="reload-on-close"

Der Dialog kann starr eingestellt werden, er kann also in der Größe nicht vom Nutzer verändert werden:

  • data-dialog="resize=false"

Über den HTTP-Header X-WikiLink kann eingestellt werden, zu welcher Seite das im Titel angezeigte Hilfe-Icon verweisen soll:

  • HTTP-Header X-WikiLink: <url>

Der Inhalt des Dialogs kann in sowohl horizontal als auch vertikal zentriert werden:

  • data-dialog="center-content"

Seit Studip 3.4 kann aus der Rückgabe heraus, eine beliebige JavaScript-Funktion aufgerufen werden, welcher der Body des Requests übergeben wird (falls dieser JSON ist, wird er entsprechend umgewandelt). Ist die übegebene JavaScript-Funktion ungültig (nicht definiert oder keine Funktion), so wird ein entsprechender Fehler geworfen.

  • HTTP-Header X-Dialog-Execute: <JS-Funktion, bspw. STUDIP.Foo.bar>

Alternativ kann in diesem Header ein JSON-kodiertes Array mit dem verpflichtendem Eintrag func als Funktionsnamen und dem optionalen Eintrag payload übergeben werden. Dies ist in Situationen notwendig, wo zwar der Dialog aktualisiert werden soll (als HTTML über den Body der AJAX-Response) aber auch über die angegebene Funktion func mittels des gelieferten Payloads Änderungen stattfinden sollen.

  • HTTP-Header X-Dialog-Execute: {func: <JS-Funktion, bspw. STUDIP.Foo.bar>, payload: []}

Über die CSS-Klasse hide-in-dialog können Inhalte gezielt in Dialogen versteckt werden.

Unterstützte Events

Beim Öffnen und Schliessen des Dialogs werden jeweils JavaScript-Events getriggert, um dem Entwickler die Möglichkeit zu geben, das Verhalten der Inhalte dynamisch zu erweitern/ändern.

  • Beim Öffnen wird der Event dialog-open getriggert
  • Beim Öffnen und beim Ändern des Inhalts des Dialogs via AJAX wird der Event dialog-update getriggert
  • Beim Schliessen wird der Event dialog-close getriggert

Beiden Events wird der aktuelle Dialog sowie die Optionen beim Aufruf übergeben. Exemplarischer Beispielcode:

 
  1. (function ($) {
  2.   $(document).on('dialog-open', function (event, parameters) {
  3.     var dialog  = parameters.dialog,
  4.           options = parameters.options;
  5.  
  6.     $(dialog).dialog('title', options.title + ' - adjusted');
  7.   });
  8. }(jQuery));

Beim Laden der Daten über AJAX wird nach dem Laden der Event dialog-load getriggert, welchem die Optionen und das verwendete jQuery-XMLHttp-Request (als xhr) übergeben wird.

Je nachdem, wie der Dialog aufgerufen wurde, erfolgen die Events an unterschiedlichen Stellen:

Wurde der Dialog implizit über das data-dialog-Attribut an einem Element geöffnet, werden die Events an eben diesem Element getriggert, während sie im expliziten/programmatischen Fall am globalen document-Objekt getriggert werden. Eine Ausnahme bildet der Event dialog-update. Dieser wird immer global am document-Objekt getriggert, damit er immer aufgerufen wird - unabhängig davon, ob das auslösende Element vorhanden ist oder nicht.

3.  Clientseitige Dialoge zur Dateneingabe

Dialoge, welche serverseitig zur Eingabe von Daten in Formularen geladen werden, sollen im Fehlerfall eine Fehlermeldung im Dialog anzeigen. Bei erfolgreicher Dateneingabe soll der Dialog geschlossen werden und die Seite, welche im Hintergrund des Dialoges sichtbar ist (und aus welcher der Dialog geladen wurde) neu geladen werden. Um dies zu ermöglichen, müssen folgende Dinge im Quellcode eingebaut werden:

  • Das Formular, welches im Dialog angezeigt wird, muss das data-dialog Attribut besitzen, welches den Wert "reload-on-close" besitzt.
  • Der Dialog wird über einen Link aufgerufen, bei dem ebenfalls das data-dialog Attribut mit dem Wert "reload-on-close" gesetzt ist.
  • In der Aktion im Controller wird im Fehlerfall eine Fehlermeldung via PageLayout::postError (oder PageLayout::postMessage(MessageBox::error())) ausgegeben.
  • Im Erfolgsfall wird in der Aktion im Controller der Header X-Dialog-Close hinzugefügt und nichts gerendert:
<?php
$this->response->add_header('X-Dialog-Close', '1');
$this->render_nothing();

Damit wird das oben beschriebene Verhalten des Dialoges erreicht.

Letzte Änderung am 03.08.2016 15:27 Uhr von strohm. Titelkorrektur: "Serverseitige Dialoge zur Dateneingabe" -> "Clientseitige Dialoge zur Dateneingabe"