Nutzungsvorgaben

IFS-Logo Diese Seite ist ein Teil der IsyFact-Standards. Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.

Creative Commons Namensnennung Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.

Java Bibliothek / IT-System

Name Art Version

isy-web

Bibliothek

6.2

Deprecation

Dieser Baustein ist veraltet und wird in einem zukünftigen Release entfernt. Die Inhalte dieser Seite sollten zur Entwicklung neuer Anwendungen nicht mehr berücksichtigt werden. Stattdessen wird empfohlen, Baustein isy-web-angular - Nutzungsvorgaben zu verwenden.

1. Einleitung

Im Dokument Softwaretechnische Architektur ist der Aufbau von IT-Systemen in fünf Komponenten beschrieben. Eine davon ist die Komponente GUI (s. Softwaretechnische Architektur eines IT-Systems (GUI hervorgehoben)).

IFRefArcITSysGUI
Abbildung 1. Softwaretechnische Architektur eines IT-Systems (GUI hervorgehoben)

Die Nutzungsvorgaben bauen auf dem Detailkonzept Web-GUI sowie dem Konzept JSF auf und beschreiben die Umsetzung der GUI-Komponente mit den Technologien JSF und Spring Web Flow. Sie enthalten konkrete, technische Vorgaben, die bei der Umsetzung der GUI-Komponente zu beachten sind. Die folgenden Kapitel verwenden Begrifflichkeiten von JSF und Spring Web Flow, ohne sie zu erklären, und setzen so eine gewisse Vorkenntnis voraus.

Zielgruppe dieses Dokuments sind Entwickler, die sich einen Überblick über den Baustein JSF verschaffen und wissen möchten, wie genau die technische Umsetzung der GUI-Komponente geschieht.

Das Dokument ist in mehrere Teile gegliedert. Zunächst beschreibt es, wie sich der Baustein in eine Anwendung integriert. Danach beschreibt es die Erstellung der GUI-Komponente mit ihren Bestandteilen (Flows, Controller, Models & Views). Es folgen generelle Vorgaben zum Arbeiten mit JSF, insbesondere zu den Themen, die durch andere IsyFact-Bausteine abgedeckt sind (u.a. Fehlerbehandlung und Sicherheit). Diese Vorgaben umfassen sowohl Hinweise zur Programmierung als auch Konfiguration. Es folgt eine detaillierte Beschreibung der bereitgestellten Seiten- und Bedienelemente auf Basis von JSF.

Allgemeine Angaben zur Gestaltung von Oberflächen finden sich im Bedienkonzept.

2. Benötigte Bibliotheken

Die Bibliothek isy-web enthält alle notwendigen Abhängigkeiten, Spring-Konfigurationen, JSF-Komponenten (Composite Components) sowie zugehörige XHTML-Templates, CSS-, JavaScript-, Bilddateien und Schriftarten zur Erstellung der GUI-Komponente. Sie wird über eine Maven-Abhängigkeit eingebunden. Bei Verwendung des IsyFact-BOMs wird die Version automatisch ermittelt.

Listing 1. Einbindung der Bibliothek isy-web in Maven
<dependency>
   <groupId>de.bund.bva.isyfact</groupId>
   <artifactId>isy-web</artifactId>
</dependency>

Für die Erstellung von Web-GUIs existieren Vorgaben in Form eines Bedienkonzepts. Der Baustein Bedienkonzept legt Anforderungen an die Gestaltung und Nutzbarkeit von Oberflächen fest. Die Bibliothek isy-web enthält die CSS-, JavaScript-, Bilddateien und Schriftarten des Bedienkonzepts zur produktiven Nutzung aufbereitet.

Die CSS-Dateien für eine zum Bedienkonzept konforme Anwendung werden bei Nutzung der Bibliothek isy-web automatisch geladen und eingebunden. Zur anwendungsspezifischen Anpassung der Stylesheets dienen folgende, innerhalb der Anwendung liegende, Dateien:

  • /css/custom-styles.css - spezielle CSS Klassen für die Anwendung,

  • /css/custom-print.css - spezielle CSS Klassen für die Druckansicht der Anwendung.

2.1. Enthaltene Bibliotheken, Plugins und Skripte

Um eine umfassendere Funktionalität zu gewährleisten, muss teilweise zusätzliches JavaScript eingesetzt werden. Diese Skripte dienen beispielsweise zum Styling applikationsspezifischer Bedienelemente, Optimieren der Browser-Kompatibilität oder Erweiterung der Standardinteraktivität. Zu diesem Zweck wurden diverse Plugins mit freier (permissive) Software Lizenz integriert.

jQuery 3.6.0

Bootstrap JS setzt jQuery voraus

Bootstrap JS 3.4.1

Zusätzliche JavaScript-Komponenten für erweiterte Bootstrap-Bedienelemente (affix, alert, button, carousel, collapse, dropdown, modal, popover, scrollspy,tab,tooltip,transition)

Modernizr 2.7.1

Ermöglicht es, herauszufinden, welche Features durch den Browser unterstützt werden und setzt dementsprechende CSS-Klassen. (- Bisher ungenutzt -)

Bootstrap Datepicker 1.8.0

Implementiert einen interaktiven Standard Date Picker

Bootstrap Select 1.13.18

Implementiert eine Auswahlbox

Bootstrap Timepicker 0.3.0

Implementiert einen interaktiven Standard Time Picker

ExtendedBootstrapTab 0.1

Eine erweiterte Version der Bootstrap Tabs, die das Anzeigen der Inhalte aller Tabs innerhalb eines Tabs ermöglicht.

harmonizePanelHeadlineWidth 0.1

Gruppierungs-Container (panel groups) können Toolbars enthalten. Diese wiederum können Funktionen in Form von Icon-Buttons enthalten. Dieses Skript ermöglicht eine vertikale Ausrichtung dieser Buttons innerhalb von verschachtelten Gruppierungs-Containern unabhängig von der Länge der Gruppierungsüberschrift (Label).

infoPanel 0.1

Dieses Skript ermöglicht das Ein- und Ausblenden des optionalen Informationsbereiches auf den Applikationsdetailseiten.

jquery.maskedinput.js 1.4.1

Dieses Plugin unterstützt die Eingabe formatierter Daten (z. B. TT/MM/JJ) in Standard-Eingabefelder. Zur besseren Orientierung werden Platzhalter in Form von Unterstrichen in dem entsprechenden Eingabefeld angezeigt.

Magnific Popup 0.9.9

Dieses Plugin ermöglicht die Verwendung einer Lightbox.

Functions

Dieses Skript enthält eine Sammlung von allgemeinen Funktionen.

3. Erstellung der GUI-Komponente

Die folgenden Abschnitte erklären, wie die GUI-Komponente nach dem MVC-Muster, mit der Erweiterung um Flows, mit dem JSF-Baustein erstellt wird.

3.1. Basis-Konfiguration von JSF

Dieses Kapitel enthält alle notwendigen Basiskonfigurationen für die Verwendung von JSF.

Verwendung der Autokonfiguration

Das Isy-Web-Modul liefert den größten Teil der benötigten Konfiguration für JSF, Spring Webflow und Spring MVC in seiner Autokonfiguration bereits mit. Um darauf zuzugreifen, muss in der Hauptklasse der Anwendung die Autokonfiguration entsprechend aktiviert sein.

Listing 2. Ausschnitt BeispielApplication.java
@Configuration
@EnableAutoConfiguration
public class IsyWebguiApplication extends SpringBootServletInitializer {

}

Um ein deployen als WAR-Archiv auf einem Tomcat zu ermöglichen, erbt die Haupt-Applikationsklasse von SpringBootServletInitializer. Die Autokonfiguration wird enabled. Die genauere Securitykonfiguration wird weiter unten im Abschnitt Sicherheit erklärt.

Abschalten der Ausgabe von Kommentaren

Die Ausgabe von HTML-Kommentaren, die in der Flow-Definition und im View zur Dokumentation der Software eingebettet wurden, wird abgeschaltet.

Konfiguration von Konvertern (faces-config.xml)

Alle Konverter müssen einzeln nach folgendem Muster konfiguriert werden.

Listing 3. Definition eines Konverters
<converter>
	<converter-for-class>java.util.Date</converter-for-class>
	<converter-class>de.msg.terminfindung.gui.util.DateConverter</converter-class>
</converter>
Aktivieren von „Partial State Saving“

Das mit JSF 2.0 eingeführte Feature „Partial State Saving“ muss aktiviert bleiben. Hintergrund ist, dass JSF 2.0 ansonsten im Zusammenhang mit der Replikation der Session die IDs für JSF-Komponenten doppelt vergibt und es dadurch zu Fehlern in der Anwendung kommt.

Konfiguration der Widget-Renderer (faces-config.xml)

Zur Darstellung von Radio Buttons und Checkboxen ohne Labels überschreibt der JSF-Baustein die Standard-Renderer der Bibliothek Tomahawk mit IsyFact-spezifischen Implementierungen.

Listing 4. Konfiguration der IsyFact-spezifischen Renderer
<render-kit>
    <renderer>
        <component-family>org.apache.myfaces.Radio</component-family>
        <renderer-type>org.apache.myfaces.Radio</renderer-type>
        <renderer-class>
            de.bund.bva.isyfact.common.web.jsf.renderer.NoLabelHtmlRadioRenderer
        </renderer-class>
    </renderer>

    <renderer>
        <component-family>org.apache.myfaces.Checkbox</component-family>
        <renderer-type>org.apache.myfaces.Checkbox</renderer-type>
        <renderer-class>
            de.bund.bva.isyfact.common.web.jsf.renderer.NoLabelHtmlCheckboxRenderer
        </renderer-class>
    </renderer>
</render-kit>

3.2. Erstellung der Flows

Für eine GUI-Komponente wird zunächst die Definition des Flows als XML-Datei erstellt. 'WebFlowAutoConfiguration' sucht und findet den Flow selbständig und fügt ihn der Flow-Registry hinzu.

Je nach Seitentyp muss entweder der detailseiteParentFlow oder der applikationseiteParentFlow als Parent-Flow angegeben werden. Die Definition des Parent-Flows muss mit der Wahl der Parent-View (s. Erstellung der Views) aller Views des Flows einhergehen, da Applikations- und Detailseiten unterschiedliche Anforderungen an die Darstellung besitzen. Das Model wird als Variable definiert und damit im Flow erzeugt (hier: auskunftModel). Im Tag on-start wird, falls nötig, der Controller aufgerufen, um das Model zu initialisieren.

Listing 5. Beispiel einer Flow-Datei
<?xml version="1.0" encoding="UTF-8"?>
<flow
  xmlns="http://www.springframework.org/schema/webflow"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/webflow
	  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
  parent="applikationseiteParentFlow"
  abstract="true">

  <!-- Absichern des Flows. -->
  <secured attributes="Auskunft_Nutzen" />

  <!-- Erzeugung der UI-Models. -->
  <var name="auskunftModel" class="de.packagepfad.AuskunftModel" />
  <var name="abcModel" class="de.packagepfad.MeldungWizardModel" />

  <!-- Initialisieren des auskunftModels. -->
  <on-start>
    <evaluate expression="auskunftController.setzeStartseite(auskunftModel)"/>
    <evaluate expression="auskunftController.initModel(auskunftModel)"/>
    <evaluate expression="basisModel.toolbarModel.setAnzeigen(true)"/>
  </on-start>

  <view-state id="auskunftViewState" model="auskunftModel">
    <on-render>
      <evaluate expression="auskunftController.initViewState(auskunftModel)" />
    </on-render>

    <!-- Die verschiedenen Suchen -->
    <transition on="sucheAbc" to="_abcsuche">
      <evaluate expression="auskunftController.fuehreAuskunftDurch(auskunftModel)" />
    </transition>
    <transition on="sucheAbc" to="_abcsuche">
      <evaluate expression="..." />
    </transition>
    ...

  </view-state>
</flow>

Charakteristisch sind hier die folgenden Elemente:

Flow-Tag: Deklariert alle verwendeten Taglibs und Namespaces sowie den Parent Flow. Dieser enthält anwendungsübergreifend einheitliche Vorgaben zu global gültigen Regeln, Fehler-Handler und Layout-Konfigurationen.

Flow-Model: Definition des Models unter Angabe der Model-Bean-Klasse als Flow-Variable.

On-Start-Handler: Das Model sollte immer über die standardisierte Initialisierungsmethode beim Starten des Flows initialisiert werden. Weiterhin können weitere, spezifische Methoden aufgerufen werden, um z.B. Eingabeparameter in das Model einzuarbeiten.

View States: Definieren die Zustände des Flows. Der Name des View-State verknüpft die Komponente auch mit dem gleichnamigen View (z.B. auskunftViewState.xhtml), der automatisch beim Rendern aufgerufen wird. Falls die Komponente mehrere Views (z.B. aufeinanderfolgende Eingabemasken zu einem zu erfassenden Datentyp) verwaltet, enthält die Flow-Definition weitere View-States. Für jeden View-State kann ein on-entry-Handler definiert werden.

Transitionen: Für jeden View-State werden die ausgehenden Transitionen im Sinne eines Zustandsautomaten definiert. Für jede Transition wird ein Zielzustand festgelegt. Diese können sein:

  • der eigene View-State (zur Aktualisierung des Views),

  • ein untergeordneter Subflow (führt zur Anzeige einer anderen GUI-Komponente, nach Ausführung des Subflows kehrt die Anwendung in den aktuellen Flow zurück),

  • ein Action-State oder ein Decision-State, in denen der Flow entweder Aktionen (z.B. Aufrufe des Anwendungskerns) oder Entscheidungen zum weiteren Flow-Ablauf trifft, oder

  • keine Angabe eines Zielzustands: Dadurch verbleibt der Flow im aktuellen View-State.

Wenn der Zielzustand dem aktuellen View State entspricht, wird er aktualisiert. Der vorherige Zustand kann NICHT mehr über den Browser-Back-Button erreicht werden. Für AJAX-Aufrufe, welche nur einen bestimmten Teil der Seite aktualisieren sollen, darf kein Zielzustand angegeben werden.

Für jede Transition kann hinterlegt werden, ob die Browser-Historie (für Back Button Handling) zurückgesetzt werden soll. Kommt man also nach Anzeigen einer Trefferliste über das Löschen eines Eintrags wieder zur Trefferliste, so sollte die Möglichkeit der Bereinigung der Historie genutzt werden.

Aufruf von Subflows: Beim Aufruf von Subflows müssen meist Parameter übergeben werden. Dazu wird ein Input-Tag verwendet, welches ein Schlüssel/Wertpaar an den Subflow übergibt. Im Subflow wird der Parameter über ein Input-Tag entgegengenommen und steht dann als Flow-Variable zur Verfügung und sollte im on-start-Handler per Controller in das Model übernommen werden.

Um die Kapselung der GUI-Komponenten zu bewahren, ist es wichtig, dass GUI-Komponenten ihre Parameter immer über ein Input-Tag erhalten und nicht frei auf fremde Models und Controller zugreifen.

Bei der Übergabe eines Parameters (z.B. Liste) ist immer eine Kopie der Datenstruktur zu übergeben, damit Änderungen an der Datenstruktur durch einen Subflow sich nicht auf den aufrufenden Flow auswirken. In diesem Sinne ist auch verboten, ein ganzes Model-Bean zu übergeben. Müssen mehrere Informationen übergeben werden, so können natürlich auch mehrere Input-Parameter verwendet werden.

Auch die Rückgabe von Out-Parametern ist über ein Output-Tag möglich. Es gelten die gleichen Richtlinien wie bei Input-Parametern.

Aufruf von Spring-Beans: An nahezu allen Stellen der Flow-Definition ist der Aufruf von Spring-Beans per evaluate-Tag möglich. Genutzt wird die Möglichkeit ausschließlich zum Aufruf des zustandslosen Controller-Beans – meist unter Bereitstellung des Model-Beans. Das Ergebnis kann in einer neuen Flow-Variablen hinterlegt werden. Üblicherweise aktualisieren die Aufrufe des Controllers aber direkt das zentrale Flow-Model.

Im evaluate-Tag wird die Java-Expression-Language verwendet, nicht die deutlich leistungsfähigere Spring Expression Language!

Flow-Definitionen bietet weitaus mehr Möglichkeiten, die im Regelfall allerdings seltener benötigt und daher hier nicht erläutert werden.

3.3. Erstellung der Controller

Jede GUI-Komponente verfügt über einen Controller. Der Controller ist der „verlängerte Arm“ des Flows, denn im Flow darf keine GUI-Logik ausgeführt werden. Jegliche zu programmierende GUI-Logik wird im Controller in zustandslosen Methoden bereitgestellt. Typische Methoden im Controller sind:

  • Methoden zur Initialisierung des Models,

  • Methoden zum Aufruf des Anwendungskerns,

  • Methoden zur Aufbereitung von Daten des Models vor dem Rendern.

Der Controller wird in der ControllerAutoConfiguration als einfaches Spring-Bean definiert und ist somit im Flow automatisch sichtbar und nutzbar. Jeder Controller muss von AbstractGuiController erben. Da der Controller zustandslos ist, benötigt jeder Aufruf das zugehörige Model. Der Controller kann auch eine eigene Fehlerbehandlung enthalten. In seltenen Fällen schreibt er selbst Meldungen in den FlowRequestContext, die dann als Fehler- oder Hinweismeldung ausgegeben werden.

Eine Rückgabe von Zielzuständen zur Steuerung des Flows in Methoden des Controllers ist zu vermeiden. Sinnvoll ist die Rückgabe eines Ergebnistokens (Erfolg oder Fehler), um dann im Flow den Zielzustand festzulegen und anzusteuern. Solche Entscheidungen können im Flow auch per Action- oder Decision-State umgesetzt werden, wobei im Controller eine Methode is… mit Rückgabewert boolean verwendet wird.

Die häufig gesehene Umsetzung von einfachen geheZu-Methoden des Controllers, die lediglich einen Rückgabewert aus einer Konstanten zurückliefern, erbringt keinen Mehrwert. Der Wert sollte in diesem Fall direkt in der Flow-Definition festgelegt werden.

3.4. Erstellung der Models

Das Model enthält alle temporären Daten, die ein Flow zur erfolgreichen Durchführung benötigt. Es wird, wie im Abschnitt über Flows beschrieben, immer durch einen Flow instanziiert und verwaltet. Ein Model für eine Maske muss von AbstractMaskenModel erben.

3.4.1. Befüllung eines Models

Wie im Abschnitt über Controller beschrieben, wird das Model durch den Controller bei Bedarf initialisiert und mit Daten aus dem Anwendungskern befüllt. Auch die Aufbereitung von Daten des Models kann durch den Controller erfolgen (alternativ über View-Konverter). Das Konvertieren von Model-Inhalten durch Logik im Model-Bean soll möglichst vermieden werden. Insbesondere ist Logik zu vermeiden, bei der Fehler auftreten können. Ein Model soll vor dem Rendern möglichst alle anzuzeigenden Daten passgenau für das Rendering vorhalten.

3.4.2. Abgleichen eines Models

Der Abgleich des Models mit dem View (nach Submit einer Maske) erfolgt automatisch durch JSF. Alle Seiteninhalte, die beim Rendern aus einem Model gelesen wurden, werden nach dem Submit wieder in das Model rückübertragen und stehen dann zur weiteren Verarbeitung für den Controller oder erneutes Rendering zur Verfügung.

3.4.3. Speichern der Daten eines Models

Das Model-Bean wird vom Flow im Flow Scope gehalten. Daher wird die Datenstruktur zwischen den einzelnen Dialogschritten in der Session persistiert (für Details zur Conversation-Persistierung siehe Spring Web Flow).

Für die Ablage im Flow Scope werden die Daten in serialisierter Form abgelegt. Daher muss das Model-Bean das Interface Serializable implementieren.

Größere Datenmengen beeinträchtigen die Performance der Anwendung zur Laufzeit. Umso mehr Daten im Model enthalten sind, desto aufwendiger ist die Session-Persistierung. Daher ist die Menge an gehaltenen Daten auf das Notwendige zu beschränken. Diejenigen Teile des Models, die nur temporär während der Datenaufbereitung befüllt werden, sollten dringend als transient markiert werden, um sie nicht in der Session zu speichern.

Die nach einem Submit im Model-Bean gespeicherten (und vom Anwender ggf. veränderten) fachlichen Daten werden nach Validierung in die fachlichen Tabellen der Datenbank übernommen. Dies erfolgt immer durch einen Controller, der die Daten aus dem Model an den Anwendungskern-Wrapper übergibt.

3.5. Erstellung der Views

3.5.1. Definition des View-State

Jeder View-State in der Flow-Definition der GUI-Komponente ist mit einer eigenen Maske, dem View verknüpft. Spring Web Flow steuert das Rendering des Views.

Der View einer GUI Komponente ist nach dem Umsetzungsmuster der IsyFact wie folgt aufgebaut: Eine Facelet-Datei dient dazu, die im Seitentemplate inkludierte Definition der Seitenbereiche des Inhaltsbereiches zu definieren. Das Tag <ui:composition> referenziert hierbei das Seitentemplate, in welchem die über <ui:define> definierten Teile eingebunden werden.

Je nach Seitentyp muss entweder

  • /WEB-INF/gui/common/layout/applikationDetailseite.xhtml oder

  • /WEB-INF/gui/common/layout/applikation.xhtml

als Ausgangs-Seitentemplate angegeben werden.

demoWebGui ApplicationTemplate
Abbildung 2. Einbindung eines Ausgangsseiten-Templates (applikation.xhtml)

Das Tag <ui:composition> referenziert hierbei das Ausgangsseiten-Template, in welchem die über <ui:define> definierten Teile eingebunden werden.

Die verschiedenen Teile des Seitentemplates finden sich in JSF Seitenelemente.

Die Templates bieten folgende Schnittstellen über den ui:define / ui:insert Mechanismus von JSF an:

  • inhaltsbereich: Der eigentliche Inhaltsbereich der Seite.

  • headIncludes: Zum Einbinden von weiteren Ressourcen in den HTML Header.

  • script: Zum Einbinden von seitenspezifischen JavaScript.

  • modalDialogPlaceholder: Zum Einbinden von modalen Dialogen.

  • printMetaInformation: Die Stelle um Meta-Informationen für Druckausgaben zu hinterlegen.

  • form: Zusätzliche Form-Elemente können hier eingebunden werden. Normalerweise stellt das Layout eine Form bereit. Für spezifische Anpassungen (z.B. AJAX-Listpicker) müssen jedoch eigene Forms definiert werden.

Listing 6. Beispiel für eine JSF ViewState Seite mit Inhaltsbereichsangabe
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:isy="http://java.sun.com/jsf/composite/isyfact"
   template="/WEB-INF/gui/common/layout/applikation.xhtml">

   	<!-- UI-Parameter setzen. -->
   	<ui:param name="flowModel" value="${auskunftDurchfuehrenModel}" />
   	<ui:param name="guiController"
   	    value="${auskunftDurchfuehrenController}" />
   	...

   <!-- Form für AJAX-Seiteninhalt definieren -->
   <ui:define name="form">
     <h:form id="listpickerAjaxForm">
        <isy:formListpickerAjaxContent />
     </h:form>
    </ui:define>

   <!-- Der Inhaltsbereich (Hauptanwendungsbereich s.a. Bedienkonzept) -->
   <ui:define name="inhaltsbereich">
      ...
      	<ui:include src="./DruckButtonZeile.xhtml" />
      ...
   </ui:define>
</ui:composition>

Die Seitenbereiche werden im ViewState-Facelet wiederum durch Inklusion auf kleinere Facelets umgesetzt. Das heißt jeder Seitenbereich (Formular, Buttonzeile) wird per Konvention in einer separaten Datei gepflegt. Innerhalb dieser Facelets wird im Normalfall nichts mehr inkludiert.

Listing 7. Beispiel: Inkludiertes Facelet DruckButtonZeile.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:isy="http://java.sun.com/jsf/composite/isyfact">

	<!-- Download des PDFs geht nur bei ajax='false' -->
	<isy:buttonIcon id="druck_icon"
	   name="#{msg.MEL_Drucken}"
	   icon="print"
	   tooltip="#{msg.MEL_Tooltip_Drucken}"
	   size="large"
	   action="drucken"
	   reverseIconPosition="true"
	   ajax="false">
	</isy:buttonIcon>

</ui:composition>

3.5.2. Rendern einer Maske mit den Daten eines Models

Der Zugriff auf die Daten des Models erfolgt in den Facelets über die Common Expression Language (EL). Das Model ist im View sichtbar, da es im Flow als Flow-Variable deklariert wurde. Das Model ist zum Zeitpunkt des Renderns bereits mit Daten befüllt, da im on-entry-Handler des Flows der Controller die Befüllung des Models vorgenommen hat.

Listing 8. Datenzugriff im Facelet
<isy:formInput reference="name"
   value="#{auskunftDurchfuehrenModel.veranstaltungstitel}"
   label="Titel der Veranstaltung"
   required="true"/>

Es ist wichtig zu verstehen, dass durch das Rendern der Daten aus dem Model eine Bindung der Model-Property mit dem GUI-Element (im Beispiel ein Form-Input-Feld) hergestellt wird, welches nach Submit des Webformulars automatisch durch Spring Web Flow in das Model zurück synchronisiert wird. Damit das funktioniert ist eine eindeutige HTML-ID zu vergeben. Die HTML Elemente erhalten entsprechend ihres Inhaltes den Bezeichner des zugehörigen Attributes. Würde keine ID vergeben, so würde JSF selbständig eine dynamische ID vergeben. Das erschwert jedoch den automatischen Test der Oberfläche.

Listing 9. HTML ID Vergabe
<h:selectOneMenu id="vonZeit"
   value="#{erstellenModel.alleZeitraeume}"
   var="von" itemValue="#{von}" itemLabel="#{von}"
/>

Werden versehentlich IDs mehrfach verwendet, so sind Fehler bei der Datenübernahme wahrscheinlich.

3.5.3. Auslösen von Aktivitäten in Facelets

Die Auslösung von Aktion erfolgt über die Nutzung des action-Attributes der verwendeten GUI-Komponenten. Hier wird ein Token verwendet, welches auch im Flow bekannt ist und die Transition so steuert, dass der Controller die Daten über den Anwendungskern persistiert.

Listing 10. Beispiele für Actions
<isy:button action="back" value="Zurück"/>
<isy:button action="continue" value="Weiter"/>

3.5.4. Datenkonvertierung für Darstellung und Eingabe

Für die formatierte Darstellung von Daten können JSF-Konverter zur Konvertierung aus der Ansicht ins typisierte Datenmodell, wie auch zur Umwandlung aus dem Datenmodell in die Ansicht verwendet werden. Hier bieten sich JSF-Konverter an, die jedoch nur mit Einschränkungen verwendet werden können, da diese bei der Konvertierung „freier Eingaben“ nicht mit Fehleingaben umgehen können.

Listing 11. Umwandlung eines Datums mittels Konverter
<h:inputText id="datum" value="#{erstellenModel.newDate}">
       <f:convertDateTime type="date" />
</h:inputText>

Wenn die Validierung in einem JSF-Konverter stattfindet, werden die Daten in einem Fehlerfall nicht ins Modell geschrieben. Dies führt dazu, dass das Formular zurückgesetzt wird, weil die Seite wegen des PRG-Patterns mit einem GET-Request mit dem alten Modell neu geladen wird. Die ungültigen Eingaben gehen also zusammen mit allen anderen Änderungen im Modell verloren. Standard-JSF-Konverter sind also faktisch nicht nutzbar.

Ein geeigneter Konverter muss auch ungültige Daten ins Modell schreiben können. Wenn dies aufgrund der Nutzung spezieller Datentypen (wie z.B. Date) nicht möglich ist, muss im View-Model der Datentyp String verwendet werden. Die Konvertierung findet in diesem Fall nicht durch einen Konverter statt, sondern erst nach oder während der Validierung.

JSF-Konverter werden auch für die Darstellung von readonly Felder verwendet. Folgende Komponenten werden entsprechend behandelt:

  • actionInput,

  • actionInputWithFourEyes,

  • formActionInput,

  • formActionInputWithFourEyes,

  • formCurrencyInput,

  • formCurrencyInputWithFourEyes,

  • formDate,

  • formDateWithFourEyes,

  • formInput,

  • formInputWithFourEyes,

  • formNumericInput,

  • formNumericInputWithFourEyes,

  • formTextArea,

  • formTextAreaWithFourEyes.

Oft ist es notwendig, im Model Schlüssel eines Schlüsselverzeichnisses zu verwenden. Dieser sollte in der Regel in der Maske nicht als Schlüssel, sondern in einer verständlichen Form dargestellt werden. Hier bietet sich der Einsatz eines eigenen Konverters an, der mittels Schlüssel-Wert-Mapping die Umwandlung je nach Verarbeitungsrichtung leistet. Analog gilt dies auch für Booleans und Aufzählungstypen.

Listing 12. Umwandlung eines Aufzählungstyps mittels Konverter
<h:outputText value="#{cdAblageDatenBackBean.interpretMaennlich}">
     <f:converter converterId="geschlechtsTypConverter"/>
</h:outputText>

Im Hinblick auf aktiviertes JavaScript darf bei outputText niemals das Attribut escape auf false gesetzt werden.

3.6. Interaktive Elemente mit JQuery

Folgende JQuery-Module dürfen eingesetzt werden:

  • jquery-core (Kernfunktionalität zur DOM-Manipulation),

  • jquery-effects (Effekte für das Ein- und Ausblenden von Elementen),

  • jqueryui-datepicker (Kalender-Widget),

  • jquery-validation-plugin (Datenvalidierung).

Die Module jquery-data und jquery-ajax dürfen nicht verwendet werden, da AJAX-Funktionalität im Hinblick auf die eingesetzte Seitenlogik mit Spring Web Flow nicht angeboten werden soll.

Enthält eine View interaktive Elemente, wird eine entsprechend benannte JavaScript-Datei am Seitenende (d.h. am Ende des View-Templates) eingebunden:

Listing 13. Einbindung view-spezifischer JavaScript-Dateien
<script type="text/javascript"
    src="#{facesContext.externalContext.requestContextPath}/js/vorgangSuchen.js">
</script>

Diese Datei enthält den benötigten JavaScript-Code zum Erzeugen von UI-Elementen oder zum Binden von Events an bestehende Fragmente. Die Vorgaben zur Nutzung von JavaScript aus dem Konzept JSF sind unbedingt einzuhalten.

Wie Einbindung view-spezifischer JavaScript-Dateien zeigt, sind beim Einbinden niemals relative Pfade zu verwenden, um die Same-Origin-Policy zu forcieren. Zusätzlich sorgt das script-Tag dafür, dass im Fall von deaktiviertem JavaScript kein Fehler auftritt und die XHTML-Konformität erhalten bleibt.

Das folgende Beispiel für eine JavaScript-Datei zeigt das Beispiel vorgangSuchen.js, das ein GUI-Element mit der ID Geburtsdatum fokussiert:

Listing 14. Beispiel für eine JavaScript-Datei
(function(){
  $('#Geburtsdatum').focus();
})()

In der Regel bieten die JSF Bedienelemente der IsyFact Zugriff auf Darstellungsformen mittels JavaScript (z.B. Kalenderwidget, Tags, Panels). Für bestimmte Zusatzanforderungen (z.B. bedingtes Deaktivieren eines Felds, weitere GUI-Verschönerungen) kann es jedoch notwendig sein zusätzliches JavaScript einzubinden.

3.7. Konfiguration der Web-Anwendung

Mit SpringBoot 2 ist eine web.xml nicht mehr vorgesehen. Die Konfiguration erfolgt in der Regel mit @Configuration-annotierten Java-Klassen. Zur Autokonfiguration von Controllern, WebMVC und Flows sind hierbei die Klassen ControllerAutoConfiguration, MvcAutoConfiguration und WebFlowAutoConfiguration vorgesehen und müssen importiert werden.

3.7.1. Festlegung der Startseite

Standardmäßig ist die Startseite der Anwendung die index.html. In ihr muss ein Redirect auf den Startflow erfolgen. Dieses ist notwendig, weil eine Angabe der Flow Engine für Welcome Files nicht direkt möglich ist.

Die Datei index.html sieht folgendermaßen aus:

Listing 15. Ausschnitt index.html
<html>
  <head>
    <meta http-equiv="Refresh" content="0; URL= app/startFlow">
  </head>
</html>

3.7.2. Erkennung von JavaScript Unterstützung

Je nach Browser und JavaScript Aktivierungsstatus muss die Anwendung Widgets verschieden darstellen. Hierzu existiert ein Filter, welcher in die Anwendungskonfiguration als Bean eingebunden werden muss.

Der Parameter urlApplicationInitialisierung ist verpflichtend und enthält die URL zur Application-Initialisierungsseite. Es ist ein führendes / anzugeben.

Der Parameter urlsToSkip ist optional und dient zur Aufnahme von URL-Pfaden, relativ zu dem Pfad des ApplicationContext, die von der Filterung ausgenommen werden. Mehrere URL-Pfade sind durch Kommas separiert anzugeben. Es ist jeweils ein führendes / anzugeben.

Die Parameter müssen ggf. angepasst werden.

Listing 16. Ausschnitt WebConfig.java
public class WebConfig {

    @Bean
    public FilterRegistrationBean<ApplicationInitialisierungFilter> applicationInitialisierungFilter() {
        FilterRegistrationBean<ApplicationInitialisierungFilter> registrationBean =
            new FilterRegistrationBean<>();
        registrationBean.setFilter(new ApplicationInitialisierungFilter());

        registrationBean.addUrlPatterns("/app/*");

        // Optionaler Parameter: Der Parameter "urlsToSkip" dient zur Aufnahme von Url-Pfaden,
        // relativ zum ApplicationContext-Pfad, die von der Filterung ausgenommen werden.
        // Mehrere Url-Pfade sind kommasepariert anzugeben. Es ist pro Url ein führendes "/" anzugeben.
        registrationBean.addInitParameter("urlsToSkip", "/app/resources");
        registrationBean.addInitParameter("ajaxRedirectUrl", "/");
        // Pflicht-Parameter:
        // Der Parameter "urlApplicationInitialisierung" enthält die Url zur Application-Initialisierungsseite.
        // Es ist ein führendes "/" anzugeben.
        registrationBean.addInitParameter("urlApplicationInitialisierung",
            "/app/common/init/applicationInitialisierung.xhtml");
        return registrationBean;
    }
}

3.8. Konfiguration der Navigation

Nachfolgend werden die notwendigen Konfigurationen beschrieben, um die konkreten Dialog-Flows zu definieren, und wo die entsprechenden Anpassungen vorgenommen werden müssen.

3.8.1. JSF Flow Builder Service

Der JSF Flow Builder Service initialisiert aus der Dialog-Ablaufbeschreibung die konkreten Dialoge. Zusätzlich kann hier noch der Expression Parser für die EL-Implementierung definiert werden. Durch die Definition des EL-Parsers kann die konkrete EL-Implementierung festgelegt werden. Standardmäßig sollte hier keine spezifische Konfiguration vorgenommen werden, eine Autokonfiguration findet bereits in WebFlowAutoConfiguration statt.

3.8.2. Ablage der Flow-Konfiguration

Die Spring Webflow Konfiguration erfolgt standardmäßig in der Autokonfiguration. Als Lokation der Flows ist dabei /WEB-INF/gui/**/*Flow.xml angegeben. Das heißt, die Flows sind in Unterordnern von /WEB-INF/gui abzulegen und enden gemäß Namenskonvention mit Flow.xml (z.B. beispielFlow.xml).

3.9. Konfiguration der Maskentexte

Maskentexte, die nur innerhalb eines bestimmten Flows verwendet werden, können in der Konfigurationsdatei <FlowName>.properties im Ordner resources/nachrichten/maskentexte definiert werden. Wenn die jeweilige Konfigurationsdatei vorhanden ist, werden die Maskentexte automatisch geladen und in die Variable msg_currentflow abgespeichert. Die Maskentexte des jeweiligen Flows können dann beispielsweise wie folgt ausgelesen werden:

Listing 17. Maskentexte über Konfigurationsdatei
<h:outputText value="#{msg_currentflow.MAS_Ueberschrift}" />

Um übergreifende Maskentexte Spring bekannt zu machen, müssen die Lokationen Spring bekannt gemacht werden. Hierfür wird eine ResourceBundleMessageSource als Bean definiert:

Listing 18. Maskentexte
// Diese Bean sorgt für die Message-ResourceBundle Bereitstellung,
// zugreifbar über Klasse SpringContextHolder.
@Bean
public ResourceBundleMessageSource messageSource() {

    ResourceBundleMessageSource source = new ResourceBundleMessageSource();
    source.addBasenames(
        "resources/nachrichten/fehler",
        "resources/nachrichten/maskentexte",
        "resources/nachrichten/titles");

    return source;
}

Im Beispiel aus Maskentexte referenziert dabei der Basename resources/nachrichten/maskentexte die Konfigurationsdatei resources/nachrichten/maskentexte.properties.

3.10. Konfiguration des Resource Caching Mechanismus

Möchte man Webressourcen wie Bilder oder CSS-Dateien von Softwareversionen abhängig machen, muss das Folgende gemacht werden:

3.10.1. JSF ResourceHandler einrichten

Die Ressourcenlieferung wird durch sogenannte ResourceHandler verkapselt. Um also den Prozess anpassen zu können, muss man einen eigenen ResourceHandler definieren und an die Web Applikation anbinden. Da jedoch das GUI mittels JSF erstellt wird, muss es JSF-spezifisch umgesetzt werden. Der folgende Code ist ein Beispiel so eines Handlers:

public class VersionierungResourceHandler extends ResourceHandlerWrapper {

	private ResourceHandler wrapped;
	private SystemVersionBean systemVersionBean;

	public VersionierungResourceHandler(ResourceHandler wrapped) {
		this.wrapped = wrapped;
		if (StatischerKontextInhaber.getApplicationContext() != null) {
			this.systemVersionBean =
				StatischerKontextInhaber.getApplicationContext().getBean(SystemVersionBean.class);
		}
	}

	@Override
	public Resource createResource(String resourceName) {
		return createResource(resourceName, null, null);
	}

	@Override
	public Resource createResource(String resourceName, String libraryName) {
		return createResource(resourceName, libraryName, null);
	}

	@Override
	public Resource createResource(String resourceName, String libraryName, String contentType) {
		final Resource resource = super.createResource(resourceName, libraryName, contentType);
		if (resource == null) {
			return null;
		}
		return new ResourceWrapper() {

			@Override
			public String getRequestPath() {
				String requestPath = super.getRequestPath();
				String version = "v=" + getSystemVersion();
				if (!requestPath.contains("?")) {
					return requestPath + "?" + version;
				}
				return requestPath + "&" + version;
			}

			@Override
			public Resource getWrapped() {
				return resource;
			}
		};
	}

	@Override
	public ResourceHandler getWrapped() {
		return this.wrapped;
	}

	private String getSystemVersion() {
		if (this.systemVersionBean == null && StatischerKontextInhaber.getApplicationContext() != null) {
			this.systemVersionBean = StatischerKontextInhaber.getApplicationContext().getBean(SystemVersionBean.class);
		}
		if (this.systemVersionBean == null) {
			this.systemVersionBean = new SystemVersionBean();
			this.systemVersionBean.setSystemVersion("DEV");
		}
		return this.systemVersionBean.getSystemVersion();
	}
}

In der Methode getRequestPath() kann man die Pfade der Ressourcen beliebig anpassen und zum Beispiel, wie oben gezeigt, eine Version an sie anhängen.

3.10.2. Konfiguration

Der ResourceHandler muss noch mittels Konfiguration an die Web-Applikation angebunden werden. Dies macht man in faces-config.xml (Java Server Faces Konfigurationsdatei) auf die folgende Weise:

<application>
	<resource-handler>pfad.VersionierungResourceHandler</resource-handler>
</application>

3.10.3. JSF Tags benutzen

Es gibt noch eine letzte Bedingung, die man erfüllen muss, damit der JSF ResourceHandler die Ressourcen überhaupt behandelt. Es müssen JSF Tags benutzt werden:

  • JavaScript: <h:outputScript> anstatt <script>,

  • CSS: <h:outputStylesheet> anstatt <link>.

Dank ihnen werden die jeweiligen Ressourcen für unseren ResourceHandler sichtbar und werden von ihm nun verwaltet.

3.11. Optionale Anzeige der Versionsnummer im Webseitentitel

Es besteht die Möglichkeit, die Versionsnummer einer Anwendung im Webseitentitel anzuzeigen. Hierzu muss der Parameter gui.versionsanzeige.seitentitel.aktiv in einer Konfigurationsdatei der Anwendung hinterlegt sein und auf true gesetzt werden. Ist der Parameter nicht hinterlegt, so ist die Anzeige standardmäßig nicht aktiviert und es ist nichts zu tun (Abwärtskompatibilität).

Zusätzlich muss der Parameter system.version in einer Konfigurationsdatei hinterlegt sein. Dieser Parameter enthält die aktuelle Version der Anwendung. Es empfiehlt sich, die Versionsnummer beim Build automatisch zu setzen. Außerdem kann im Parameter system.name der Name der Anwendung hinterlegt werden. Dies ist jedoch nicht zwingend nötig. Die Anzeige der Versionsnummer funktioniert auch ohne Angabe des Anwendungsnamens. Dieser entfällt dann einfach. In Konfiguration der Anzeige von Name und Version im Seitentitel finden sich eine beispielhafte Konfiguration und in Anzeige von Name und Version im Seitentitel wird das eigentliche Feature gezeigt.

Listing 19. Konfiguration der Anzeige von Name und Version im Seitentitel
# Ob die Versionsnummer im Seitentitel angezeigt werden soll.
# Mögliche Werte `true` oder `false`. Standardwert ist `false`.
gui.versionsanzeige.seitentitel.aktiv=true

# Die Systemversion wird in richtigen Anwendungen automatisch
# über Maven aktualisiert. Hat hier einfach einen festen
# Wert, da sie nur für Beispiele verwendet wird.
system.version=1.2.3

# Der Systemname
system.name=Terminfindung
DispNameVersTitle
Abbildung 3. Anzeige von Name und Version im Seitentitel

3.12. Packaging und Namenskonventionen

Ein nicht zu vernachlässigender Aspekt zur Komponentenbildung ist die Paketierung, durch die zu einer Komponente gehörende Elemente gruppiert abgelegt werden. Alle Elemente werden in einem Paket mit einheitlichem Paketnamen abgelegt.

Für die Namenskonvention zu Java-Klassen und Paketen wird hier auf das Dokument Java-Programmierkonventionen verwiesen. Zusätzlich gelten die folgenden Konventionen:

  • Jede GUI-Komponente hat einen Namen. Die Namen richten sich nach den fachlichen Komponenten bzw. Dialogen.

  • Das Paket, in dem die GUI-Komponente abgelegt wird, trägt den vollständig kleingeschriebenen Namen der GUI-(Sub-)Komponente (z.B. erstellen). Jede GUI-Komponente nutzt zwei Ablageorte:

    • java/de/…/gui/terminfindung/erstellen/…​ für Java-Klassen

    • WEB-INF/gui/terminfindung/erstellen/…​ für Flows und Views

  • Model Bean-Klassen tragen den Namen der GUI-Komponente und enden auf Model (z.B. ErstellenModel).

  • Controller Bean-Klassen tragen den Namen der GUI-Komponente und enden auf Controller (z.B. ErstellenController).

  • Flows tragen den Namen der GUI-Komponente und enden auf Flow.xml (z.B. erstellenFlow.xml).

  • Der Main-View, der dem Flow-View-State zugeordnet ist endet auf ViewState (z.B. erstellenViewState.xhtml). Besteht der Flow aus mehreren View-States, so wird eine Schritt-Nummer angehängt (z.B. erstellenViewState1.xhtml).

  • Alle weiteren für den View verwendeten Facelets tragen den Namen der Komponente und eine Charakterisierung des Facelets (z.B. erstellenFormular.xhtml). Auch hier ist eine Schrittnummer anzuhängen, wenn der Flow mehrere View-States enthält (z.B. erstellenFormular1.xhtml).

  • Die bei einem View-State verwendete JavaScript-Datei trägt den Namen des View-States (z.B. erstellenFormular1.js). Gibt es View-übergreifende Funktionalität, kann diese in eine wiederverwendbare JavaScript-Datei ausgelagert werden (z.B. erstellenFormular.js).

Die Abbildung Verzeichnisstruktur der Dialog-Komponente Erstellen zeigt einen Verzeichnisbaum und verdeutlicht, wie die Elemente einer Dialog-Komponente (hier: Erstellen) im Dateisystem abgelegt werden.

bspstructmit
Abbildung 4. Verzeichnisstruktur der Dialog-Komponente Erstellen

4. Umsetzung querschnittlicher Aspekte

Die folgenden Abschnitte beschreiben die Integration weiterer Bausteine der IsyFact, die querschnittliche Funktionalität bereitstellen.

4.1. Logging

Für das Logging kommt logback zum Einsatz. Das Konzept Logging enthält die dafür notwendigen Konfigurationen und weitere Details. Zur Konfiguration des Logging ist folgende Abhängigkeit nötig:

Listing 20. Abhängigkeit isy-logging (Ausschnitt pom.xml)
<dependency>
    <groupId>de.bund.bva.isyfact</groupId>
    <artifactId>isy-logging</artifactId>
</dependency>

Isy-Logging erwartet die logback-Konfiguration standardmäßig im Klassenpfad unter /config/logback.xml.

Die Nutzungsvorgaben Logging beinhalten Vorgaben zum Schreiben von Log-Einträgen und zur Ablage von Log-Dateien.

4.2. Fehlerbehandlung

In diesem Kapitel wird die Behandlung von Fehlern beschrieben. Dabei sind folgende Arten von Fehlern zu unterscheiden:

  • Validierungsfehler,

  • Fehler innerhalb des Dialogablaufs (AWK),

  • Fehler innerhalb des Dialogablaufs (GUI),

  • Fehler außerhalb des Dialogablaufs,

  • Fehler innerhalb des Clients.

4.2.1. Darstellung von Fehlern

Die Darstellung von Fehlern wird über das JSF-Seitentemplate basis.xhtml vorgenommen. Die Fehlermeldungen werden hierbei im Kopfbereich des Applikations-Inhaltsfensters angezeigt.

Für Fehler beim Zugriff auf den Anwendungskern kann zusätzlich eine Fehlerbehandlung im Controller eingeführt werden (try/catch).

Das JSF-Tag message kommt zum Einsatz, um einen Fehler für ein bestimmtes Feld anzuzeigen:

Listing 21. Beispiel aus Facelet
<h:message for="isbn" showDetail="false" errorClass="error"/>

Das obige JSF Tag markiert das Feld, das die JSF-ID isbn hat, als fehlerhaft, wenn im JSF-Context eine Fehlernachricht für die JSF-ID isbn geschrieben wurde.

Für die Darstellung aller Fehlermeldungen kommt das JSF Tag messages zum Einsatz. Hierdurch werden alle Fehler, unabhängig von ihren JSF-IDs, in einer Liste dargestellt:

Listing 22. Darstellung von Fehlermeldungen
<h:messages/>

Die Darstellung von Fehlern und Validierungsnachrichten wird auch im Bedienkonzept beschrieben.

4.2.2. Umgang mit Validierungsfehlern

Um Validierungsfehler innerhalb der Masken bei den fehlerhaften Feldern darzustellen, besitzt jede Formularkomponente das Attribut reference (siehe Validierung). Dadurch können Validierungsfehler den entsprechenden Feldern zugeordnet werden.

In bestimmten Fällen kann es auch notwendig sein, zusätzliche Validierungsprüfungen in GUI-Komponenten bereitzustellen (z.B. wenn die GUI je nach Eingabe unterschiedliche Aufrufe des Anwendungskerns durchführt). Diese sollten durch einen evaluate Aufruf innerhalb des Flows vor dem eigentlichen Zustandsübergang durchgeführt werden. Die Nutzung des Validierungsmechanismus von Spring Webflow ist grundsätzlich möglich, bringt jedoch auch Nachteile mit sich, da der Aufruf der Validierung auf einer Namenskonvention von View States und Transitionen beruht und bei Umbenennungen sehr fehleranfällig ist. Durch den Aufruf der Validierung mit evaluate wird die Validierung daher explizit und sichtbar definiert.

Bei der Übermittlung von Werten in JSF müssen die Vorgaben aus Kapitel Datenkonvertierung für Darstellung und Eingabe beachtet werden: Die Eingabe von ungültigen Werten (z.B. ungültiges Datum, Buchstaben in einem Zahlenfeld) muss grundsätzlich möglich sein. Ggf. müssen entsprechende Datentypen und JSF-Converter erzeugt werden. Die Validierung in der GUI, aber spätestens im Anwendungskern, muss die fehlerhafte Eingabe feststellen. Die Validierung über JSF ist derzeit nicht vorgesehen.

4.2.3. Behandlung von Fehlern innerhalb der Verarbeitung im AWK

Innerhalb der Verarbeitung von Dialogaktionen können Exceptions auftreten. Sofern diese nicht ohnehin behandelt werden, müssen sie innerhalb der GUI-Komponenten behandelt werden. Der jeweilige Controller muss dabei durch eine Exception-Fassade (try/catch) sicherstellen, dass auftretende Fehler nicht in die Dialogsteuerung weitergegeben werden. So können checked und unchecked Exceptions abgefangen werden. Der MessageController bietet hierzu Methoden (writeException, writeAndLogException) zum Loggen und Erzeugen von Fehlern/Warnungen im Nachrichtenbereich an. Das dort implementierte Exception Handling unterscheidet fachliche und technische Exceptions. Während fachliche Fehler mit einer möglichst aussagekräftigen Fehlermeldung in der Oberfläche angezeigt werden müssen, soll für technische Fehler nur eine allgemeine Fehlermeldung angezeigt werden.

4.2.3.1. Ausgabe für fachliche Fehler
  • Im Error-Log und über die GUI: {Fehler-ID}: {Fehlernachricht} (Referenzcode: {UUID})

Weil die Fehlertexte der fachlichen Fehler in der GUI angezeigt werden, ist die Verwendung von spezialisierten Exceptions anzuraten, die Fehlertexte enthalten, die für die Anzeige in der GUI geeignet sind. Hierzu finden sich weitere Informationen im Dokument Konzept Fehlerbehandlung.

4.2.3.2. Ausgabe für technische Fehler
  • Im Error-Log: {Fehler-ID}: {Fehlernachricht} (Referenzcode: {UUID})

  • Über die GUI: Es ist ein technischer Fehler aufgetreten {Fehler-ID}. Bitte versuchen Sie es später noch einmal (Referenzcode: {UUID}).

In der Oberfläche wird also für technische Fehler immer ein fester Standardtext, zusammen mit dem ursprünglichen Fehlercode, ausgegeben. Nur das Error-Log enthält ebenso die ursprüngliche Fehlermeldung. Dadurch wird verhindert, dass interne oder nur für die Systementwicklung oder den Betrieb relevante Meldungen nach außen getragen werden.

4.2.4. Behandlung von Fehlern innerhalb des Dialogablaufs

Exceptions, welche während der Ausführung von Logik der GUI-Komponenten (z.B. Datenaufbereitung, Rendering) entstehen, werden immer als technische Exception angesehen. Für diese wird eine standardisierte Fehlerseite mit der in Punkt Ausgabe für technische Fehler angegebenen Fehlermeldung für technische Fehler ausgegeben.

Um die Behandlung solcher Fehler zu ermöglichen, stellt die Bibliothek isy-web folgendes sicher, sodass für Anwendungen nichts weiter zu tun ist:

Globaler Übergang auf einen Fehler-Flow: Der globale Parent-Flow definiert einen Übergang auf den globalen Fehler-Flow.

Listing 23. Flow Übergang auf Fehlerseite
<flow>
  <subflow-state id="fehler" subflow="errorFlow" />

  <global-transitions>
    <transition on-exception="java.lang.Exception" to="fehler" />
  </global-transitions>
</flow>

Konfiguration des JSF Exception Handlers: Dieser Handler wird in der faces-config.xml konfiguriert:

Listing 24. Flow JSF Exception Handler Konfiguration
<factory>
  <exception-handler-factory>
    de.bund.bva.isyfact.common.web.exception.web.JsfExceptionHandlerFactory
  </exception-handler-factory>
</factory>

Bereitstellung des globalen Error-Flows: Der Flow errorFlow bietet eine globale Fehlerseite an.

4.2.5. Behandlung von Fehlern außerhalb des Dialogablaufs

Es gibt Exceptions, die außerhalb des "normalen" Dialogablaufs auftreten. Beispiele dazu sind fehlende Flow-Definitionen, abgelaufene Sessions und Fehler bei der Autorisierung. Solche Fehler werden im Rahmen der HTTP-Request-Bearbeitung auf erster Ebene durch einen FlowHandler behandelt, den Spring Web Flow mitbringt. Kann dieser den Fehler nicht behandeln, wird er auf zweiter Ebene durch einen ExceptionResolver von Spring MVC behandelt. Hierfür stellt die Bibliothek isy-web Implementierungen zur Verfügung, über welche ein Mapping der Fehler auf spezielle Flows und Fehlerseiten möglich ist, und konfiguriert diese automatisch.

Es gibt keine anwendungsspezifischen Fehlerseiten. Alle IsyFact-Anwendungen verwenden eine einheitliche Fehlerseite.

Die Fehlerseite gibt aus Sicherheitsgründen keine Informationen über die Art des Fehlers preis. Die eigentliche Fehlerursache kann nur aus den Server-Logs ermittelt werden.

4.2.6. Behandlung von OptimisticLockExceptions

Für die Behandlung einer OptimisticLockException innerhalb der Anwendung ist ein spezieller Handler eingerichtet. Beim Auftreten einer OptimisticLockException wird eine gesonderte Fehlermeldung ausgegeben, die auf einen konkurrierenden Zugriff hinweist. Zusätzlich wechselt der Handler in den Zustand abbrechenEndState des aktiven Flows, wenn dieser vorhanden ist. Sonst wird in den allgemeinen Fehlerzustand (fehler) gewechselt.

4.2.7. Behandlung von Fehlern innerhalb des Clients

Durch die Nutzung von AJAX entstehen clientseitige HTTP-Requests, welche durch die JSF-JavaScript-Bibliothek gesteuert werden. Auftretende Fehler (z.B. Server nicht erreichbar, Serverfehler) werden daher nicht durch den Browser direkt, sondern durch die JS Bibliothek behandelt.

4.3. Sicherheit

Die Absicherung von Masken erfolgt auf Dialogablauf-Ebene mittels Spring Web Flow. Die Berechtigungsprüfung verwendet den Security-Baustein.

4.3.1. Autorisierung

Für die Absicherung von Dialogabläufen wird innerhalb der Spring Web Flow-Konfiguration auf dem <view-state> ein <secured> Tag mit dem geforderten Recht gesetzt. Die verwendeten Rechte müssen durch die Rollenrechte-Konfiguration (siehe Nutzungsvorgaben Security) für den eingeloggten Benutzer entsprechend gesetzt werden. Durch die Verwendung des Tags wird vor dem Anzeigen des <view-state> eine Überprüfung der Berechtigung des anfragenden Benutzers durchgeführt. Fehlt dem Benutzer diese, wird die Fehlerseite angezeigt.

Listing 25. Ausschnitt aus Flow erstellenFlow.xml
<view-state id="erstellenViewState1" model="erstellenModel">
    <secured attributes="Erstellen"/>
    <transition on="continue" to="validiereStammdaten"/>
    <transition on="add" to="erstellenViewState1" />
    ...
</view-state>
Listing 26. Ausschnitt aus Flow verwaltenFlow.xml
<view-state id="verwaltenViewState">
    <secured attributes="Verwalten"/>
    <transition on="abschliessen" o="abschliessenViewState"/>
    <transition on="loeschen" to="loeschenViewState" />
    ...
</view-state>

4.3.2. Berechtigungsabhängige Darstellung in Masken

Um eine berechtigungsabhängige Darstellung von Maskenelementen zu realisieren, muss die Anwendung einen Controller bereitstellen, mit dessen Hilfe über nicht parametrisierte Methoden Anfragen nach den benötigten Rechten gestellt werden können. Dieser Controller ist dafür zuständig, den Rechte-Schlüssel aufzulösen und die Anfrage an die Komponente Security zu delegieren. Beantwortet werden die Anfragen stets mit einem einfachen Booleschen Wert.

Mithilfe dieses Controllers lassen sich einzelne Maskenelemente, aber auch Gruppen von Maskenelementen berechtigungsabhängig ausblenden. Die JSF-Komponenten bietet hierfür das rendered-Attribut (siehe JSF-Komponente berechtigungsabhängig ausblenden). Beantwortet der BerechtigungsController den Methoden-Aufruf von getBenutzerDarfAdministrieren() mit false, so wird der Button nicht dargestellt.

Listing 27. JSF-Komponente berechtigungsabhängig ausblenden
<t:commandButton rendered="#{berechtigungsController.benutzerDarfAdministrieren}"/>

Sollen mehrere oder nicht-JSF Komponenten berechtigungs­abhängig ausgeblendet werden, kann das Fragment-Tag der Facelets-Bibliothek verwendet werden. Dieses kann eine beliebige Anzahl an weiteren Maskenelementen umschließen und bietet ebenfalls das rendered-Attribut, welches sich dann auf alle enthaltenen Komponenten auswirkt (siehe GUI-Komponenten berechtigungsabhängig ausblenden).

Listing 28. GUI-Komponenten berechtigungsabhängig ausblenden
<ui:fragment
   rendered="#{berechtigungsController.benutzerDarfAnwenderAdministrieren}">
           […] weitere Komponenten […]
</ui:fragment>

4.3.3. Vermeidung von Sicherheitslücken bei aktiviertem JavaScript

Ist JavaScript in einem Browser aktiviert, eröffnet dies gewisse Risiken bei der Verarbeitung datenschutzrelevanter Informationen. Folgende Maßnahmen reduzieren jedoch das Risiko möglicher Attacken für Cross-site-Scripting (XSS):

  • Verwendung von Standardbrowsern: Die gängigen Browser befolgen festgelegte Sicherheitsrichtlinien, die nur schwer und vorsätzlich deaktiviert werden können. Diese Standard­einstellungen erschweren XSS und sind gerade für den folgenden Punkt unerlässlich.

  • Übertragung aller Inhalte per HTTPS zum Browser: Werden Webinhalte per HTTPS zum Client übertragen, ist ein unerwünschtes Datenauslesen per JavaScript-Injection oder IFrame-Injection verhindert, da Browser JavaScript-Code nur dann auf einen domain-fremden DOM zugreifen lassen, sofern dieser nicht sicher übertragen wurde.

  • Keine Verwendung von Request-Variablen in offenem JS: Werden Request-Parameter, z.B. als Teile eines Formulars, direkt in offenem JavaScript (eval([var]) oder setTimeout([var])) weiterverwendet, so können Angreifer manipulierte Parameter für DOM-based-XSS nutzen, d.h. es werden JavaScript Befehle als Parameter übergeben, die Inhalte verändern, auslesen oder in einen falschen Kontext setzen.

  • Encodierung von Request-Variablen im DOM: Werden Request-Variablen auf einer Seite dargestellt, so sind diese XML-encodiert einzubinden (siehe Element outputText in Kapitel Datenkonvertierung für Darstellung und Eingabe). Somit wird verhindert, dass ein Angreifer ein ungewünschtes Script-Tag übergibt.

4.3.3.1. Konfiguration Security-Komponente

Die Konfiguration der Security-Komponente ist in den Nutzungsvorgaben Security beschrieben.

Die zur Integration mit Spring Webflow benötigten Listener liefert isy-web in der Autokonfiguration mit.

4.3.4. Konfiguration des CSRF Schutzes

Seit JSF 2.0 ist der CSRF Schutz für POST Requests standardmäßig aktiviert. Für den Schutzbedarf mittel und hoch reicht die Implementierung der Variante Token per Session, für Schutzbedarf sehr hoch muss die Variante Token per Request implementiert werden (vgl. Konzept JSF).

4.3.4.1. Token per Session (Schutzbedarf mittel und hoch)

Das CSRF-Token muss in den Formulardaten des POST-Request mitgesendet werden. Dafür wird typischerweise das versteckte Element <h:inputHidden> verwendet.

Listing 29. Verwendung eines hiddenInput Elements für die CSRF-Token Übertragung
<!-- [...] -->
<h:form>
    <!-- [...] -->
    <h:input
        type="text "
        value="${model.value}"
    />
    <h:inputHidden
        value="${_csrf.token}"
        a:name="${_csrf.parameterName}"
    />
</h:form>
<!-- [...] -->
4.3.4.2. Token per Request (Schutzbedarf sehr hoch)

Für die Variante Token per Request bietet die IsyFact keine Standardlösung an. Eine Empfehlung für die Umsetzung dieser Anforderung ist die Verwendung von spring-security-web und die Implementierung eines eigenen CsrfTokenRepository. Auch bei dieser Variante muss das von Spring bereitgestellte CSRF-Token über die POST-Requests mitgesendet werden. Da die Tokens immer nur für einen Request gültig sind, muss sichergestellt werden, dass vor jedem Request ein neues CSRF-Token vom Server abgeholt wird.

Listing 30. Ausschnitt aus isy-sicherheit-web.xml: Verwendung eines eigenen CsrfTokenRepositories
<!-- [...] -->
<security:http auto-config="true">
    <security:csrf token-repository-ref="requestCsrfTokenRepository" />
</security:http>

<bean id="requestCsrfTokenRepository"
      class="org.company.web.security.RequestCsrfTokenRepository"
      p:cookieHttpOnly="true"
/>
<!-- [...] -->

4.4. Druckaufbereitung

Für den Druck von Masken wird ein eigenes Stylesheet print.css verwendet. In diesem Stylesheet kann die Anzeige für den Druck optimiert aufbereitet werden. Zum Beispiel sollten nicht benötigte Elemente ausgeblendet und Farben für den Druck optimiert werden.

Für die Druckvorschau einer Seite sollten die benutzten Widgets so aufbereitet werden, dass alle Inhalte auf der Seite angezeigt werden (z.B. bei Tabs alle Tabs anzeigen).

Im Bedienkonzept finden sich Beispiele für Druckansichten.

Browser Druckfunktion

Für jede Seite besteht die Möglichkeit eine generische Druckansicht anzuzeigen. Diese Druckansicht kann in einem eigenen View-State definiert werden. Durch Aufruf des BasisController s wird sie aktiviert oder deaktiviert.

Beispiel:

Listing 31. Generische Druckansicht anzeigen
<view-state id="auskunftAnzeigenDruckansichtViewState" model="auskunftAnzeigenModel">
    <on-entry>
       <evaluate expression="basisController.showPrintView()"/>
    </on-entry>
</view-state>

Über den Vererbungsmechanismus zwischen XHTML Seiten oder durch Angabe einer spezifischen View kann dadurch die komplette Seite in eine Druckansicht versetzt werden. In der Druckansicht werden alle Elemente ohne JavaScript angezeigt und das Format entsprechend angepasst. Mit der Druckfunktion des Browsers kann diese dann ausgedruckt werden. Ruft man die Druckfunktion des Browsers direkt auf (ohne zuvor auf die Druckansicht geöffnet zu haben), so wird nur das angepasste CSS (print.css) verwendet. Es erfolgen keine spezifischen Anpassungen von Elementen (z.B. alle Tabs anzeigen).

Das Tag <isy:print-metainformation> kann benutzt werden, um Metainformationen zum Druck anzuzeigen. Der Inhalt dieses Tags wird nur ausgegeben, sofern die Druckansicht aktiviert ist. Es enthält den Parameter warning, der einen Text enthält, welcher ausgegeben werden soll, falls ein Nutzer die Druckfunktion des Browsers nutzt, jedoch nicht die Druckansicht aktiviert hat. Standardmäßig ist der Parameter leer.

4.4.1. Druck bestimmter Inhaltsbereiche

Neben der allgemeinen Druck-Funktion des Browsers kann der Benutzer über explizite Drucken-Buttons bestimmte Bereiche ausdrucken.

Für eine spezifische Druckansicht von Komponenten kann über einen eigenen View-State die generische Druckansicht (siehe Drucklayout) verwendet werden. Alternativ dazu können die Inhalte der Druckansicht auch selbst definiert und optimiert werden. Zur Prüfung, ob die Druckansicht aktiviert wurde, dient das BasisModel.

4.5. Temporäre Binärdaten

Für manche Anwendungsfälle in Webanwendungen wird ein Speicherort für temporäre Binärdaten benötigt. Dies ist z.B. notwendig, um dem Nutzer die Binärdaten wieder zur Verfügung zu stellen, bevor diese in einem Datenbestand gespeichert wurden (z.B. hochgeladenes Lichtbild anzeigen).

Für (temporäre) Binärdaten kann der RegisterFactory-Binärdatenservice genutzt werden. Dieser bietet die Möglichkeit Binärdaten entgegenzunehmen und einen Cleanup-Timertask, der veraltete Binärdaten automatisch wieder aufräumt. Somit ist keine Verwendung von Datenbankmitteln notwendig.

4.6. Dynamische Downloads

JSF ermöglicht über das Element <outputlink/> den Download von statischen Dateien. Der Download bzw. das Streaming von dynamisch generierten Dokumenten wird nicht von Haus aus unterstützt. Diese Funktionalität wird in der Bibliothek isy-web durch die Klasse DownloadHelper implementiert. Unterstützt wird der Download einzelner Dateien (Download von dynamische generierten Dateien) und der Download mehrerer Dateien, die in einer ZIP-Datei zusammengefasst werden (Download von dynamische generierten Dateien als ZIP-Datei).

Listing 32. Download von dynamische generierten Dateien
@Controller
public class DownloadController {

    private DownloadHelper downloadHelper;

    public void download() {
        DokumentDatenModel dokumentDatenModel = new DokumentDatenModel();
        dokumentDatenModel.setInhalt(new byte[] {'T', 'e', 's', 't'});
        dokumentDatenModel.setDateiname("Test");
        dokumentDatenModel.setDateityp(DateitypEnum.TXT);

        downloadHelper.starteDownload(dokumentDatenModel);
    }
}
Listing 33. Download von dynamische generierten Dateien als ZIP-Datei
@Controller
public class DownloadController {

    private DownloadHelper downloadHelper;

    public void downloadZip() {
        FileModel datei1 = new FileModel();
        datei1.setInhalt(new byte[] {'T', 'e', 's', 't', '1'});
        datei1.setDateiname("Test1.txt");
        datei1.setMimeType(DateitypEnum.TXT.getMimeType());

        FileModel datei2 = new FileModel();
        datei2.setInhalt(new byte[] {'T', 'e', 's', 't', '2'});
        datei2.setDateiname("Test2.txt");
        datei2.setMimeType(DateitypEnum.TXT.getMimeType());

        downloadHelper.downloadZipFileByModel("Test.zip", datei1, datei2);
    }
}

Um den DownloadHelper zu verwenden, müssen die Beans aus Konfiguration DownloadHelper als Bean konfiguriert werden. Die Einbindung erfolgt dann per Dependency Injection z.B. in einem Controller.

Listing 34. Konfiguration DownloadHelper als Bean
<bean id="zipHelper" class="de.bund.bva.isyfact.common.web.filetransfer.ZipHelper"/>

<bean id="downloadHelper" class="de.bund.bva.isyfact.common.web.filetransfer.DownloadHelper"/>

5. JSF Seitenelemente

Die IsyFact enthält die Demo-Anwendung isy-webgui.

Die Anwendung zeigt die Features der Bibliothek isy-web beispielhaft. Insbesondere demonstriert sie Aussehen und Verhalten der nachfolgend beschriebenen JSF-Seitenelemente. Für die Verwendung dieser Elemente muss in den View-Templates folgender Namespace eingebunden werden: xmlns:isy="http://java.sun.com/jsf/composite/isyfact".

5.1. Hauptfenster

Das im Bedienkonzept beschriebene Anwendungslayout besteht im Allgemeinen aus einem Hauptfenster mit einem Header und einem Inhaltsbereich, dessen Inhalt je nach Seitentyp und Applikation variieren kann.

Aufbau Applikationsseite
Abbildung 5. Aufbau einer Applikationsseite

Aufbau

  • Header-Bereich,

  • Linksnavigation (optional),

  • Inhaltsbereich.

5.1.1. Header-Bereich

Der Header-Bereich enthält allgemeine Informationen zur Anwendungslandschaft, den in ihr verfügbaren Fachanwendungen und zum angemeldeten Anwender.

header aufbau
Abbildung 6. Aufbau des Header-Bereiches

Aufbau des Header-Bereiches verdeutlicht die Teile, aus denen er besteht:

  • A Logo des Anbieters der Anwendungslandschaft

  • B Balken in der Standardfarbe der Anwendungslandschaft ("Portalfarbe")

  • C Logo der Anwendungslandschaft

  • D Informationen zum angemeldeten Anwender ("Nutzerbereich")

  • E + F Hauptnavigation und Subnavigation als Flyout (zur Nutzung siehe Horizontale Navigation)

5.1.1.1. Nutzerbereich

Der Nutzerbereich wird von der isy-web zur Verfügung gestellt. Damit der Logout bei allen Anwendungen einheitlich funktioniert, ist ein Default-Verhalten implementiert (/logout). Um das Verhalten zu überschreiben, kann die Property gui.logout.url angepasst werden.

5.1.1.2. Logos und Texte im Header-Bereich

Es besteht die Möglichkeit, für jeden Flow die folgenden Teile des Seitenrahmens anzupassen:

  • linkes Logo im Header (gui.header.logo.links.pfad),

  • rechtes Logo im Header (gui.header.logo.rechts.pfad),

  • Text unterhalb des rechten Logos im Header (gui.header.text.logo.rechts).

Um hiervon Gebrauch zu machen, muss eine entsprechende Konfigurationsdatei über die Bean-Definition eingebunden werden:

Listing 35. Konfigurationsdatei zur Anpassung des Seitenrahmens einbinden
<beans>
    ...
    <bean id="konfiguration">
        <constructor-arg>
            <list>
                ...
                <value>/resources/gui-anwendungsgruppen.properties</value>
                ...
            </list>
        </constructor-arg>
    </bean>
    ...
</beans>

Geschäftsanwendungen können globale Standardwerte definieren. Definieren sie diese nicht, verwendet der Seitenrahmen Standardwerte aus isy-web.

Tabelle 1. Globale Standardwerte für den Seitenrahmen
Parameter Standardwert

gui.header.logo.links.pfad

kein Logo

gui.header.logo.rechts.pfad

kein Logo

gui.header.text.logo.rechts

kein Text

Die gleichen Werte können Anwendungen zusätzlich auf Ebene sogenannter Anwendungsgruppen setzen, um den Seitenrahmen noch weiter an ihre Anforderungen anzupassen. Anwendungsgruppen fassen in der Regel mehrere Flows zusammen und spiegeln sich nicht selten direkt in der Hauptnavigation wider. Setzt die Anwendungen einzelne Werte für bestimmte Anwendungsgruppen nicht, werden die globalen Standardwerte (s. vorige Globale Standardwerte für den Seitenrahmen) herangezogen.

Tabelle 2. Standardwerte für den Seitenrahmen bezogen auf Anwendungsgruppen
Parameter Standardwert

gui.header.logo.links.pfad.<anwendungsgruppe>

gui.header.logo.links

gui.header.logo.rechts.pfad.<anwendungsgruppe>

gui.header.logo.rechts

gui.header.text.logo.rechts.<anwendungsgruppe>

gui.header.text.logo.rechts

Das folgende Beispiel zeigt eine vollständige Konfiguration.

Listing 36. Konfiguration zur Anpassung des Seitenrahmens
# Globale Standardwerte
gui.header.logo.links.pfad = /javax.faces.resource/img/isyfactschriftzug.jpeg
gui.header.logo.rechts.pfad = /javax.faces.resource/img/isyfactlogo.jpeg
gui.header.text.logo.rechts = IsyFact
gui.logout.url = /logout

# Defintion der Anwendungsgruppen
gui.anwendungsgruppen.ids = gruppeEins,gruppeZwei,gruppeDrei

# Zuordnung von Flows zu Anwendungsgruppen
gui.anwendungsgruppen.urls.gruppeEins = startseiteFlow,nachrichtenFlow
gui.anwendungsgruppen.urls.gruppeZwei = formulareFlow,beispiellinkFlow
gui.anwendungsgruppen.urls.gruppeDrei = validierungFlow,wizardDialogFlow

# Logos / Texte der Anwendungsgruppen
gui.header.logo.links.pfad.gruppeZwei = /javax.faces.resource/img/andererschriftzug.jpeg
gui.header.logo.rechts.pfad.gruppeZwei = /javax.faces.resource/img/andereslogo.jpeg
gui.header.text.logo.rechts.gruppeZwei = Zweite Gruppe

5.1.2. Applikationsseiten

Applikationsseiten werden über den Controller ApplikationseiteController und das Model ApplikationseiteModel realisiert.

Wenn eine Applikationsseite erstellt werden soll, dann muss der Flow der Applikationsseite vom Flow applikationseiteParentFlow erben. Es muss weiterhin ein Controller erstellt werden, der vom AbstractGuiController erbt und ein Model, das vom AbstractMaskenModel erbt. Die XHTML-Seiten der ViewStates müssen alle vom Masken-Template /WEB-INF/gui/common/layout/applikation.xhtml erben (s.a. Beispiel für eine JSF ViewState Seite mit Inhaltsbereichsangabe).

Der ApplikationseiteController stellt sicher, dass alle layoutspezifischen Funktionen (z.B. der Linksnavigation) einer Applikationsseite initialisiert und zur Verfügung gestellt werden. Abweichungen vom Standardvorgehen (z.B. Linksnavigation ausblenden) können durch Zugriff auf den Controller und Model in spezifischeren Controllern beim Initialisieren durchgeführt werden.

Neben dem ApplikationseiteController existiert auch der BasisController. Dieser bietet Zugriff auf seitentypunabhängige Layoutfunktionen (z.B. modalen Dialog anzeigen).

Siehe weiterhin die Hinweise unter Header-Bereich, Linksnavigation und Quicklinks.

5.1.3. Applikation Detailseite

Applikationsdetailseiten werden über den Controller DetailseiteController und das Model DetailseiteModel realisiert.

Wenn eine Applikationsdetailseite erstellt werden soll, dann muss der Flow der Applikationsdetailseite vom Flow detailseiteParentFlow erben. Es muss weiterhin ein Controller erstellt werden, der vom AbstractGuiController erbt und ein Model, das vom AbstractMaskenModel erbt. Die XHTML-Seiten der ViewStates müssen alle vom JSF-Masken-Template /WEB-INF/gui/common/layout/applikationDetailseite.xhtml erben.

Der DetailseiteController stellt sicher, dass alle layoutspezifischen Funktionen (z.B. der Seitentoolbar sowie Buttons in der Toolbar) einer Detailseite initialisiert und zur Verfügung gestellt werden. Abweichungen vom Standardvorgehen (z.B. Seitentoolbar ausblenden, Druckbutton einblenden, Informationsbereich einblenden) können durch Zugriff auf den Controller und Model in spezifischeren Controllern beim Initialisieren durchgeführt werden.

Neben dem DetailseiteController existiert auch der BasisController. Dieser bietet Zugriff auf seitentypunabhängige Layoutfunktionen (z.B. modalen Dialog anzeigen).

5.1.3.1. Seitentitel

Der TitlesListener (Listener für Spring-Webflow) ermöglicht es, dass konfigurierte Nachrichten anhand von Namenskonventionen automatisch als Title (Title-Tag), Headline (Titelzeile) oder Breadcrumb verwendet werden. Der TitlesListener ist automatisch eingebunden und muss nicht explizit aktiviert werden.

Folgende Angaben sind zulässig:

MAS_{FlowName}_Title
MAS_{FlowName}_{ViewState}_Title
MAS_{FlowName}_Headline
MAS_{FlowName}_{ViewState}_Headline
MAS_{FlowName}_Breadcrumb
MAS_{FlowName}_{ViewState}_Breadcrumb

Die Angaben müssen sich in den Anwendungsressourcen (analog zu anderen Nachrichten) befinden und über eine MessageSource-Bean (messageSource) der isy-web zur Verfügung gestellt werden.

Wenn vorhanden, werden stets die Angaben mit ViewState verwendet, ansonsten die Angaben ohne ViewState. In der Flowdefinition können die zu verwendenden Texte überschrieben werden, indem die Attribute titleKey, breadcrumbKey und headlineKey gesetzt werden. Wenn für den Title keine Angabe gefunden werden kann, dann wird der Wert von MAS_Global_Title verwendet. Weiterhin kann mit MAS_Global_Title_Prefix ein globaler Präfix für den Title gesetzt werden.

Weiterhin kann über eine Angabe von <ui:define name="titel"/> in Seiten definiert werden, welche Inhalte rechts neben dem bereits definierten Title (Title-Tag) ausgegeben werden. Im Folgenden ein Beispiel:

Listing 37. Zusatz-Maskentitel im Header-Bereich
<ui:define name="titel">
   <h:outputText value="zusätzlicher Text" />
</ui:define>
<!-- über die Angaben -->
<ui:define name="titelzeileInfoLinks"/>
<!-- bzw. -->
<ui:define name="titelzeileInfoRechts"/>

Es kann weiterhin definiert werden, welche Inhalte zusätzlich direkt rechts neben der Headline (Titelzeile) angezeigt werden bzw. ganz am rechten Rand der Headline angezeigt werden. Im Folgenden ein Beispiel:

Listing 38. Titelzeileninfo
<ui:define name="titelzeileInfoLinks">
   <h:outputText value="zusätzlicher Text" />
</ui:define>
<ui:define name="titelzeileInfoRechts">
   <h:outputText value="zusätzlicher Text" />
</ui:define>

5.2. Konfiguration Portalfarbe

Für eine Anwendung kann eine Basisfarbe / Portalfarbe konfiguriert werden. Von dieser portalColor werden viele der weiteren Farbstyles für die Anwendung abgeleitet und in der generierten Datei color.css abgelegt, die in der Zielanwendung einzubinden ist. Es kann zudem eine abweichende Fokusfarbe für Bedienelemente focusColor konfiguriert werden. Standardmäßig wird die portalColor auch als Fokusfarbe der Bedienelemente gesetzt.

Zur Generierung der Datei color.css mit der eigenen Portalfarbe sind folgende Schritte erforderlich:

  1. Konfiguration der Portalfarbe: In der Datei isy-web-lib/src/main/less/portal-color.less des isy-web Repositories ist die Basisfarbe / Portalfarbe zu setzen. Hier kann auch eine abweichende Fokusfarbe für Bedienelemente konfiguriert werden.

Listing 39. Portalfarbe konfigurieren
@portal-color: #004179;
@focus-color: @portal-color;

@es-portal-color-100: @portal-color;
@es-portal-color-80: tint(@portal-color, 20%);
@es-portal-color-60: tint(@portal-color, 40%);
@es-portal-color-40: tint(@portal-color, 60%);
@es-portal-color-20: tint(@portal-color, 80%);
@input-border-focus: @focus-color;

@import "es/color/color-base";
  1. Maven Install: In dem Modul isy-web-lib ist ein "Maven install" durchzuführen. Dadurch wird ein "webpack build" ausgelöst und die Farbstyles befinden sich nach der Generierung in target/classes/META-INF/resources/css/color.css.

  2. Einbindung in Zielanwendung: Die Datei color.css aus dem Target-Verzeichnis von isy-web-lib ist in die Zielanwendung unterhalb des WEB-INF Verzeichnisses zu kopieren.

color css position
Abbildung 7. Zielordner für color.css Datei

5.3. Modaler Dialog

Modale Dialoge werden mit dem Tag <isy:modalDialogContent> definiert. Der Dialog besitzt folgende Facets:

  • Der Header-Bereich,

  • Der Body-Bereich,

  • Der Footer-Bereich.

demoflow modaler dialog
Abbildung 8. Beispiel eines modalen Dialogs

Das Tag <isy:modalDialogContent> wird über den UI-Platzhalter modalDialog eingefügt. Dieser Platzhalter sorgt dafür, dass je nach Verfügbarkeit von JavaScript, der Inhalt des modalen Fensters entweder als Inhalt oder als eigenständiger Dialog gerendert wird. Die Funktionsweise des modalen Dialogs ist in das Basis-Layout eingebunden. Um einen Dialog zu öffnen, muss dieser als eigener View-State (in Spring Webflow) definiert werden. Beim Eintreten in den Flow wird das modale Fenster über einen Aufruf des BasisController geöffnet. Beim Verlassen des View-States wird dieser wieder geschlossen.

Listing 40. Modaler Dialog
<ui:define name="modalDialog">
   <isy:modalDialogContent>
     <f:facet name="modalHeader">\{msg.MEL_Lichtbild_anzeigen_Titel}</f:facet>
     <f:facet name="modalBody">
     <div class="form-horizontal">
        ...
     </div>
     </f:facet>
     <f:facet name="modalFooter">
        <div class="form-horizontal readonly">
           ...
        </div>
      </f:facet>
   </isy:modalDialogContent>
 </ui:define>

Um im Hintergrund weiterhin das aktuelle Fenster anzuzeigen, genügt es den bisherigen View-State entsprechend zu vererben.

Listing 41. Öffnen und Schließen von modalen Dialogen
<view-state id="lichtbildAnzeigenViewState" model="maskenModel">
   <on-entry>
      <evaluate expression="basisController.showModalDialog()"/>
   </on-entry>

   ...

   <transition on="schliesseModalenDialog" to="gesamtauskunftAnzeigenViewState">
      <evaluate expression="basisController.hideModalDialog()"/>
   </transition>

</view-state>

5.4. Bestätigungsdialog

Bestätigungsdialoge, auch Popup-Dialoge genannt, sind spezielle modale Dialoge, die als Subflows eingebunden werden. Die anzuzeigenden Texte und Button-Beschriftungen werden dem Flow als Parameter übergeben. Bestätigungsdialoge sind daher einfach und vielfältig einsetzbar und eignen sich immer, wenn der Benutzer vor eine "Ja/Nein Entscheidung" gestellt werden soll. Sollte kein Java-Script aktiviert sein, so wird der Dialog direkt im Fenster angezeigt.

demoflow bestaetigungs dialog
Abbildung 9. Beispiel eines Bestätigungsdialogs (Popup-Dialog)

Bei einem Bestätigungsdialog können auch mehrzeilige Texte hinterlegt werden. Hierfür ist es möglich, eine Nachricht aus einer weiteren Ressource einzubinden. Der Parameter “dialogNachricht” wird in diesem Falle nicht zwingend benötigt (required="false").

Bei Verwendung des Parameters "dialogNachrichtPfad" wird die "dialogNachricht" nicht angezeigt. Die anzuzeigenden Texte aus einer weiteren Ressource werden dem Flow als neuer Parameter "dialogNachrichtPfad" übergeben (siehe Bestätigungsdialog - subflow mit Parametern).

Falls der anzuzeigende Text für den Abbrechen-Button nicht dem Flow übergeben wurde, wird der Default-Text zu "MEL_Button_Abbrechen" aus den maskentexte.properties geladen.

Listing 42. Bestätigungsdialog - subflow mit Parametern
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
    parent="applikationseiteParentFlow">

    <var name="modalerDialogModel" class="de.bund.bva.pliscommon.pliswebgui.gui.flows.modalerdialog.ModalerDialogModel" />
    <var name="bestaetigungsdialogModel" class="de.bund.bva.pliscommon.pliswebgui.gui.flows.modalerdialog.BestaetigungsdialogModel" />
 ...
 ...
    <subflow-state id="demoBestaetigenSubflowState" subflow="bestaetigenFlow">
        <input name="dialogTitel" value="'Ein Beispieltitel: Achtung, sind Sie sich sicher...'" />
        <input name="dialogNachricht" value="'Eine Beispielnachricht: Sind Sie sicher, dass sie fortfahren wollen?'" />
        <input name="dialogNachrichtPfad" value="'/WEB-INF/gui/common/eingebundeneNachricht.xhtml'" />
        <input name="dialogKonsequenz" value="'Eine beispielhafte Konsequenz (Angabe optional): Nicht gespeicherte Änderungen gehen verloren.'" />
        <input name="submitActionName" value="'Fortfahren'" />
        <!-- <input name="abbrechenActionName" value="'Abbrechen'" /> -->
        <transition on="abbrechenEndState" to="modalerDialogViewState" >
          <evaluate expression="bestaetigungsdialogController.abbrechen(bestaetigungsdialogModel)" />
        </transition>
        <transition on="submitEndState" to="modalerDialogViewState">
          <evaluate expression="bestaetigungsdialogController.bestaetige(bestaetigungsdialogModel)" />
        </transition>
    </subflow-state>
</flow>

5.5. Wizard

Wizards, auch Assistenten genannt, bezeichnen eine geführte Abfolge von Interaktionsschritten.

Wizard Beispiel Schritt 2
Abbildung 10. Beispiel eines Wizards

Wizards werden mit dem Tag <isy:wizard> definiert.

Der Wizard besitzt folgende Facets:

  • wizardHeader: Der Header-Bereich,

  • wizardBody: Der Body-Bereich,

  • wizardFooterLeftButtons: Ergänzungen zu den angezeigten Buttons auf der linken Seite,

  • wizardFooterRightButtons: Ergänzungen zu den angezeigten Buttons auf der rechten Seite.

Die Komponente besitzt folgende notwendige Parameter:

  • wizardDialogModel: Das Model des Wizards. (Typ: de.bund.bva.isyfact.common.web.jsf.components.wizard.WizardDialogModel)

Außerdem gibt es folgende optionale Parameter:

  • width: Die Breite des modalen Dialogs (Standard: auto),

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig.

  • stepVisible: Gibt an, ob die Step Nummer gezeigt werden soll. (Standard: true, Typ: Boolean )

Listing 43. Modaler Wizard
<isy:wizard wizardDialogModel="#{wdm}">
   <f:facet name="wizardHeader">Testheader</f:facet>
   <f:facet name="wizardBody">
       <ui:param name="aktuelleWizardSeite" value="#{wdm.getActiveWizardDialogPage()}" />
       <!-- In Abhängigkeit der ID werden die entsprechenden Seiten angezeigt. -->
       <ui:fragment rendered="#{wdm.getActiveWizardDialogPageId().equals('1')}">
          <ui:include src="page1.xhtml" />
       </ui:fragment>
       <ui:fragment rendered="#{wdm.getActiveWizardDialogPageId().equals('2')}">
          <ui:include src="page2.xhtml" /> </ui:fragment>
       <ui:fragment rendered="#{wdm.getActiveWizardDialogPageId().equals('3')}">
          <ui:include src="page3.xhtml" />
       </ui:fragment>
       <ui:fragment rendered="#{wdm.getActiveWizardDialogPageId().equals('4')}">
          <ui:include src="page4.xhtml" />
       </ui:fragment>
   </f:facet>
</isy:wizard>

Eine einzelne Seite eines Wizards wird über ein Objekt des Typs WizardDialogPage definiert. Eine WizardDialogPage hat u.A. folgende Attribute:

  • wizardDialogPageId: Eine ID, welche die Wizardseite eindeutig innerhalb des Wizards identifiziert.

  • title: Title der Wizardseite,

  • pageDone: Seite wurde abgearbeitet.

  • pageSuccessful: Seite wurde erfolgreich oder nicht erfolgreich abgearbeitet.

  • pageDisabled: Seite wurde deaktiviert.

Jeder Wizard besitzt die folgenden, vordefinierten Buttons:

  • previous: zurück zur vorherigen Seite,

  • next: weiter zur nächsten Seite,

  • complete: Wizard abschließen,

  • abort: Wizard abbrechen.

Für jeden dieser Buttons gibt es die folgenden Einstellungen:

  • activated: Gibt an, ob der Button aktiviert ist. (Standard: false)

  • visible: Gibt an, ob der Button sichtbar ist. (Standard: true)

  • ajaxActivated: Gibt an, ob die Aktion per AJAX ausgeführt werden soll. (Standard: true)

  • ajaxAction: Welche Felder bei einem AJAX-Aufruf ausgewertet werden. (Standard: @form)

  • ajaxRender: Welcher Seitenbereich nach dem AJAX-Aufruf aktualisiert wird. (Standard: @form)

  • ajaxBlock: Gibt an, ob die GUI während des AJAX-Aufrufs blockiert. (Standard: false)

Weiterhin benötigt ein Wizard ein Model des Typs WizardDialogModel. Ein WizardDialogModel hat folgende Attribute und Methoden:

  • activeWizardDialogPageId: ID der derzeit aktiven Seite,

  • activeWizardDialogPage: momentan aktive Seite,

  • nextActiveWizardDialogPageId: ID der nächsten Seite,

  • wizardDialogPages: Liste der einzelnen Seiten des Wizards (WizardDialogPage-Objekte),

  • boolean isPageDone(String id): Gibt an, ob die Seite mit der angegebenen ID bereits abgearbeitet wurde.

  • boolean isPageDisabled(String id): Gibt an, ob die Seite mit der angegebenen ID deaktiviert ist.

  • WizardDialogPage getWizardDialogPage(String wizardDialogPageId): Gibt die Seite zur angegebenen ID zurück.

Für die Verwendung eines Wizards muss ein Controller erstellt werden, der vom WizardDialogController erbt. Folgende Methoden müssen dabei überschrieben werden:

  • boolean finish(WizardDialogModel model) beendet die Verarbeitung des Wizards.

  • boolean cancel(WizardDialogModel model) bricht die Verarbeitung ab.

Folgende Methoden können genutzt und optional überschrieben werden:

  • initializeDefaultPages(WizardDialogModel model) initialisiert die Pages des Wizards mit dem Standardverhalten,

  • boolean next(WizardDialogModel model) ruft die nächste Seite auf,

  • boolean previous(WizardDialogModel model) ruft die vorherige Seite auf.

5.6. Dialoge ohne JavaScript

no js
Abbildung 11. Kein Javascript

Die modalen Dialoge werden automatisch in das Layout integriert, sofern kein JavaScript verfügbar ist.

Menuepunkt Flows
Abbildung 12. Kein JavaScript – Dialog
Kein Javascript Wizard
Abbildung 13. Kein JavaScript – Wizard

6. JSF Bedienelemente

Der JSF-Baustein stellt JSF Composite Components als Bedienelemente für Web-GUIs zur Verfügung. Für die Verwendung dieser Elemente muss in den View-Templates folgender Namespace eingebunden werden: xmlns:isy="http://java.sun.com/jsf/composite/isyfact".

Die Bedienelemente stellen im Grundsatz folgendes sicher:

  • JavaScript-Kompatibilität: Komponenten bieten eine Fallback-Lösung an, falls kein JavaScript aktiviert ist.

  • Druckfunktion: Komponenten stellen eine Druckansicht zur Verfügung, falls die Druckansicht aktiviert wurde.

  • Validierung: Die speziellen Formularkomponenten stellen Validierungsfunktionen zur Verfügung, sodass bei Validierungsfehlern automatisch Nachrichten und Tooltips (inkl. Abwärtskompatibilität, falls kein JavaScript aktiviert wurde) gerendert werden.

Abweichungen zu diesen Vorgaben können im Spezialfall möglich sein.

Die IsyFact enthält die Demo-Anwendung isy-webgui.

Die Anwendung zeigt die Features der Bibliothek isy-web beispielhaft. Insbesondere demonstriert sie Aussehen und Verhalten der nachfolgend beschriebenen JSF-Bedienelemente.

6.1. Button

Ein einfacher Button wird über das Tag <isy:button> eingebunden.

demopanel button
Abbildung 14. Beispiele für <isy:button> Aktionen (Normal, Ajax, Formular)

Die Komponente besitzt folgende notwendige Parameter:

  • action: Die auszuführende Aktion,

  • value: Das Label des Buttons,

Außerdem gibt es folgende optionale Parameter:

  • styleClass: Die zu ergänzenden Style-Klassen,

  • disabled: Gibt an, ob der Button deaktiviert ist oder nicht. (Standard: false, Typ: Boolean)

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • ajax: AJAX: Soll eine AJAX Aktion ausgeführt werden. (Standard: true, Typ: Boolean)

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • block: AJAX: Gibt an, ob ein Klick die GUI blockieren soll bis das Ergebnis eingetroffen ist. (Standard: false, Typ: Boolean)

  • defaultAction: AJAX: Gibt an, ob dieser Knopf die defaultAction des Formulars sein soll. (Standard: false, Typ: Boolean)

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

Wenn JavaScript aktiviert ist, dann wird die AJAX-Action durchgeführt. Andernfalls wird immer ein Full-Page-Reload ausgeführt.

Einen Button, bei dem die Oberfläche während der Ajax-Aktion blockiert ist, würde man Einbindung über <isy:button> mit dem block="true" einbinden.

Listing 44. Codebeispiel für <isy:button>
<isy:button
  id="buttonBlockTest"
  action="blockButtonAction"
  value="Button (Block)"
  block="true"/>

6.1.1. Mehrere Buttons in einer Zeile

Mehrere Buttons können in einer Zeile gruppiert werden, indem sie in das Tag <isy:buttonRow> eingeschlossen werden.

demopanel buttonRow
Abbildung 15. Beispiel für <isy:buttonRow> mit <isy:buttonToolbar>

Folgende optionale Parameter sind für das Tag <isy:buttonRow> zulässig:

  • alignRight: Gibt an, ob die Button Row ein Alignment nach rechts besitzen soll. (Standard: false, Typ: Boolean)

  • styleClass: Zusätzliche Style-Klassen für die Button-Row. (Standard: ``)

Listing 45. Codebeispiel für <isy:buttonRow>
<isy:buttonRow>
	<isy:buttonToolbar
		icon="placeholder"
		value="Button 1"
		action="noAction"/>
	<isy:buttonToolbar
		icon="placeholder"
		value="Button 2"
		action="noAction"/>
</isy:buttonRow>

6.1.2. Gruppierung von mehreren Buttons

Mehrere Buttons können gruppiert werden, indem sie in das Tag <isy:buttonGroup> eingeschlossen werden. Der Hauptanwendungszweck dieses Tags ist die gemeinsame Ausrichtung der Buttons auf der Maske.

Folgende optionale Parameter sind für das Tag <isy:buttonGroup> zulässig:

  • alignRight: Gibt an, ob die Button Row eine Alignment nach rechts besitzen soll oder nicht (Standard: false, Typ: Boolean).

  • alignLeft: Gibt an, ob die Button Row eine Alignment nach links besitzen soll oder nicht (Standard: false, Typ: Boolean).

Listing 46. Codebeispiel für <isy:buttonGroup>
<f:facet name="tableToolbar">
    <isy:buttonGroup>
        <isy:buttonToolbar />
    </isy:buttonGroup>
</f:facet>

6.1.3. Mehrere Aktionen

In bestimmten Fällen kann es notwendig sein mehrere Formulare an den Server zu senden, um bestimmte Aktionen auszuführen (z.B. das Formular für den Inhaltsbereich soll auch beim Klick auf Drucken in der Seitentoolbar übermittelt werden). Dies kann durch Verwenden des Tags <isy:buttonInjectPost> erreicht werden. Dadurch lässt sich eine andere Aktion vor der eigentlichen Aktion des Buttons innerhalb des Tags ausführen.

Folgende Parameter sind notwendig:

  • postButton: Die ID des Buttons, der die zusätzliche POST-Aktion durchführen soll.

  • continueAfterPost: Über diesen Wert true/false kann gesteuert werden, ob nach der POST-Aktion auch tatsächlich der eigentliche Button geklickt werden soll (z.B. um Fehlerfälle abzufangen).

6.2. Button Toolbar

Eine Button-Toolbar wird über das Tag <isy:buttonToolbar> eingebunden. Die Buttons innerhalb der Toolbar können sowohl horizontal als auch vertikal angeordnet sein.

Die folgende Abbildung zeigt z.B. die Verwendung der Komponente <isy:buttonToolbar> oberhalb einer DataTable-Komponente.

demopanel toolbarButton
Abbildung 16. <isy:buttonToolbar> mit Button-Komponenten

Eine Button-Toolbar besitzt folgende notwendige Parameter:

  • action: Die auszuführende Aktion.

Außerdem gibt es folgende optionale Parameter:

  • value: Der Wert/Text des Buttons, (Standard: ``)

  • icon: Das Icon aus der Icon-Bibliothek (ohne Präfix 'icon-'). (Standard: placeholder)

  • showIcon: Gibt an, ob ein Icon angezeigt werden soll oder nicht. (Standard: true, Typ: Boolean)

  • reverseIconPosition: Gibt an, ob das Icon rechts angezeigt werden soll. (Standard: false, Typ: java.lang.Boolean)

  • disabled: Gibt an, ob der Button deaktiviert sein soll. Standard: false. (Standard: false, Typ: java.lang.Boolean)

  • showPrintView: Gibt an, ob der Button innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • ajax: AJAX: Soll eine AJAX Aktion ausgeführt werden. (Standard: true)

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • globalConfig: Eine spezifische globale Konfiguration, falls nötig. (Standard: #{globalConfigurationModel})

Wenn JavaScript aktiviert ist, dann wird die AJAX-Action durchgeführt. Andernfalls wird immer ein Full-Page-Reload durchgeführt.

Folgende Action-Sources werden bereitgestellt:

  • buttonActionEvent: Das Action-Event für den Button.

Listing 47. Codebeispiel für <isy:buttonToolbar>, vertikale Darstellung
<f:facet name="panelHeader">Toolbar Buttons</f:facet>

<isy:buttonToolbar
	icon="placeholder"
	value="Button mit Icon"
	action="noAction"/>

<isy:buttonToolbar
    showIcon="false"
	value="Button ohne Icon"
	action="noAction"/>

Weitere Codebeispiele für das Tag <isy:buttonToolbar> siehe Beispiel für <isy:dataTable> Verwendung und Codebeispiel für <isy:buttonRow>

6.2.1. Toggle Button

Ein Toggle Button wird über das Tag <isy:buttonToggle> eingebunden.

Ein Toggle Button besitzt folgende notwendige Parameter:

  • action: Die auszuführende Aktion.

Außerdem gibt es folgende optionale Parameter:

  • buttonId: Eindeutige ButtonId,

  • value: Der Wert/Text des Buttons, (Standard: ``)

  • icon: Das Icon aus der Icon-Bibliothek (ohne Präfix 'icon-'), (Standard: placeholder)

  • showIcon: Gibt an, ob ein Icon angezeigt werden soll oder nicht. (Standard: true, Typ: Boolean)

  • reverseIconPosition: Gibt an, ob das Icon rechts angezeigt werden soll. (Standard: false, Typ: java.lang.Boolean)

  • disabled: Gibt an, ob der Button deaktiviert sein soll. Standard: false. (Standard: false, Typ: java.lang.Boolean)

  • active: Gibt an, ob der Button ausgewählt sein soll. Standard: false. (Standard: false, Typ: java.lang.Boolean)

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • globalConfig: Eine spezifische globale Konfiguration, falls nötig. (Standard: #{globalConfigurationModel})

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

Folgende Action-Sources werden bereitgestellt:

  • toggleButton: Das Action-Event für den Button.

6.2.2. Icon Button

Ein Button mit Icon wird über das Tag <isy:buttonIcon> eingebunden.

Ein Icon Button besitzt folgende notwendige Parameter:

  • action: Die auszuführende Aktion.

Außerdem gibt es folgende optionale Parameter:

  • value: Das Label des Buttons, (Standard: ``)

  • size: Die Größe des Icons, (Mögliche Werte: small/large. (Standard: large))

  • icon: Der Suffix des zu verwendenden Icons, (Standard: placeholder)

  • showIcon: Gibt an, ob das Icon angezeigt werden soll oder nicht. (Standard: true, Typ: java.lang.Boolean)

  • tooltip: Tooltip, der über dem Icon angezeigt werden soll. (Standard: ``)

  • disabled: Gibt an, ob der Button deaktiviert ist oder nicht. (Standard: false, Typ: Boolean)

  • btnClass: Die CSS-Klasse, welche für Buttons ergänzt werden soll. (Standard: ``)

  • ajax: AJAX: Soll eine AJAX Aktion ausgeführt werden. (Standard: true, Typ: Boolean)

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • block: AJAX: Gibt an, ob ein Klick die GUI blockieren soll bis das Ergebnis eingetroffen ist. (Standard: false, Typ: Boolean)

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

Folgende Action-Sources werden bereitgestellt:

  • buttonActionEvent: Das Action-Event für den Button.

Wenn JavaScript aktiviert ist, dann wird die AJAX-Action durchgeführt. Andernfalls wird immer ein Full-Page-Reload durchgeführt.

Hyperlinks sind verlinkte Texte (oder auch Grafiken), die im Wesentlichen zur Navigation zwischen Seiten dienen. Ebenso können Hyperlinks dazu eingesetzt werden, Funktionen aufzurufen.

Links können mit dem Standard-HTML Tag <a/> oder durch Nutzung des JSF Tags <h:outputLink/> erzeugt werden.

Auch die Nutzung des JSF Tags <h:commandLink /> ist möglich. Jedoch ist die Funktionalität nur bei aktiviertem JavaScript nutzbar. Entsprechende Fallbackmaßnahmen müssen also getroffen werden.

Falls ein Hyperlink Aktionen im Webflow bzw. JSF ausführen soll, so kann das Tag <isy:hyperlink> verwendet werden. Dieses Tag stellt sicher, dass falls JavaScript deaktiviert ist, ein Button mit Layout eines Links dargestellt wird.

Ein Hyperlink besitzt folgende optionale Parameter:

  • action: Die Action, die ausgeführt werden soll,

  • value: Das Label des Links,

  • title: Der Alternativtext,

  • baseStyleClass: Die Basis-CSS-Klasse zum Überschreiben, (Standard: cmdbtn-link)

  • additionalStyleClass: Eine zusätzliche Styleklasse, (Standard: ``)

  • openInNewTab: Gibt an, ob der Link in einem neuen Tab geöffnet werden soll. Funktioniert nur mit aktiviertem JavaScript. (Standard: false, Typ: Boolean)

Das Tag stellt folgende ActionSource bereit:

  • hyperlink: Die ActionSource des Links.

6.3. Label

Ein Label besteht in der Regel aus einem Text. In manchen Fällen kann es auch eine Kombination aus einem Icon und einem Text sein (z.B. Buttons mit Icon und Text). Es gibt auch Bedienelemente, deren Label ausschließlich aus einem Icon bestehen.

Für reine Labels existieren keine spezifischen JSF-Komponenten. Das Standard-JSF Tag <h:outputText/> kann verwendet werden. Für formularbasierte Masken werden automatisch Labels für Eingabefelder erzeugt, wie in Eingabefelder beschrieben. Für das Ausgeben eines Textes (mit zugehörigem Label) in einem Formular kann das Tag <isy:formLabel> verwendet werden.

Es besitzt folgende optionale Parameter:

  • reference: Referenz des Objekts für die Validierung,

  • value: Text des Ausgabebereichs,

  • label: Text des Labels,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Ausgabebereiches, (Standard: col-lg-6)

  • textStyleClass: Die CSS-Klasse des auszugebenden Textes,

  • tooltip: Tooltip des Ausgabebereichs,

  • escapeLabel: Gibt an, ob Sonderzeichen für das Label escaped werden sollen. (Standard: true)

  • breakWords: Gibt an, ob der Überlauf von Text in die nächste Zeile erlaubt ist. (Standard: true)

  • converter: ID des JSF-Converters, welche die Ausgabe in einen Text konvertiert. (Standard: leer)

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

6.4. Eingabefelder

Eingabefelder dienen der Eingabe von Text durch den Benutzer und sind in der Regel einzeilig.

Für einzelne Eingabefelder existieren derzeit noch keine einfachen Komponenten. Um ein einfaches Eingabefeld einzufügen, kann das JSF-Tag <h:inputText/> mit der CSS-Klasse form-control von Bootstrap verwendet werden. Für formularbasierte Eingaben existiert das Tag <isy:formInput/>, welches ein Eingabefeld in einem Formularlayout mit Label kapselt. Nähere Informationen hierzu finden sich in Layout von Formularen.

Ein Eingabefeld besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • type: Typ des Eingabefelds, sodass diese Komponente z.B. auch für Passwort-Felder verwendet werden kann. Mögliche Werte sind alle Werte für das Feld type des HTML-Tags input. (Standard: text)

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • inputmask: Eingabemaske,

  • inputmaskInsertMode: Gibt an, ob der Text bei der Eingabe überschrieben wird. (Standard: true)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255)

  • width: Die maximale Breite des Eingabefeldes, (Standard: 100%)

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • showPrintView: Spezifisches Flag zur Erkennung der Druckansicht, (Standard: basisModel.showPrintView)

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: '')

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration, (Standard: globalConfigurationModel)

  • charpicker: Gibt an, welche Eingabe für Sonderzeichen verwendet werden soll. Wird der Wert auf dinNorm gesetzt, wird der Character-Picker verwendet, welcher alle Zeichen der DIN NORM 91379 unterstützt. Für Rückwärtskompatibilität kann weiterhin der Wert dinSpec verwendet werden. Soll der alte Legacy-Character-Picker verwendet werden, muss der Wert auf special gesetzt werden. Standardmäßig wird kein Character-Picker verwendet.

Eingabefelder besitzen folgende Facets:

  • contentRight: Inhalt, der rechts vom Eingabefeld angezeigt wird.

6.4.1. Character-Picker

Eingabefelder besitzen die Möglichkeit einen Character-Picker (kurz: CharPicker) für die Eingabe von Sonderzeichen einzublenden. Dazu muss, wie im folgenden Beispiel (Verwendung vom CharPicker), der Parameter charpicker auf den Wert dinNorm gesetzt werden, um den CharPicker zu verwenden, welcher die Sonderzeichen der DIN NORM 91379 unterstützt:

Listing 48. Verwendung vom CharPicker
<isy:formInput id="formInputSpecialCharDinNorm" type="text"
    label="DIN NORM 91379 CharPicker: "
    reference="formInputSpecialChar" value="Ein Special Char Textfeld"
    charpicker="dinNorm" datentyp="DATENTYP_A"/>

Der Parameter datentyp gibt an, welche Sonderzeichen vom CharPicker unterstützt werden sollen. Zur Auswahl stehen folgende Optionen:

  • DATENTYP_A,

  • DATENTYP_B,

  • DATENTYP_C,

  • DATENTYP_D,

  • DATENTYP_E.

Für den Fall, dass kein Parameter gewählt wird, werden alle Zeichen aus DATENTYP_E verwendet. Alternativ kann der Parameter charpicker auf den Wert special gesetzt werden, um den alten CharPicker zu verwenden. Dieser unterstützt nur die Schriftzeichen aus String.Latin 1.1, also deutlich weniger Zeichen. Ein Eingabefeld mit CharPicker besitzt, wie in Eingabefeld mit CharPicker zu sehen, einen Button auf der rechten Seite, mit dem sich der CharPicker öffnen lässt.

charpicker button
Abbildung 17. Eingabefeld mit CharPicker

Der CharPicker (zu sehen in CharPicker nach DIN NORM 91379) besteht aus folgenden Komponenten:

  • Die Leiste links erlaubt eine Auswahl von Kategorien, nach denen die Zeichen gefiltert werden können.

  • In der rechten Box werden die Sonderzeichen angezeigt und lassen sich per Mausklick auswählen.

  • Darunter befindet sich eine Detailansicht. Für eine bessere Übersicht werden die Schriftzeichen dort in groß, sowohl in einer Serifen- als auch in einer serifenlosen Schrift dargestellt. Rechts davon wird der Name und der Unicode-Codepoint des Symbols angezeigt. Mit dem Button Einfügen kann man bestätigen, dass das Symbol in das Eingabefeld eingefügt werden soll.

charpicker widget
Abbildung 18. CharPicker nach DIN NORM 91379

Alternativ kann der CharPicker auch mit den folgenden Eingaben mit der Tastatur bedient werden:

  • Alt+Runter öffnet den CharPicker, wenn das Eingabefeld fokussiert ist.

  • Alt+Hoch bzw. Escape schließt den CharPicker.

  • Pfeiltasten können zum Auswählen von Schriftzeichen verwendet werden.

  • Mit Enter wird das ausgewählte Schriftzeichen in das Eingabefeld eingefügt.

  • TAB wechselt zur nächsten Kategorie.

  • Shift+TAB wechselt zur vorherigen Kategorie.

6.5. Eingabefelder ohne Label

Für Eingabefelder ohne Label existiert das Tag <isy:input>.

Ein Eingabefeld ohne Label besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • type: Typ des Eingabefelds, sodass diese Komponente z.B. auch für Passwort-Felder verwendet werden kann. Mögliche Werte sind alle Werte für das Feld type des HTML-Tags input. (Standard: text)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • inputmask: Eingabemaske,

  • inputmaskInsertMode: Gibt an, ob der Text bei der Eingabe überschrieben wird. (Standard: true)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255)

  • width: Die maximale Breite des Eingabefeldes, (Standard: 100%)

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • showPrintView: Spezifisches Flag zur Erkennung der Druckansicht, (Standard: basisModel.showPrintView)

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: '')

  • globalConfig: Spezifische, globale Konfiguration, (Standard: globalConfigurationModel)

  • charpicker: Gibt an, welche Eingabe für Sonderzeichen verwendet werden soll. Wird der Wert auf dinNorm gesetzt, wird der neue Character-Picker verwendet, welcher alle Zeichen der DIN NORM 91379 unterstützt. Für Rückwärtskompatibilität kann weiterhin der Wert dinSpec verwendet werden. Soll der alte Legacy-Character-Picker verwendet werden, muss der Wert auf special gesetzt werden. Standardmäßig wird kein Character-Picker verwendet.

Eingabefelder besitzen folgende Facets:

  • contentRight: Inhalt, der rechts vom Eingabefeld angezeigt wird.

Der CharPicker funktioniert wie im Abschnitt Character-Picker beschrieben.

6.5.1. Aktionseingabefeld

Für Aktionseingabefelder existieren die Tags <isy:actionInput> bzw. <isy:formActionInput>.

Aktionseingabefeld
Abbildung 19. Aktionseingabefeld

Ein Aktionseingabefeld besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • action: Die auszulösende Aktion,

  • icon: Das anzuzeigendes Icon aus der Icon-Bibliothek.

Außerdem gibt es folgende optionale Parameter:

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • maxlength: Die maximale Länge der Eingabe, (Standard: 20)

  • iconColor: Farbe des Icons, (Standard: #45484D)

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: …​)

  • mode: [normal|button-only|input-only]. normal für Eingabefeld und Icon aktiv, button-only für nur Icon aktiv, input-only für nur Eingabefeld aktiv, (Standard: normal)

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

Folgende Parameter sind zusätzlich zu den eben genannten für <isy:formActionInput> zulässig:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

6.5.2. Eingabefeld für Geldbeträge

Für die Eingabe von Geldbeträgen existiert das Tag <isy:formCurrencyInput>. Dieses Bedienelement verhält sich bis auf wenige Ausnahmen wie <isy:formInput>. Das Eingabefeld für Geldbeträge:

  • besitzt kein Attribut inputmask, da sich diese nicht mit der JavaScript-Funktion verträgt, welche die Daten formatiert.

  • lässt nur die Eingabe von Zahlen und Kommata zu; alle anderen Zeichen werden direkt nach Eingabe sofort wieder gelöscht.

  • besitzt das Attribut onchange - dort kann eine JavaScript-Funktion übergeben werden, die aufgerufen wird, sobald der Cursor das Feld verlässt.

  • rundet die eingegebene Zahl ab einer Länge von mehr als 15 Ziffern automatisch. Daraus lassen sich folgende Beispiele ableiten:

    • Ohne Nachkommastelle ist 999999999999999,

    • für 1 Nachkommastelle ist 99999999999999,9,

    • für 2 Nachkommastellen ist 9999999999999,99 der maximale Betrag ohne Rundung.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels,(Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255)

  • width: Die maximale Breite des Eingabefeldes, (Standard: 100%)

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: '')

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration, (Standard: globalConfigurationModel)

  • onchange: JavaScript-Funktion, die bei Verlassen des Feldes aufgerufen wird.

  • onkeyup: JavaScript-Funktion, die direkt nach einer Eingabe aufgerufen wird.

  • decimalplaces: Anzahl der Nachkommastellen, (Standard: 2)

  • alignright: Gibt an, ob der Text innerhalb des Eingabefeldes rechts ausgerichtet sein soll. (Standard: false)

6.5.3. Upload

Für den Upload von Dateien existiert das Tag <isy:formUpload>.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • accept: Einschränkung der angenommenen Dateien gemäß ihres MIME-Types,

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: '')

  • showPrintView: Spezifisches Flag zur Erkennung der Druckansicht, (Standard: basisModel.showPrintView)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

6.5.4. Textbox

Eine Textbox kann über das HTML-Tag <textarea> mit der CSS-Klasse form-control von Bootstrap eingebunden werden.

Textboxen sehen optisch aus wie Eingabefelder, es können jedoch mehrzeilige Daten eingegeben werden.

Textbox
Abbildung 20. Textbox

Für Formulare kann das Tag <isy:formTextarea> verwendet werden.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • textareaStyleClass: Die CSS-Klasse der Textbox, (Standard: leer)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: '')

  • rows: Anzahl an Zeilen, (Standard: 5)

  • cols: Anzahl an Spalten,

  • maxlength: Die maximale Länge der Eingabe, (Standard: 4000)

  • showPrintView: Spezifisches Flag zur Erkennung der Druckansicht, (Standard: basisModel.showPrintView)

  • validationModel: Ein spezifisches Validation-Model, falls diese benötigt wird. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

6.5.5. Date Picker

Mit dem Date Picker können Anwender über einen Kalender gezielt einen Tag auswählen. Der Kalender öffnet sich nach einem Klick auf das Icon neben dem Eingabefeld.

Der Date Picker wird über das Tag <isy:formDate> eingebunden.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • label: Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • inputFieldClass: Die CSS-Klasse des Eingabefeldes, (Standard: leer)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird. (Standard: TT.MM.JJJJ)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • language: Angezeigte Sprache, (Standard: de)

  • dateformat: Datumsformat, (Standard: dd.mm.yyyy)

  • inputmask: Eingabemaske,

  • inputmaskInsertMode: Gibt an, ob der Text bei der Eingabe überschrieben wird. (Standard: true)

  • inputmaskClearOnBlur: Gibt an, ob beim Verlassen des Feldes die Maskierungsplatzhalter ausgeblendet werden. (Standard: true)

  • showPicker: Gibt an, ob der Kalender angezeigt wird. (Standard: true)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

Für den Datepicker wird ein externes Plug-In verwendet. Das Bedienelement selbst bietet eine automatische Konfiguration des Plug-Ins sowie eine zum Rest der JSF-Bedienelemente einheitlich Schnittstelle.

Mit einem Dropdown Menü kann der Benutzer per Mausklick oder Tastatur-Bedienung genau einen Wert aus einer Liste von Optionen auswählen.

Ein Dropdown Menü wird über das Tag <isy:selectOneDropdown> eingebunden. Für Formulareingaben existiert das Tag <isy:formSelectOneDropdown>.

Dropdown Menue Flyout
Abbildung 21. Dropdown Menü (innerhalb einer Form)
demopanel selectOneDropdown
Abbildung 22. Demo-Anwendung: Dropdown Menü (außerhalb einer Form)

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts.

  • value: Der Wert für das Databinding in der Auswahl

Außerdem gibt es folgende optionale Parameter:

  • reference: Wert der ID

  • invalid: Gibt an, ob die Auswahl invalide ist. (Standard: false)

  • disabled: Gibt an, ob die Auswahl deaktiviert ist. (Standard: false)

  • title: Tooltip, der über der Auswahl angezeigt wird.

  • dropdownStyleClass: Die CSS-Klasse des Dropdown Menüs. (Standard: leer)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

  • converter: Konverter-Bean für die angezeigten Elemente.

  • converterAttribute: Attribut für den Konverter.

Für das Bedienelement <isy:formSelectOneDropdown /> gibt es zusätzlich die folgenden Parameter:

  • label: Text für das Label.

  • labelStyleClass: Die CSS-Klasse des Labels. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches. (Standard: col-lg-6)

  • dropdownStyleClass: Die CSS-Klasse des Dropdown Menüs. (Standard: form-selectonedropdown)

  • showPrintView: Spezifisches Flag zur Erkennung der Druckansicht. (Standard: basisModel.showPrintView)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

Wenn JavaScript aktiviert ist, wird das Dropdown Menü über ein Bootstrap-Plugin dargestellt, ansonsten als natives Element.

6.7. Tabs

Tabs dienen der Strukturierung von Informationen und Reduktion der Anzahl gleichzeitig sichtbarer Inhaltsbereiche, wenn die Informationen schnell innerhalb des gleichen Fensters zugreifbar sein müssen. Tabreiter verhalten sich entsprechend dem analogen Vorbild eines Karteireiters, der dazu dient, verschiedene Karteikarten voneinander zu trennen. Tabs werden häufig dazu verwendet, um Eigenschaften eines Objekts in inhaltliche sinnvolle Gruppen aufzuteilen.

Tabs Beispiel
Abbildung 23. Tabs

Tabs werden über die Tags <isy:tabGroup>, <isy:tabHeader> und <isy:tabContent> eingebunden. Im Folgenden ein Beispiel:

Listing 49. Beispiel für Tabs
<isy:tabGroup tabGroupId="testTab" globalTabContentRefs="A P S" globalTab="A" defaultTab="A"
  tabGroupModel="#{jsfSteuerelementeModel.tabGroupModel}">

  <f:facet name="tabHeader">
    <isy:tabHeader value="Auskunft" name="A" />
    <isy:tabHeader value="Personalien" name="P" />
    <isy:tabHeader value="Sachverhalte" name="S" />
  </f:facet>

  <isy:tabContent name="A">Dies ist die Auskunft.</isy:tabContent>
  <isy:tabContent name="P">Dies sind Personalien.</isy:tabContent>
  <isy:tabContent name="S">Dies sind die Sachverhalte.</isy:tabContent>

</isy:tabGroup>

6.7.1. Tab-Gruppe

Zunächst wird die Tabgruppe mit dem Tag <isy:tabGroup> allgemein definiert.

Folgende Parameter sind Pflichtparameter:

  • tabGroupModel: Model für die Tabgruppe, das im Maskenmodel liegen sollte. Muss vom Typ TabGroupModel sein.

Außerdem gibt es folgende optionale Parameter:

  • tabGroupId: Das Widget tabGroup.xhtml ist das Parent-Widget von tabHeader.xhtml. Das Attribut tabGroupId wird zwar in tabGroup.xhtml nicht implementiert, ist aber als composite:attribute Deklaration unbedingt erforderlich, da von tabHeader.xhtml über cc.parent.attrs.tabGroupId darauf zugegriffen wird!

  • defaultTab: Name des Default-Tabs, der beim ersten Anzeigen des Elements aktiv ist.

  • globalTab: Der Name des globalen Tabs.

  • globalTabContentRefs: Die Liste an Namen der Tabs, welche beim Anzeigen des globalen Tabs auch angezeigt werden sollen.

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • scrollTabUpwards: Bei Tabgruppen, die im unteren Maskenbereich dargestellt werden, wird oftmals der Inhalt der Tabs nicht vollständig angezeigt. Setzt man den Parameter scrollTabUpwards auf true, dann wird die gesamte Tabgruppe beim Anklicken eines Tabellenreiters nach oben verschoben, sodass für den Anwender der TabContent maximal sichtbar wird. (Standard: false, Typ: java.lang.Boolean)

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

Wenn JavaScript aktiviert ist, dann nutzen die Tabs beim Umschalten AJAX-Aufrufe. Andernfalls wird beim Wechsel der Tabs die gesamte Seite neu geladen.

6.7.2. Tab-Header

Einzelne Tab-Header werden mit dem Tag <isy:tabHeader> definiert.

Folgende Parameter sind Pflicht:

  • name: Name des Tabs, für welchen dieser Header definiert ist

  • value: Titel des Tabs zur Anzeige

Außerdem gibt es folgende optionale Parameter:

  • tabController: Ein spezifischer Tab-Controller, falls notwendig. (Standard: #{tabController})

  • tooltip: Tooltip, der über der Auswahl angezeigt wird.

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

  • action: Action, die beim Wechsel zwischen Tabs ausgeführt wird. (Standard: tabController.changeTab(TabGroupModel model, String name)). Die action kann überschrieben werden, um z.B. den aktuellen Reiter validieren zu können. (Standard: #\{cc.attrs.tabController.changeTab(cc.parent.attrs.tabGroupModel,cc.attrs.name)})

  • skipAction: Gibt an, ob die übergebene action ausgelassen werden soll. Default ist false, die action wird standardmäßig also ausgeführt. (Standard: false, Typ: java.lang.Boolean)

6.7.3. Tab-Inhalte

Inhalte von Tabs werden mit dem Tag <isy:tabContent> definiert.

Folgende Parameter sind Pflicht:

  • name: Name des Tabs, zu welchem dieser Inhalt gehört

Außerdem gibt es folgende optionale Parameter:

  • tabController: Ein spezifischer Tab-Controller, falls notwendig. (Standard: #{tabController})

  • preload: Gibt an, ob das Tab im JS-Fall vorgeladen werden soll. Default ist false, sodass nicht vorgeladen wird. (Standard: false, Typ: java.lang.Boolean)

  • globalConfig: Eine spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

Zwischen den beiden Attributen preload der Tab-Inhalte und skipAction der Tab-Header besteht eine wichtige Abhängigkeit. Sie müssen immer den gleichen Wert aufweisen, ansonsten funktioniert der Tab nicht korrekt.

Das Attribut preload legt fest, ob der Inhalt des Tabs beim Laden der gesamten Seite vorgeladen werden soll. Bei einem Wechsel zwischen vorgeladenen Tabs muss dann entsprechend kein Server-Aufruf stattfinden. In diesem Fall darf aber die Action des Tab-Headers nicht ausgeführt werden, weil sonst doch ein Server-Aufruf stattfinden würde. Dies würde sowohl unnötigen Netzwerkverkehr als auch unerwünschtes Verhalten bei der Tab-Auswahl hervorrufen.

Standardmäßig stehen beide Werte auf false. Wenn das Vorladen gewünscht ist, müssen beide Werte explizit auf true gesetzt werden.

6.8. Listen

Listen werden benutzt, um eine überschaubare Anzahl an Daten oder Objekten eines Typus übersichtlich und vergleichbar darzustellen.

Liste mit Listenkopf
Abbildung 24. Liste mit Listenkopf

Für eine Liste mit Einfachauswahl gibt es die Tags <isy:selectOneList> bzw. <isy:formSelectOneList>. Für eine Liste mit Mehrfachauswahl stehen die Tags <isy:selectManyList> bzw. <isy:formSelectManyList> zur Verfügung.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts.

  • value: Der Wert für das Databinding in der Auswahl

Außerdem gibt es folgende optionale Parameter:

  • disabled: Gibt an, ob die Liste deaktiviert ist. (Standard: false)

  • size: Anzahl der Zeilen, die sichtbar sind

  • checkboxed: Gibt an, ob neben dem Highlighting ebenfalls Checkboxen angezeigt werden. (Standard: false)

  • selectlistStyleClass: Die CSS-Klasse für die Liste.

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

Für die Elemente innerhalb von Formularen gibt es zusätzlich die folgenden Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • label: Text für das Label.

  • labelStyleClass: Die CSS-Klasse des Labels. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches. (Standard: col-lg-6)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

6.8.1. List Picker (Objektauswahl)

Der List Picker kann den Benutzer bei der Auswahl bestimmter Objekte unterstützen, in dem weitere Zusatzinformationen die Identifikation von Werten vereinfachen.

Ein List Picker wird über das Tag <isy:formListpicker> eingebunden.

Folgende Parameter sind Pflicht:

  • reference: Die Referenz des Objekts.

  • value: Der Wert für das Databinding im Eingabefeld.

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • label: Text für das Label.

  • labelStyleClass: Die CSS-Klasse des Labels. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches. (Standard: col-lg-6)

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird. (Standard: TT.MM.JJJJ)

  • inputmask: Eingabemaske

  • inputmaskInsertMode: Gibt an, ob der Text bei der Eingabe überschrieben wird. (Standard: true)

  • minWidth: Die Mindestbreite. (Standard: 0)

  • maxHeight: Die maximale Höhe. (Standard: 200)

  • tooltip: Tooltip, der über dem Button angezeigt wird.

  • title: Tooltip, der über dem Eingabefeld angezeigt wird.

  • listpickerModel: Model für den List Picker, abgleitet von ListpickerModel

  • listpickerController: Controller für den List Picker, abgeleitet von ListpickerController

  • ajaxLoading: Gibt an, ob Items dynamisch nachgeladen werden. (Standard: false)

  • ajaxForm: ID des Formulars, welches für das dynamische Nachladen von Items verwendet wird

  • servletUrl: Alternative zu ajaxLoading. Wenn dieser Parameter gesetzt ist, werden die Items über ein Servlet und nicht über Ajax nachgeladen. Was hierbei zu beachten ist, wird weiter unten genauer beschrieben.

  • header: sortierte Liste der Spaltenüberschriften

  • inputComplement: Nummer der Spalte, dessen Inhalt per JavaScript im Eingabefeld ergänzt werden soll. (Standard: 0 = deaktiviert)

  • useAutocomplete: Gibt an, ob Eingaben automatisch vervollständigt werden. (Standard: true)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

Falls JavaScript nicht aktiviert ist, dann wird statt des List Pickers ein einfaches Dropdown Menü angezeigt.

Beispiel für die Integration eines List-Pickers (ohne Ajax):

Listing 50. Listpicker ohne Ajax
<isy:formListpicker
  reference="anfrageIdentifikation.gruppe"
  inputmask="99"
  listpickerModel="#{identifikationModel.gruppeListpickerModel}"
  listpickerController="#{behoerdeHelper.gruppeListpickerController}"
  label="#{msg.MEL_Identifikation_Gruppe}"
  value="#{identifikationModel.anfrageIdentifikation.gruppe}"
  header="#{msg.MEL_Identifikation_Gruppe_Listpicker_Nummer},
          #{msg.MEL_Identifikation_Gruppe_Listpicker_Name} "/>

Das spezifische ListpickerModel enthält die Liste an Items, welche dargestellt werden sollen. Die Filterung der Items geschieht automatisch über JavaScript. Falls die Liste an Items zu groß wird, besteht die Möglichkeit die Auswahl über AJAX nachzuladen. Dazu können die Attribute ajaxLoading="true" und ajaxForm="gruppeListpickerAjaxForm" ergänzt werden. Zusätzlich muss im View State das entsprechende Form-Element ergänzt werden:

Listing 51. ListpickerAjaxForm
<ui:define name="form">
   <h:form id="gruppeListpickerAjaxForm">
      <isy:formListpickerAjaxContent
      listpickerModel="#{identifikationModel.gruppeListpickerModel}" />
   </h:form>
</ui:define>

Über das <ui:define> lassen sich Form-Elemente im Basis-Layout integrieren. Das Tag <isy:formListpickerAjaxContent> lädt die entsprechend ListpickerItems in das Formular. Das Formular an sich ist nicht sichtbar. Das JavaScript Plugin übernimmt das entsprechende Laden der Elemente in den Listpicker. Die Filterung der Elemente kann im spezifischen ListpickerController definiert werden.

6.8.2. Behörden Picker

Für die Auswahl von Behörden existiert bereits ein fertiger Behörden Picker (<isy:formBehoerdeListpicker>), welcher den normalen Listpicker instanziiert. Der Behördenlistpicker ist ein AJAX Listpicker, d.h. der Parameter ajaxForm muss gesetzt sein. Als Dropdown zeigt er eine zweispaltige Tabelle mit Behördenkennzeichen und Namen der Behörde an, auf welcher gefiltert werden kann.

Der Behörden Picker besitzt keine zusätzlichen Parameter gegenüber <isy:formListpicker>, definiert jedoch einen eigenen Controller, von dem abgeleitet werden muss (AbstractBehoerdeListpickerController), und ein eigenes Model (BehoerdeListpickerModel).

6.8.3. List Picker mit Servlet

Damit ein List Picker über ein Servlet gefiltert werden kann, muss JavaScript aktiviert sein. Ansonsten steht die Funktionalität nicht zur Verfügung. Im Folgenden wird beschrieben, welche Schritte durchzuführen sind, damit ein Listpicker über ein Servlet gefiltert werden kann.

Listing 52. Listpicker mit Servlet-Filterung
<isy:formListpicker
  reference="anfrageIdentifikation.gruppe"
  inputmask="99"
  listpickerModel="#{identifikationModel.gruppeListpickerModel}"
  listpickerController="#{behoerdeHelper.gruppeListpickerController}"
  label="#{msg.MEL_Identifikation_Gruppe}"
  value="#{identifikationModel.anfrageIdentifikation.gruppe}"
  header="#{msg.MEL_Identifikation_Gruppe_Listpicker_Nummer},
          #{msg.MEL_Identifikation_Gruppe_Listpicker_Name} "
  servletUrl="/app/listpicker" />

Entscheidend ist der Parameter servletUrl. Erstens wird anhand des Vorhandenseins des Parameters erkannt, dass ein Servlet zum Filtern benutzt werden soll und nicht etwa Ajax. Zweitens muss der Wert des Parameters sich in der Konfiguration des HandlerServlets wiederfinden.

Listing 53. Beispielhafte HandlerServlet-Konfiguration
// Bean, die AbstractListpickerProviderRequestHandler implementiert
@Bean
ListpickerProviderRequestHandler listpickerProviderRequestHandler() {
    return new ListpickerProviderRequestHandler();
}

//Registrierung des Servlets
@Bean
public ServletRegistrationBean<HttpRequestHandlerServlet> listPickerServletBean() {
    ServletRegistrationBean<HttpRequestHandlerServlet> bean = new ServletRegistrationBean<>(
        new HttpRequestHandlerServlet(), "/app/listpicker/*"
    );
    bean.setName("listpickerProviderRequestHandler");
    bean.setLoadOnStartup(1);
    return bean;
}

Der Parameter servletUrl hat hier beispielsweise den Wert "/app/listpicker" und das Servlet erfasst laut Eintrag in der Konfiguration alle Requests, deren URL auf das Pattern "/app/listpicker/*" passen. Auf diese Weise ist die Verknüpfung zwischen List Picker und Servlet hergestellt.

Die konkrete Implementierung des HttpRequestHandler muss von der jeweiligen Anwendung selbst bereitgestellt werden. Hierzu sollte von der Klasse AbstractListpickerProviderRequestHandler geerbt werden. In dem obigen Beispiel heißt die Bean der Implementierung listpickerProviderRequestHandler.

6.8.3.1. Hinweise zur Funktionsweise

Folgende grundlegende Funktionalität wird durch die Komponente automatisch, also ohne weiteres Zutun, bereitgestellt: Per JavaScript werden Eingaben im Filter-Feld des Listpickers erkannt. Der aktuell eingegebene Wert wird der URL (siehe servletUrl) angefügt (Beispiel: Anwender filtert nach "123". Dann wird die URL um ?filter=123 ergänzt) und der Request wird anschließend abgesetzt und vom Servlet behandelt. Die eigentliche Filterlogik obliegt dann der konkreten Implementierung. Den Wert des Filter-Feldes erhält sie jedoch von der abstrakten Oberklasse. Nachdem die Einträge gefiltert wurden, werden sie automatisch mittels JavaScript gerendert.

Es kann vorkommen, dass die Filterung nicht nur von dem Wert des Filter-Feldes abhängt. Es ist z.B. denkbar, dass die Filterung zusätzlich die Auswahl eines gänzlich anderen Feldes innerhalb des Formulars berücksichtigen soll. In dieser Situation würde es also nicht genügen, den Wert des Filter-Feldes in der URL zu codieren und zu übertragen. Zusätzlich benötigte Parameter können frei gewählt werden und müssen einfach der URL hinzugefügt werden. Ein Beispiel:

Listing 54. Servlet-URL mit weiteren Filter-Parametern
<isy:formListpicker
  servletUrl="/app/listpicker?weitererFilterParameter1={#eingabeModel.weitererFilterParameter1}&weitererFilterParameter2={#eingabeModel.weitererFilterParameter2}" />

In dem Beispiel werden zwei zusätzliche Parameter zur Filterung benötigt (weitererFilterParameter1 und weitererFilterParameter2). Ihre Bezeichnung und woher sie bezogen werden, kann beliebig festgelegt werden. Wichtig ist lediglich, dass die konkrete Implementierung des Servlets die Bezeichnungen kennt und diese der Oberklasse über die entsprechende Methode bekannt macht. Unabhängig von etwaigen zusätzlichen Filter-Parametern wird der Wert des Filter-Feldes des Listpicker immer übertragen.

6.9. Tabelle

Eine Tabelle dient der übersichtlichen Anzeige von größeren Datenmengen. Die Tabelle besteht aus mehreren Informationsspalten, die zur Sortierung verwendet werden können.

Tabelle Einfuehrung
Abbildung 25. Tabelle
Tabelle Zustaende Zeilen
Abbildung 26. Tabelle – Zustände interaktiver Zeilen

Die Umsetzung der Tabelle unterscheidet sich grundsätzlich zu Widgets wie der von JSF bereitgestellten <h:dataTable>. Die <isy:dataTable> ist näher am Layout einer eigentlichen Tabelle aufgebaut und dadurch flexibler nutzbar (z.B. dynamische Anzahl an Spalten). Dafür ist jedoch auch ein größerer Implementierungsaufwand erforderlich.

Es existieren folgende Tags zur Konfiguration der <isy:dataTable>:

  • <isy:dataTable>

  • <isy:dataTableHeader>

  • <isy:dataTableRowAllSelection>

  • <isy:dataTableRows>

  • <isy:dataTableCell>

  • <isy:dataTableDetailButton>

  • <isy:dataTableRowSelection>

Beispiel für die Definition einer <isy:dataTable>:

Listing 55. Beispiel für <isy:dataTable> Verwendung
<isy:dataTable
  dataTableModel="#{...}"
  dataTableController="#{...}"
  action="trefferlisteDoppelklick">

  <f:facet name="tableToolbar">
    <isy:buttonGroup>
       <isy:buttonToolbar />
    </isy:buttonGroup>
  </f:facet>

  <f:facet name="tableHeader">
    <isy:dataTableHeader name="Vorname" />
    <isy:dataTableHeader name="Nachname" />
    <isy:dataTableHeader name="Aktionen" />
  </f:facet>

  <isy:dataTableRows
      rowDefinition="/WEB-INF/gui/.../rowDefinition.xhtml"
      detailDefinition="/WEB-INF/gui/.../detailDefinition.xhtml" />

</isy:dataTable>

Die grundlegende Basis für eine Tabelle bildet das Tag <isy:dataTable>.

Folgende Facets können innerhalb des Tags verwendet werden:

  • tableToolbar: Das Facet umschließt eine Liste von Buttons in der Toolbar der Tabelle, siehe auch JSF-Facet tableToolbar

  • tableHeader: Das Facet umschließt eine Liste von Überschriften im Kopfbereich der Tabelle, siehe auch JSF-Facet tableHeader

Folgende Parameter sind Pflicht:

  • dataTableModel: Model für die Tabelle, das im Maskenmodel liegen muss. Muss vom Typ DataTableModel sein und eine Liste von Datensätzen (Items) zur Anzeige beinhalten.

  • dataTableController: Der zugehörige, spezifische Controller. Der Controller stellt z.B. Funktionalität zur Suche bereit. Muss vom Typ DataTableController sein.

Außerdem gibt es folgende optionale Parameter:

  • jsSortFunction: Eine Sortierfunktion, welche direkt auf dem Client ausgeführt werden kann.

  • selectable: Gibt an, ob die Datatable selektierbar ist oder nicht. Diese Information wird benötigt, um das JavaScript Plug-In zu konfigurieren. (Standard: false, Typ: Boolean)

  • selectionMode: Der Modus für die Selektierung. Entweder 'single' oder 'multiple'. (Standard: multiple)

  • detailMode: Der Modus für die Detailansicht. Entweder 'single' oder 'multiple'. (Standard: multiple)

  • action: Die Aktion, welche beim Doppelklick auf eine Zeile ausgeführt wird.

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • highlightDoubleclick: Gibt an, ob Zeilen bei einem Doppelklick hervorgehoben werden sollen. (Standard: false, Typ: Boolean)

  • tableId: Tabelle ID. (Standard: tableId)

  • globalConfig: Die spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

  • showMore: Gibt an, ob ein Button zum Anzeigen von mehr Spalten angezeigt werden soll. (Standard: false, Typ: Boolean)

  • styleClass: Die zu ergänzenden Style-Klassen.

6.9.1. JSF-Facet tableToolbar

Im JSF-Facet tableToolbar werden Listen von <isy:buttonGroup> Tags erwartet. Die Listen können jeweils Elemente der Typen <isy:buttonToolbar> (siehe Button Toolbar) und <isy:buttonToggle> (siehe Toggle Button) enthalten.

Folgende optionale Parameter gibt es für die Toolbar:

  • alignLeft: Gibt an, ob die Toolbar linksbündig ausgerichtet ist. (Standard: false)

  • alignRight: Gibt an, ob die Toolbar rechtsbündig ausgerichtet ist. (Standard: false)

6.9.2. JSF-Facet tableHeader

Im JSF-Facet tableHeader wird eine Liste von <isy:dataTableHeader> Tags erwartet. Ein Tag entspricht dabei einem Titel einer Spalte.

Folgende optionale Parameter gibt es für einen Header:

  • name: Header-Name / Spaltenüberschrift,

  • sortable: Gibt an, ob die Spalte sortierbar ist. (Standard: false)

  • hidden: Gibt an, ob die Spalte ausgeblendet ist. (Standard: false)

  • sortProperty: Attribut der Datensätze (Items), nach dem sortiert wird.

  • width: Breite der Spalte,

  • title: Tooltip, der über der Spalte angezeigt wird. (Standard: '')

  • align: horizontale Ausrichtung der Spaltenüberschrift.

6.9.3. Zeilen einer Tabelle

Die Zeilen der Tabelle werden mit dem Tag <isy:dataTableRows> definiert. Hier steht der eigentliche Inhalt der Datatable. Dieses Tag sollte nach den Headern in den Body der Datatable geschrieben werden.

Folgende optionale Parameter sind zulässig:

  • rowDefinition: Pfad zur XHTML-Seite für die Definition des Zeilenaufbaues. Wird mehrfach inkludiert.

  • detailDefinition: Pfad zur XHTML-Seite für die Detailansicht. Diese kann zusätzliche Datenfelder zur Zeile enthalten.

  • preloadingSize: Die Anzahl an Elementen, die im JavaScript Modus für die Detailansicht vorgeladen werden. (Standard: 0, Typ: java.lang.Integer)

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

Listing 56. Beispiel einer Row-Definition
<ui:composition>

  <isy:dataTableCell>#{dataTableItem.vorname}</isy:dataTableCell>
  <isy:dataTableCell>#{dataTableItem.nachname}</isy:dataTableCell>
  <isy:dataTableCell>
    <isy:dataTableDetailButton dataTableModel="#{...}" />
  </isy:dataTableCell>

</ui:composition>

Die Row-Definition wird für jeden Datensatz in der Tabelle eingebunden. Der UI-Parameter dataTableItem weist immer auf den aktuellen Treffer (also ein Objekt des Typs DataTableItem). Mit diesem Parameter können dann für jede Spalte die <isy:dataTableCell> Tags eingebunden werden. Die Inhalte dieser Tags repräsentieren den Inhalt der jeweiligen Zellen. Die Reihenfolge der Spalten werden durch die Definition des Tabellen-Headers festgelegt.

6.9.4. Zellen einer Tabellenzeile

Das Tag <isy:dataTableCell> hat derzeit folgende Parameter:

  • hidden: Gibt an, ob die Spalte angezeigt werden soll. (Standard: false, Typ: Boolean)

  • id: Identifier,

  • sortData: Optionales Feld für die clientseitige Sortierung, falls nicht nach dem Inhalt (z.B. beim Datum) sortieren werden soll.

  • filterData: Damit Client- und Server-Mode konsistent sind, sollte hier die sortProperty des Headers angegeben werden.

  • align: Gibt die horizontale Ausrichtung des Inhalts der Tabellenzelle an. Mögliche Werte sind left, right und center. (Standard: left)

Die Einbindung der Row-Definition erfolgt über das JSF Tag <ui:repeat>. Als Statusvariable wird dataTableItemRepeatStatus verwendet. Auch auf diese Variable kann innerhalb der Row-Definition zugegriffen werden.

Zur Vereinfachung des Aufrufs der Detailansicht wird das Tag <isy:dataTableDetailButton> angeboten. Dieses Tag rendert einen Button und öffnet die Detailansicht eines Treffers. Die Detailansicht eines Treffers befindet sich an der im Tag <isy:dataTableRows> angegebenen Stelle.

Listing 57. Beispiel einer Detail-Definition
<ui:composition>
  <td colspan="2">
    <div class="form-horizontal readonly">
      <div class="row">
        <div class="col col-lg-6">
          <isy:formLabel reference="aktenzeichen"
             value="#{dataTableItem.aktenzeichen}"
             label="#{msg_currentflow.MEL_Trefferliste_Aktenzeichen}"/>
          <isy:formLabel reference="ordnungsnummer"
             value="#{dataTableItem.ordnungsnummer}"
             label="#{msg_currentflow.MEL_Trefferliste_Ordnungsnummer}"/>
          <isy:formLabel reference="speicherungsdatum"
             value="#{dataTableItem.speicherungsdatum}"
             label="#{msg_currentflow.MEL_Trefferliste_Speicherungsdatum}"/>
        </div>
      </div>
    </div>
  </td>
</ui:composition>

Die Detail-Definition enthält beliebigen Inhalt. Im Beispiel ist dies ein Formular mit der Ausgabe von drei Labels in der linken Hälfte der Tabelle. Analog zur Row-Definition kann auf den aktuellen Treffer über die UI-Parameter dataTableItem und dataTableItemRepeatStatus zugegriffen werden.

Die weiteren Abschnitte beschreiben weiterführende Aspekte wie Filterung, Sortierung und das Selektionsverhalten von Tabellen.

6.9.5. Filterung in einer Tabelle

Zur Filterung einer Tabelle stehen das Facet <f:tableFilter>, die Tags <isy:dataTableFilter> und <isy:dataTableFilterCleaner> sowie das dazugehörige DataTableFilterModel bereit.

Im Allgemeinen muss beim Tag <isy:dataTableFilter> nur die Eigenschaft angegeben werden, nach der man filtern will. Damit wird ein normales Eingabefeld für die Filterung zur verfügung gestellt. Es gibt auch die Möglichkeit die Filterung über ein Dropdown Menü zu ermöglichen. Dafür müssen die möglichen Einträge im Tag verschachtelt angegeben werden.

Es ist besonders wichtig, dass die Anzahl der Spalten im Header, der Filter-Zeile und den Zeilen der Datensätze übereinstimmen. Dieser Zusammenhang wird mittels JavaScript überprüft. Spalten, die nicht gefiltert werden sollen (bzw. können), werden mittels des Tags <isy:dataTableFilter> ohne Attribute beschrieben.

Listing 58. Beispiel für die Filterung einer Tabelle
<f:facet name="tableFilter">
  <!-- Platzhalter für eine Spalte, die z.B. Checkboxen enthält -->
  <isy:dataTableFilter />
  <isy:dataTableFilter property="anrede" dropdown="true">
    <f:selectItem itemValue="" itemLabel="Wählen Sie aus:" />
    <f:selectItems value="#{dropdownHelper.anredeListe}" />
  </isy:dataTableFilter>
  <isy:dataTableFilter property="vorname" />
  <isy:dataTableFilter property="nachname" />
  <isy:dataTableFilter property="geburtsdatum" />
  <isy:dataTableFilterClearer />
</f:facet>

Kein JavaScript

no js
Abbildung 27. Kein Javascript

Die Komfortfunktionen der Filter-Zeile können ohne JavaScript nicht zur Verfügung gestellt werden. Die Filter-Zeile ist in diesem Fall nicht vorhanden und wird auch nicht angezeigt.

Die Komponente <isy:dataTableFilter> hat folgende optionale Parameter:

  • property: Die Property, die gefiltert werden soll, i.A. gleich zur sortProperty im zugehörigen Header, falls nicht angegeben wird einfach eine Platzhalter-Spalte generiert. (Standard: ``)

  • dropdown: Gibt an, ob eine Auswahlliste zur Filterung angezeigt werden soll. Falls ja, müssen die Einträge mittels selectItem(s) angegeben werden. (Standard: false, Typ: Boolean)

  • clearFilterTooltip: Tooltip, der über dem Icon "clear-filter" angezeigt werden soll. (Standard: Filter aufheben)

<isy:dataTableFilterClearer> - Tooltip, der über dem Icon "clear-all-filter" angezeigt werden soll.

Die Komponente hat folgende optionale Parameter:

  • tooltip: Tooltip, der über dem Icon "clear-all-filter" angezeigt werden soll. (Standard: Alle Filter aufheben)

6.9.6. Sortierung in einer Tabelle

Tabellen bieten Möglichkeiten zur Sortierung an. Dazu können die einzelnen Spalten-Header über das <isy:dataTableHeader> Tag entsprechend konfiguriert werden.

Wenn eine Tabellenspalte auf- bzw. absteigend sortierbar ist, dann wird dies durch zwei kleine Pfeil-Icon-Dreiecke dargestellt. Wählt der Anwender eine Spalte zum Sortieren aus, dann wird entsprechend der ausgewählten Sortierrichtung das jeweilige Icon dargestellt. In der folgenden Abbildung sind die Spalten Vorname, Loginname und "#" als sortierbar erkennbar. Die Spalte Nachname ist abwärts-sortiert, dargestellt durch das nach unten gerichtete Dreiecks-Icon.

demopanel dataTableHeader
Abbildung 28. Tabelle – Sortierungs-Indikator im Tabellenkopf

Durch Angabe von sortable="true" und dem Attribut sortProperty werden automatisch Buttons und Symbole zur Sortierung hinzugefügt. Beim Initialisieren des Models muss der Operationsmodus (SERVER oder CLIENT) gesetzt werden: model.setMode(DatatableOperationMode.SERVER). Im Modus CLIENT erfolgt die Sortierung automatisch per JavaScript. Im Modus SERVER wird die Methode DataTableController.updateDisplayItems(…​) aufgerufen, welche die Tabelleneinträge filtert, sortiert und anschließend seitenweise anzeigt.

Listing 59. Beispiel für dataTableHeader
<isy:dataTableHeader name="#{...}" sortable="true" sortProperty="vorname"/>

6.9.7. Selektionsverhalten in einer Tabelle

Um die Selektion von Zeilen zu ermöglichen, müssen folgende Konfigurationen durchgeführt werden:

Tabellen-Definition: In der Tabellen-Definition (<isy:dataTable>) muss das Attribut selectable="true" gesetzt sein. Der Selektierungsmodus (einzeln, mehrere) wird über das Attribut selectionMode gesteuert.

Header-Definition: In der Header-Definition muss ein <isy:dataTableHeader> Tag an erster Stelle mit folgender Definition aufgenommen werden:

Listing 60. Zeilenselektion Schritt 1
<isy:dataTableHeader>
  <isy:dataTableRowAllSelection />
</isy:dataTableHeader>

Row-Definition: In der Row-Definition muss ein <isy:dataTableCell> Tag an erster Stelle mit folgender Definition aufgenommen werden:

Listing 61. Zeilenselektion Schritt 2
<isy:dataTableCell>
  <isy:dataTableRowSelection />
</isy:dataTableCell>
Tabelle Mehrfachselektion
Abbildung 29. Tabelle – Mehrfachselektion über STRG Taste & Maus
Tabelle Mehrfach Checkbox
Abbildung 30. Tabelle – Mehrfachselektion über Checkboxen
Textlink Kennzeichnung Objekt
Abbildung 31. Textlink zur Kennzeichnung eines Objektes

6.9.8. Große Datenmengen in einer Tabelle

Tabellen können sehr viele Daten enthalten und gegebenenfalls sehr lang werden. Um dem Benutzer den Umgang mit solchen Tabellen zu vereinfachen, werden zunächst nicht alle Daten initial in der Tabelle angezeigt. Über einen Mehr anzeigen Button oder einen Paginator kann der Benutzer sich bei Bedarf mehr Daten anzeigen lassen.

Tabelle Button MehrAnzeigen
Abbildung 32. Tabelle mit "mehr zeigen" Button

Die Implementierung einer Paginierung erfolgt über das Facet <f:tablePagination>, das Tag <t:dataTablePaginator> und das dazugehörige DataTablePaginationModel. Die Paginierung wird beim Initialisieren des DataTableModel im Controller konfiguriert:

Listing 62. Implementierung Paginierung
public void initialisiereModel(DataTableModel model) {
   model.getPaginationModel().setPageSize(3);
   model.getPaginationModel().setMode(PaginationMode.SIMPLE);
   updateDisplayItems(model);
}

In der View setzt folgendes Facet die Paginierung um:

Listing 63. Implementierung Paginierung in der View
<f:facet name="tablePagination">
  <isy:dataTablePaginator />
</f:facet>

<isy:dataTablePaginator> - Alle Texte haben 2 optionale Parameter: #{0}: Die Nummer der betroffenen Seite #{1}: Die Anzahl der Seiten.

Folgende Facets können innerhalb des Tags verwendet werden:

  • paginatorRechts: Ergänzungen an der rechten Seite, links neben dem Paginator

Die Komponente besitzt folgende optionale Parameter:

  • showMoreText: Alle Texte haben 2 optionale Parameter: #{0}: Die Nummer der betroffenen Seite; #{1}: Die Anzahl der Seiten. (Standard: …​Mehr Anzeigen…​)

  • showMoreTooltip: (Standard: Nächste Seite - Seite #{0} von #{1} anzeigen)

  • text: (Standard: Seite #{0} von #{1})

  • firstPageText: (Standard: «)

  • firstPageTooltip: (Standard: Erste Seite - Seite #{0} von #{1} anzeigen)

  • previousPageText: (Standard: )

  • previousPageTooltip: (Standard: Vorherige Seite - Seite #{0} von #{1} anzeigen)

  • pageText: (Standard: #{0})

  • pageTooltip: (Standard: Seite #{0} von #{1} anzeigen)

  • nextPageText: (Standard: )

  • nextPageTooltip: (Standard: Nächste Seite - Seite #{0} von #{1} anzeigen)

  • lastPageText: (Standard: »)

  • lastPageTooltip: (Standard: Letzte Seite - Seite #{0} von #{1} anzeigen)

6.10. Checkbox

Eine Checkbox repräsentiert eine unabhängige, nicht-exklusive Auswahl. Der Benutzer kann beliebige Optionen auswählen.

6.10.1. Einzelne Checkbox

Eine einzelne Checkbox wird über das Tag <isy:selectBooleanCheckbox> eingebunden.

Die Komponente besitzt folgende notwendige Parameter:

  • value: Der Wert der Checkbox für das Databinding in Models.

  • disabled: Gibt an, ob die Checkbox deaktiviert ist oder nicht. (Standard: false, Typ: Boolean)

  • required: Gibt an, ob die Checkbox zwingend markiert werden muss oder nicht. (Standard: false, Typ: Boolean)

Außerdem gibt es folgende optionale Parameter:

  • label: Das Label der Checkbox

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • onchange: Das onchange-Event der Checkbox

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock)

  • fourEyesLastValue: 4 Augen Prinzip letzter Wert

6.10.2. Mehrere Checkbox Felder

Mehrere Checkboxen werden über das Tag <isy:selectManyCheckbox> eingebunden. Realisiert über Select-Items.

Die Komponente besitzt folgende notwendige Parameter:

  • value: Der Wert für das Data-Binding

Außerdem gibt es folgende optionale Parameter:

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean).

6.10.3. Checkbox innerhalb von Formularen

Für Formulare existiert das Tag <isy:formCheckbox>.

Die Komponente besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • disabled: Gibt an, ob die Checkbox deaktiviert ist oder nicht. (Standard: false)

Außerdem gibt es folgende optionale Parameter:

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • label: Der Text für das Label,

  • labelRight: Der Text für das Label rechts daneben,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • optional: Gibt an, ob die Eingabe ein optionale Pflichteingabe ist (blaues Sternchen). (Standard: false, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • valueChangeListener: Value Change Listener.

6.10.4. Radio Button

Radio Buttons dienen der eindeutigen Auswahl von sich ausschließenden Optionen. Der Benutzer kann also nur eine der Optionen auswählen.

RadioButton Normal Disabled
Abbildung 33. Radio Button – Darstellungsbeispiel IE 9

Ein Radio Button wird über das Tag <isy:selectOneRadio> (bzw. <isy:selectOneRadioInline>) und <isy:formSelectOneRadio> eingebunden.

6.10.5. Horizontal gruppierte Radio Buttons

Über das Tag <isy:selectOneRadioInline> werden Radiobuttons horizontal gruppiert dargestellt. Die Komponente besitzt folgende notwendige Parameter:

  • value: Der Wert der Auswahl für das Data-Binding,

  • selectItems: Liste der auszuwählenden Werte den Select-Items. Jedes Item entspricht einem Radio-Button.

Außerdem gibt es folgende optionale Parameter:

  • disabled: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

6.10.6. Vertikal gruppierte Radio Buttons

Über das Tag <isy:selectOneRadio> werden Radiobuttons vertikal gruppiert dargestellt.

Die Komponente besitzt folgende notwendige Parameter:

  • value: Der Wert der Auswahl für das Data-Binding,

  • selectItems: Liste der auszuwählenden Werte, den Select-Items. Jedes Item entspricht einem Radio-Button.

Außerdem gibt es folgende optionale Parameter:

  • showPrintView: Gibt an, ob die Komponente innerhalb einer Druckansicht angezeigt werden soll. (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

6.10.7. Form gruppierte Radio Buttons

Das Tag <isy:formSelectOneRadio> ermöglicht die Gruppierung von Radiobuttons innerhalb einer Form.

Die Komponente besitzt folgende notwendige Parameter:

  • value: Der Wert der Auswahl für das Data-Binding,

  • selectItems: Liste der auszuwählenden Werte, den Select-Items. Jedes Item entspricht einem Radio-Button.

  • reference: Die Referenz des Objekts.

Außerdem gibt es folgende optionale Parameter:

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • inline: Gibt an, ob die Radio-Buttons inline angezeigt werden sollen. (Standard: false, Typ: Boolean)

  • disabled: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • inlineInputStyleClass: Die CSS-Klasse für den Eingabebereich eines einzelnen Inline-Radio-Button, (Standard: ``)

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • valueChangeListener: Value Change Listener.

6.11.1. Horizontale Navigation

Die Navigationsleiste im Header-Bereich lässt sich konfigurierbar gestalten. Hierzu muss jede Anwendung zunächst eine Instanz von de.bund.bva.isyfact.common.web.jsf.components.navigationmenu.generieren.impl.NavigationMenuGenerierenAusKonfiguration im Application-Context zur Verfügung stellen und korrekt konfigurieren. Die Bean benötigt lediglich einen de.bund.bva.isyfact.security.core.Berechtigungsmanager und eine de.bund.bva.isyfact.konfiguration.common.Konfiguration, um korrekt zu funktionieren.

Listing 64. Beispiel für die Deklaration der Bean
@Bean
public NavigationMenuGenerierenAusKonfiguration navigationMenuGenerierenStrategie(
        Konfiguration konfiguration, Berechtigungsmanager berechtigungsmanager) {
    return new NavigationMenuGenerierenAusKonfiguration(konfiguration, berechtigungsmanager);
}

Ein einzelner Eintrag in der Navigation lässt sich nach folgendem Schema konfigurieren:

Listing 65. Beispiel zur Konfiguration der horizontalen Navigation
gui.navbar.applikationsgruppe.1.wert = JSF-Vorlagen
gui.navbar.applikationsgruppe.1.link = /isy-webgui/app/index.html
gui.navbar.applikationsgruppe.1.farbe = #337299
gui.navbar.applikationsgruppe.1.reihenfolge = 1
gui.navbar.applikationsgruppe.1.rollen =

gui.navbar.applikationsgruppe.1.anwendung.1.wert  = JSF-Steuerelemente
gui.navbar.applikationsgruppe.1.anwendung.1.link = /isy-webgui/app/jsfSteuerelementeFlow
gui.navbar.applikationsgruppe.1.anwendung.1.reihenfolge  = 1
gui.navbar.applikationsgruppe.1.anwendung.1.rollen =

gui.navbar.applikationsgruppe.1.anwendung.2.wert  = 4-Augen Prinzip
gui.navbar.applikationsgruppe.1.anwendung.2.link = /isy-webgui/app/vieraugenFlow
gui.navbar.applikationsgruppe.1.anwendung.2.reihenfolge  = 2
gui.navbar.applikationsgruppe.1.anwendung.2.rollen =

gui.navbar.applikationsgruppe.1.anwendung.3.wert  = Nachrichten
gui.navbar.applikationsgruppe.1.anwendung.3.link = /isy-webgui/app/nachrichtenFlow
gui.navbar.applikationsgruppe.1.anwendung.3.reihenfolge  = 3
gui.navbar.applikationsgruppe.1.anwendung.3.rollen = Beispielrolle

Das Schlüsselwort applikationsgruppe und die darauf folgenden Parameter beziehen sich immer auf einen Eintrag in der Leiste selbst. Das Schlüsselwort anwendung und die darauf folgenden Parameter beziehen sich wiederum immer auf einen Eintrag innerhalb des Flyout Menüs eines Eintrags innerhalb der Leiste. Die Zahlen innerhalb der Konfigurationsparameter dienen der logischen Zuordnung. Im obigen Beispiel sieht man schnell, dass es eine Applikationsgruppe gibt und dieser Gruppe drei Anwendungen zugeordnet sind. Die Zahlen müssen aus technischer Sicht keiner strikten Sequenz folgen (etwa *.anwendung.1.*, *.anwendung.2.* usw.), aber dies bietet sich aufgrund der Lesbarkeit an.

Für Einträge innerhalb der Leiste selbst (applikationsgruppe) existieren folgende Parameter:

  • wert: Das Label zur Anzeige.

  • link: Der Link, der aufgerufen wird, wenn der Anwender auf den Eintrag klickt.

  • farbe: Die Farbe der Applikationsgruppe in hexadezimaler Notation.

  • reihenfolge: Ein numerischer Wert für die Reihenfolge der Anzeige der Applikationsgruppen innerhalb der horizontalen Navigation.

  • rollen: Die benötigten Rollen zur Anzeige als komma-separierte Liste. Der Besitz mindestens einer Rolle ist ausreichend, um den Eintrag zu sehen.

Für Einträge innerhalb eines Flyout Menüs (anwendung) existieren folgende Parameter:

  • wert: Das Label zur Anzeige.

  • link: Der Link, der aufgerufen wird, wenn der Anwender auf den Eintrag klickt.

  • reihenfolge: Ein numerischer Wert für die Reihenfolge der Anzeige der Anwendung innerhalb des Flyout Menüs.

  • rollen: Die benötigten Rollen zur Anzeige als komma-separierte Liste. Der Besitz mindestens einer Rolle ist ausreichend, um den Eintrag zu sehen.

Grundsätzlich sind alle Werte optional. Damit ist jedoch lediglich gemeint, dass die Anwendung keinen Fehler erzeugt, falls ein Wert für eine Applikationsgruppe bzw. Anwendung überhaupt nicht konfiguriert ist. Nicht benötigte Parameter können daher einfach weggelassen werden. Um einen sinnvollen Einsatz zu gewährleisten, sollten immer mindestens wert und link konfiguriert sein.

Die Navigation würde im obigen Beispiel den Eintrag JSF-Vorlagen enthalten. Wenn die Maus sich über dem Eintrag befindet, würde das Flyout Menü aufklappen und die Einträge JSF-Steuerelemente, 4-Augen Prinzip und Nachrichten würden sichtbar werden. Der Eintrag Nachrichten ist für den jeweiligen Nutzer jedoch nur sichtbar, wenn er die Rolle Beispielrolle besitzt. Weitere Rollen lassen sich komma-separiert angeben. Ein Anwender sieht den jeweiligen Eintrag, sobald er mindestens eine der benötigten Rollen besitzt.

horizontale navigation submenu
Abbildung 34. Navigation mit ausgeklapptem Flyout Menü

Das folgende Beispiel zeigt, wie die Navigationsleiste um einen weiteren Eintrag samt Flyout Menü erweitert werden könnte:

Listing 66. Erweiterung der Konfiguration der horizontalen Navigation
gui.navbar.applikationsgruppe.2.wert = Layouts
gui.navbar.applikationsgruppe.2.link = /isy-webgui/app/page-details.html
gui.navbar.applikationsgruppe.2.farbe = #F59D35
gui.navbar.applikationsgruppe.2.reihenfolge = 2

gui.navbar.applikationsgruppe.2.anwendung.1.wert  = Applikationsseite
gui.navbar.applikationsgruppe.2.anwendung.1.link = /isy-webgui/app/beispielApplikationsseiteFlow
gui.navbar.applikationsgruppe.2.anwendung.1.reihenfolge  = 1

gui.navbar.applikationsgruppe.2.anwendung.2.wert  = applikationsgruppe-Detailseite
gui.navbar.applikationsgruppe.2.anwendung.2.link = /isy-webgui/app/applikationDetailseiteFlow
gui.navbar.applikationsgruppe.2.anwendung.2.reihenfolge  = 2

6.11.2. Linksnavigation

Die Linksnavigation ist ein optionales Element und kann zur weiteren Strukturierung einer Applikation dienen. Sie kann über ein Icon ein- und ausgeblendet werden.

Linksnavigationen werden durch den Controller LinksnavigationController und das Model LinksnavigationModel realisiert. Der Controller ist bereits im ApplikationseiteController eingebunden und muss daher nicht explizit aktiviert werden.

Linksnavigationen werden in der Konfigurationsdatei gui-linksnavigation.properties konfiguriert. Die Konfigurationsdatei liegt im Deployment. Es handelt sich nicht um eine betriebliche Konfiguration. Die Konfiguration muss in der Konfigurations-Bean konfiguration eingebunden werden. Über die Variable gui.linksnavigation.ids wird zunächst eine Liste an IDs für die jeweiligen Linksnavigationen konfiguriert. Für jede ID wird anschließend die Linksnavigation konfiguriert.

Listing 67. Beispiel zur Konfiguration der Linksnavigation
gui.linksnavigation.ids=linksnavigationbeispiel,jsfSteuerelemente

gui.linksnavigation.linksnavigationbeispiel.headline=Beispiellinkliste
gui.linksnavigation.linksnavigationbeispiel.1.text=Beispielseite A
gui.linksnavigation.linksnavigationbeispiel.1.link=beispiellinkaFlow
gui.linksnavigation.linksnavigationbeispiel.2.text=Beispielseite B
gui.linksnavigation.linksnavigationbeispiel.2.link=beispiellinkbFlow

gui.linksnavigation.jsfSteuerelemente.headline=Überschrift
gui.linksnavigation.jsfSteuerelemente.1.text=JSF-Steuerlemente
gui.linksnavigation.jsfSteuerelemente.1.link=jsfSteuerelementeFlow

Anhand des aktuell aktiven Flows wird automatisch die korrekte Linksnavigation dargestellt. Der enthaltene Link zum aktiven Flow wird automatisch als ausgewählt dargestellt. Wenn ein Subflow aktiv ist, dann wird immer der ursprünglich aufrufende Flow als der aktive Flow angesehen. Wenn keine passende Linksnavigation gefunden wird, bleibt der Bereich auf der Seite leer. Weiterhin kann auf einer Applikationsseite eine individuelle Linksnavigation manuell eingebunden werden.

Muss der Benutzer häufig auf bestimmte Funktionen oder Objekte in einer Anwendung zugreifen, so kann es sinnvoll sein ihm Schnellzugriffe, sogenannte Quicklinks, auf diese Funktionen/Objekte zur Verfügung zu stellen.

Quicklinks LetzteObjekte
Abbildung 35. Quicklinks unterhalb der Linksnavigation
Quicklinks Wiedervorlage
Abbildung 36. Quicklinks auf Dashboard

Quicklinks werden durch den Controller QuicklinksController und das Model QuicklinksModel realisiert. Zur Nutzung müssen Controller und Model in den jeweiligen Controller bzw. das Model der Seite integriert werden. Ein einzelner Quicklink (QuicklinkselementModel) besitzt folgende Attribute:

  • id: ID des Quicklinks

  • anzuzeigenderText: Text des Quicklinks

  • link: Ziel des Quicklinks

Der QuicklinksController stellt in der Hauptsache folgende Methoden bereit:

  • fuegeQuicklinkHinzu(QuicklinkselementModel model): Hinzufügen eines neuen Quicklinks auf der aktuellen Seite,

  • entferneQuicklink(String id): Entfernen des Quicklinks von der Seite.

Quicklinks werden in der Session des Anwenders abgespeichert.

Die zuletzt hinzugefügten Quicklinks werden oben dargestellt. Wenn ein Quicklink hinzugefügt wird, der bereits vorhanden ist (Identifikation über seine ID), dann werden der Link und der anzuzeigende Text des Quicklinks aktualisiert und der Quicklink wird nach oben gesetzt. Wenn die maximale Anzahl an Quicklinks erreicht wird (konfigurierbar über den Konfigurationsparameter gui.quicklinks.max.anzahl), dann wird der älteste Quicklink entfernt.

Weiterhin gibt es die Möglichkeit, Quicklinks in Gruppen zu organisieren (z.B. aktuelle Suchanfrage, letzte Suchanfragen). Gruppen von Quicklinks können abhängig vom aktuellen Flow angezeigt werden.

Weiterhin ist es möglich, die Quicklinks statisch (analog zur Linksnavigation) zu konfigurieren. Hierzu können in der Konfiguration folgende Einstellungen hinterlegt werden:

  • gui.quicklinks.gruppenIds: kommaseparierte Liste der Gruppen

  • gui.quicklinks.<gruppeId>.text: Text der Gruppe zur Anzeige

  • gui.quicklinks.<gruppeId>.contextflow: kommaseparierte Liste an Flows, welche die Anzeige der Gruppe erlauben.

Ist keine Konfiguration bzgl. Flows gesetzt, so wird die Gruppe immer angezeigt.

Auf der Detailseite einer Applikation kann in der Titelzeile ein Location-Breadcrumb eingeblendet werden. In diesem Breadcrumb wird der Pfad zum aktuellen Element angezeigt (Breadcrumb in der Titelzeile der Detailseite der Applikation).

breadcrumb
Abbildung 37. Breadcrumb in der Titelzeile der Detailseite der Applikation

Die angezeigten Daten werden nicht automatisch angezeigt, sondern müssen programmatisch gesetzt werden. Hierzu wird die Model-Klasse LocationBreadcrumbModel entsprechend befüllt. Ist das Breadcrumb-Model leer, wird der Breadcrumb nicht angezeigt.

Eine Instanz des Breadcrumb-Models wird über das BasisModel bereitgestellt. Unterstützt wird die Anzeige von Hierarchieebene über die Methoden pushHierarchiebene() / popHierarchiebene / clearHierarchiebenen() und die Angabe eines Objektnamens per setObjektname(String). Mit dem in Verwendung des Breadcrumb-Models gezeigten Code wird der in Breadcrumb in der Titelzeile der Detailseite der Applikation gezeigte Breadcrumb realisiert.

Listing 68. Verwendung des Breadcrumb-Models
public void initialisiereBreadcrumbModel(LocationBreadcrumbModel model) {
    model.setObjektname("Testobjekt / ID-1234");
    model.pushHierarchiebene("Ebene 1");
    model.pushHierarchiebene("Ebene 2");
}

6.11.5. Seitentoolbar

Die Seitentoolbar ist Teil des BasisModel. Auf das SeitentoolbarModel kann daher über den BasisController zugegriffen werden. Der ApplikationseiteController und der DetailseiteController konfigurieren dieses Model entsprechend den Vorgaben automatisch.

Über die Template-Engine (ui:insert / ui:define) werden weiterhin folgende Bereiche zur Verfügung gestellt. Konkrete Seiten können dadurch Einfluss auf das Aussehen der Seitentoolbar nehmen:

  • seitentoolbarLinksButtons: fügt Anpassungen auf der linken Seite ein,

  • seitentoolbarMitteButtons: fügt Anpassungen in der Mitte (zentriert) ein,

  • seitentoolbarRechtsButtons: fügt Anpassungen auf der rechten Seite ein.

6.11.5.1. Hilfe-Button

Der Hilfe-Button ist Teil der Seitentoolbar und wird rechts von allen anderen konfigurierten Buttons angezeigt. Zur Konfiguration des Buttons muss eine URL zu einer Hilfeseite hinterlegt werden.

Listing 69. Konfiguration des Hilfe-Buttons
portalhilfe.url=https://example.com/hilfeanwendung

Wird auf den Button geklickt, wird abhängig von der aktuellen Seite, dem Flow und dem ViewState des Flows auf die Hilfeseite geleitet.

Der Hilfe-Button wird nur angezeigt, wenn wie beschrieben, portalhilfe.url gesetzt ist. Soll der Hilfe-Button standardmäßig ausgeschaltet bleiben, kann dies über den Parameter hilfe.default.aktiv in der Konfiguration der Anwendung erfolgen.

Listing 70. Ausschalten des Hilfe-Buttons
hilfe.default.aktiv=false

Das Aktivieren und Deaktivieren des Hilfe-Buttons ist auch durch Aufruf der entsprechenden HilfeController-Methode aus dem Flow heraus möglich. Das Ausschalten des Hilfe-Buttons in einem Flow zeigt das Ausschalten des Hilfe-Buttons in der XML-Datei eines Flows.

Listing 71. Ausschalten des Hilfe-Buttons in einem Flow
<on-start>
    <!-- ... andere Initialisierungen des Flows ... -->
    <evaluate expression="hilfeController.deaktiviereHilfe(hilfeModel)" />
</on-start>

6.12. Selektion

Dieser Abschnitt beschreibt Patterns zur Selektion von Daten.

6.12.1. Suche

Ein Beispiel zur Umsetzung eines Suchformulars findet sich im Abschnitt Layout von Formularen.

6.12.2. Toggle Filter

Ein Toggle-Filter ist eine Tabellen-Toolbar, mit der durch einen Klick auf einen Button eine Liste von Objekten oder Formularen nach bestimmten vordefinierten Kriterien eingeschränkt werden kann. Der Filter wird über das Tag <isy:toggleFilter> eingebunden und die einzelnen Filter-Optionen sollten als <f:selectItem> angegeben werden.

Die Komponente besitzt folgende notwendige Parameter:

  • action: Die auszuführende Aktion.

Außerdem gibt es folgende optionale Parameter:

  • label: Der Text für das Label.

  • value: Der ausgewählt Filter.

  • styleClass: Optionale CSS Style Klasse.

  • execute: AJAX: Welcher Template-Seitenbereich ausgeführt werden soll. (Standard: @form)

  • render: AJAX: Welcher Template-Seitenbereich gerendert werden soll. (Standard: @form)

  • globalConfig: Eine spezifische globale Konfiguration, falls nötig. (Standard: #{globalConfigurationModel})

6.12.3. Browse & Collect

Mit Browse & Collect kann der Benutzer eine Liste von Objekten erstellen. Hierbei werden Objekte von einer Quellliste in eine Zielliste übertragen.

Browse & Collect kann über das Tag <isy:browseAndCollect> (bzw. <isy:formBrowseAndCollect>) eingebunden werden.

Folgende Parameter sind für <isy:browseAndCollect> verpflichtend:

  • reference: Die Referenz des Objekts.

  • value: Der Wert der Auswahl für das Databinding

Außerdem gibt es folgende optionale Parameter:

  • disabled: Gibt an, ob die Liste deaktiviert ist. (Standard: false)

  • browsecollectStyleClass: Die CSS-Klasse für die Komponente.

  • size: Anzahl der Zeilen, die sichtbar sind

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

Außerdem gibt es folgende optionale Parameter:

  • disabled: Gibt an, ob die Liste deaktiviert ist. (Standard: false, Typ: Boolean)

  • browsecollectStyleClass: Die CSS-Klasse für die Komponente.

  • size: Dieses Attribut wird im Sinne von bootstrap-selectlist.js interpretiert, d.h. es gibt die Anzahl der Zeilen, die sichtbar sind, an.

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

Folgende Parameter sind zusätzlich für <isy:formBrowseAndCollect> zulässig:

  • label: Der Text für das Label.

  • labelStyleClass: Die CSS-Klasse für das Label. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich. (Standard: col-lg-6)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

6.12.4. Master-Detail

Bei dem Master-Detail Konzept werden Informationen eines Master-Objekts und dessen Details auf einer Seite dargestellt. Zum Beispiel kann eine Liste von Objekten in einer Tabelle (Master) dargestellt werden. Die dazugehörigen Informationen (Detail) werden je nach Layout in einem Bereich darunter oder daneben angezeigt.

Die Master-Detail-Ansicht kann durch die Nutzung von einfachen Elementen (Tabelle, Buttons, bedingtes Rendern (ui:fragment)) umgesetzt werden.

6.13. Gruppierung

Dieser Abschnitt beschreibt Patterns zur Gruppierung von Daten.

6.13.1. Panel

Für die Gruppierung von Daten steht das Tag <isy:panel> bereit. Damit können entsprechende Bereiche zur Gruppierung erstellt werden. Ein Expander kann durch die Angabe von collapse="true" und der Angaben eines entsprechenden Models in der Komponente <isy:panel> erzeugt werden. Über das Model lässt sich auch der initiale Zustand steuern.

6.13.2. Komponente panel

Das Tag <isy:panel> bietet folgende Facets:

  • panelHeader: Header des Panels

  • panelButtons: Buttons am Header des Panels

  • panelBody: Inhalt des Panels (kann auch direkt über Kindelemente angegeben werden)

Außerdem gibt es folgende optionale Parameter:

  • panelModel: Model des Panels, das von PanelModel abgeleitet wird, und Teil des Seitenmodels sein sollte. Nur notwendig, falls das Panel einklappbar sein soll. (Typ: de.bund.bva.isyfact.common.web.jsf.components.panel.PanelModel)

  • collapse: Gibt an, ob das Panel einklappbar sein soll. Falls ja, so muss auch ein panelModel angegeben werden. (Standard: false, Typ: Boolean)

  • panelId: ID des Panels.

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

6.13.3. Komponente panelGroup

Zur Gruppierung von mehreren Panels sollte das Tag <isy:panelGroup> verwendet werden. In diesem können die anderen Panels geschachtelt werden. Das Tag besitzt folgende Parameter:

  • headerPanel: Gibt an, ob die Gruppe als Container für den Header des Inhaltsbereichs dient. Falls ja, werden entsprechende CSS-Klassen für das Layouting eingebunden. (Standard: false, Typ: java.lang.Boolean)

6.14. Layout von Formularen

Die Umsetzung von Formularen erfolgt mit den gängigen CSS-Klassen von Bootstrap. Um ein einfaches Suchformular umzusetzen, genügt z.B. folgender Code:

Listing 72. Beispiel für Formularumsetzung
<div>
    <div class="form-horizontal">
      <div class="row">
        <div class="col-lg-6">
          <isy:formInput reference="vorname" />
          <isy:formInput reference="nachname" />
        </div>
        <div class="col-lg-6">
          <isy:formInput reference="geburtsort" />
          <isy:formSelectOneDropdown reference="geschlecht" />
          <isy:formListpicker reference="staatsangehoerigkeit" />
        </div>
      </div>
    </div>

    <!-- ... -->

    <isy:buttonRow alignRight="true">
      <isy:button id="suchen" action="suchen" value="#{...}" />
      <isy:button id="suchfelderLeeren" action="suchfelderLeeren" value="#{...}" />
    </isy:buttonRow>
</div>

Durch ein <div>-Tag mit der CSS-Klasse form-horizontal wird der Bereich für das Formular definiert. In darin geschachtelten <div>-Tags mit der CSS-Klasse row ist das aus 12 Spalten bestehende Layout von Bootstrap aktiv. Innerhalb dieser Tags können die Formularkomponenten problemlos verwendet werden.

6.14.1. Formularkomponenten

Neben den normalen Bedienelementen existieren auch Formularkomponenten (erkennbar an dem Präfix <isy:form…​>). Diese Komponenten integrieren sich direkt in ein Formular. Sie bringen ein Label sowie eine integrierte Validierung mit sich. Die einzelnen Formularkomponenten sind zusammen mit ihren jeweiligen Bedienelementen beschrieben.

In den Formularen kann durch die Verwendung von <isy:formDefaultButton> ein Standard-Button zum Abschicken des Formulars definiert werden. Ein Druck auf kbd:[Enter] führt die Aktion aus. Diese Funktionalität ist nur bei aktiviertem JavaScript verfügbar.

Das Tag <isy:formCustom> bietet schließlich die Möglichkeit, anwendungsspezifische Elemente in ein Formular zu integrieren. Die Elemente innerhalb dieses Tags werden dann mit einem Label an der korrekten Stelle im Formular angezeigt.

Die Komponente unterstützt folgende Attribute:

  • reference: Die Referenz des Objekts für die Validierung.

  • label: Der Text für das Label.

  • labelStyleClass: Die CSS-Klasse für das Label. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich. (Standard: col-lg-6)

  • escapeLabel: Gibt an, ob Sonderzeichen für das Label escaped werden sollen. (Standard: false)

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

  • breakWords: Gibt an, ob der Überlauf von Text in die nächste Zeile erlaubt ist. (Standard: true)

Die Komponente besitzt folgende Facets:

  • contentRight: Inhalt, der rechts vom eingefügten Element angezeigt wird

6.15. Platzhalter

Platzhalter können über das Attribut placeholder in den Bedienelementen angegeben werden. Die Angabe von Platzhaltern ist derzeit noch nicht in allen Bedienelementen möglich.

6.16. Tooltips

Das Tag <isy:tooltip> bindet einen Tooltip ein und wird in der Regel um ein Hover-Element gelegt.

Die Komponente besitzt folgende notwendige Parameter:

  • text: Text, der bei Hover über das Element angezeigt werden soll.

Außerdem gibt es folgende optionale Parameter:

  • title: Optionale Überschrift, die fett über dem Text angezeigt wird,

  • globalConfig: Spezifische, globale Konfiguration. (Standard: #{globalConfigurationModel})

6.17. Anzeige von Pflichtfeldern und optionalen Pflichtfeldern

Pflichtfelder können über die Angabe des Attributs required am entsprechenden Bedienelement gesetzt werden.

Optionale Pflichtfelder bedeuten, dass von mehreren, alternativen Eingaben mindestens eine benötigt wird, um das Formular verarbeiten zu können.

Beispielsweise könnte in einem Formular die Eingabe entweder der Nummer des Personalausweises oder der Nummer des Führerscheins als Altersnachweis dienen. Wenn der Altersnachweis Pflicht ist, sind die beiden Felder optionale Pflichtfelder.

6.18. Anzeige von Nachrichten

Der MessageController erlaubt es, Nachrichten über dem Inhaltsbereich einer Seite auszugeben. Er bietet folgende Methoden für Hinweise, Erfolgsmeldungen, Warnungen und Fehlermeldungen an:

  • void writeInfoMessage(String information)

  • void writeSuccessMessage(String success)

  • void writeWarnMessage(String warning, String summary)

  • void writeErrorMessage(String error, String summary)

Weiterhin können Anwendungen die aktuell vorhandenen Meldungen auslesen:

  • List<FacesMessage> getCurrentInfoMessages()

  • List<FacesMessage> getCurrentSuccessMessages()

  • List<FacesMessage> getCurrentWarnMessages()

  • List<FacesMessage> getCurrentErrorMessages()

Das Tag <isy:messages> zeigt Nachrichten im Basis-Layout automatisch und ohne weiteres zutun an.

6.19. Validierung

Der ValidierungController erlaubt es, der aktuellen Seite über folgende Methode Nachrichten der Validierung hinzuzufügen:

  • void processValidationMessages(List<ValidationMessage> validationMessages)

Eine einzelne Nachricht besteht dabei aus folgenden Attributen:

  • code: Der (Fehler)Code der Nachricht, (z.B. ISYWG99999)

  • reference: Die Referenz auf den Fehler, (z.B. person.geburtsdatum)

  • readableReference: Die lesbare Darstellung der Referenz,(z.B. "Geburtsdatum")

  • message: Text der Nachricht. (z.B. "Geburtsdatum liegt weniger als 18 Jahre zurück.")

Validierungsnachrichten werden nur für den aktuellen Aufruf (FlashScope) angezeigt. Wenn JavaScript nicht aktiviert ist, werden alle Validierungsnachrichten in einer Liste angezeigt. Auf den Tooltip wird verzichtet. Für die Zuordnung von Validierungsnachrichten und Eingabefeld wird das Attribut reference verwendet, welches auch in der entsprechenden Formularkomponente angegeben werden muss.

6.20. 4-Augen-Prinzip

Einige JSF-Komponenten unterstützen das 4-Augen-Prinzip. Hierbei müssen Eingaben erst von einer zweiten Person bestätigt werden, bevor sie in das Datenmodell übernommen werden. Die Namensgebung der 4-Augen-Komponenten folgt dem Schema, dass dem Namen der Basiskomponente der Zeichenstring WithFourEyes angehängt wird.

Die IsyFact enthält die Demo-Anwendung isy-webgui und zeigt darin die Features der Bibliothek isy-web. Insbesondere demonstriert die Demo-Anwendung Aussehen und Verhalten der nachfolgend beschriebenen JSF-Seitenelemente. Alle Screenshots der beschriebenen 4-Augen-Prinzip Komponenten wurden dieser Demo-Anwendung entnommen.

Zu den folgenden JSF-Komponenten existieren Varianten für das 4-Augen-Prinzip.

Tabelle 3. JSF-Komponenten für das 4-Augen-Prinzip
JSF-Komponente Variante für das 4-Augen-Prinzip

<isy:actionInput />

<isy:actionInputWithFourEyes />

<isy:formActionInput />

<isy:formActionInputWithFourEyes />

<isy:formCheckbox />

<isy:formCheckboxWithFourEyes />

<isy:formCurrencyInput />

<isy:formCurrencyInputWithFourEyes />

<isy:formDate />

<isy:formDateWithFourEyes />

<isy:formInput />

<isy:formInputWithFourEyes />

<isy:formNumericInput />

<isy:formNumericInputWithFourEyes />

<isy:formSelectOneDropdown />

<isy:formSelectOneDropdownWithFourEyes />

<isy:formTextarea />

<isy:formTextareaWithFourEyes />

<isy:selectOneDropdown />

<isy:selectOneDropdownWithFourEyes />

Für die Konfiguration einer JSF-Komponenten-Variante (4-Augen-Prinzip) gilt generell, dass bis auf zwei weitere, hinzuzufügende Attribute, die Attribute identisch zur Basiskomponente sind.

Die folgenden zwei Attribute sind 4-Augen-Prinzip spezifisch und ergänzen die jeweiligen Komponentenattribute der Basiskomponente:

  • fourEyesMode: Pflichtfeld, welches den Zustandsmodus des Feldes angibt [locked|unlocked].

  • fourEyesLastValue: Wert, der vom ersten Bearbeiter eingegeben wurde.

Die 4-Augen-JSF-Komponenten benötigen kein eigenes Modell oder spezifischen Controller, sondern speichern die Felddaten im Modell der Maske ab und verwenden den normalen Controller der Maske (s.a. Erstellung der Controller).

Die Geschäftslogik, die hinter einer 4-Augen-Komponente steckt, wird entsprechend dem MVC-Muster nicht in der Komponente selbst, sondern im Maskencontroller (s.a. 4-Augen-Komponente Controller: Initialisierung und Action-State (speichern)) behandelt.

Es gibt bei der Implementierung der Geschäftslogik der 4-Augen Komponenten keine Vorgaben bzgl. der zu verwendenden Methoden. Da der Grundgedanke der 4-Augen-Komponenten darin besteht, dass Eingaben erst von einer zweiten Person bestätigt werden, bevor sie in das finale Datenbankfeld gelangen, bietet es sich an, über Methoden die Model- und Datenpflege (init…​, speichern) vorzunehmen.

Die folgenden beiden Listings zeigen entsprechende Codebeispiele für die Umsetzung dieses Grundgedankens im Maskenflow und -controller.

Listing 73. 4-Augen-Komponente Flow: Initialisierung und Action-State (speichern)
<flow>
   <var name="maskenModel" class="de.bund.bva... .VieraugenMaskeModel"/>
   <on-start>
      <evaluate expression="maskenController.initModel(maskenModel)"/>
   </on-start>

   <view-state id="vieraugenMaskeViewState">
      <on-entry>
         <evaluate expression="maskenController.initModel(maskenModel)"/>
      </on-entry>
      <transition on="speichern">
         <evaluate expression="maskenController.initModel(maskenModel)"/>
      </transition>
      ...
   </view-state>
</flow>

Der Wert einer 4-Augen-Komponente kann zum Beispiel in der Model-Initialisierungsmethode gesetzt werden.

Listing 74. 4-Augen-Komponente Controller: Initialisierung und Action-State (speichern)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import de.bund.bva.isyfact.common.web.global.AbstractGuiController;
import de.bund.bva.isyfact.common.web.global.GlobalFlowController;
import de.bund.bva.isyfact.common.web.validation.ValidationMessage;
import de.bund.bva.isyfact.util.spring.MessageSourceHolder;

@Controller
public class VieraugenMaskenController extends AbstractGuiController<VieraugenMaskeModel> {

    @Autowired
    private GlobalFlowController globalFlowController;
    private VieraugenMaskeModel model = new VieraugenMaskeModel();

    public void speichern(VieraugenMaskeModel model) {
      // ...
    }

    @Override
    public void initModel(VieraugenMaskeModel model) {
        List<ValidationMessage> validationMessages = new ArrayList<>();
        validationMessages.add(new ValidationMessage("WEBxyz", "fehler",
 		  "fehler", MessageSourceHolder.getMessage("WEBxyz")));

        this.globalFlowController.getValidationController().
		     processValidationMessages(validationMessages);
		// ...
    }
}

6.20.1. ActionInputWithFourEyes

Ein Aktionseingabefeld mit dem Vier-Augen-Prinzip Modus wird über die Tags <isy:actionInputWithFourEyes> bzw. <isy:formActionInputWithFourEyes> eingebunden.

demopanel formActionInput
Abbildung 38. Demo-Anwendung: isy_formActionInput

Das Aktionseingabefeld <isy:actionInputWithFourEyes> besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • action: Die auszulösende Aktion,

  • icon: Das anzuzeigendes Icon aus der Icon-Bibliothek,

  • fourEyesMode: Zustandsmodus des Feldes [locked|unlocked].

Außerdem gibt es folgende optionale Parameter:

  • fourEyesLastValue: Wert, der vom ersten Bearbeiter eingegeben wurde.

  • placeholder: Platzhalter, welcher im Eingabefeld angezeigt wird.

  • maxlength: Die maximale Länge der Eingabe, (Standard: 20)

  • iconColor: Farbe des Icons, (Standard: #45484D)

  • tooltip: Tooltip, der über dem Eingabefeld angezeigt wird. (Standard: …​, drei Punkte)

  • mode: [normal|button-only|input-only]. normal für Eingabefeld und Icon aktiv, button-only für nur Icon aktiv, input-only für nur Eingabefeld aktiv, (Standard: normal)

  • disabled: Flag, ob das Eingabefeld deaktiviert ist. (Standard: false)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false)

  • inputStyleClass: Die CSS-Klasse für das Eingabefeld. (nicht implementiert)

6.20.2. FormActionInputWithFourEyes

Zusätzlich zu den eben genannten Parametern bei <isy:actionInputWithFourEyes> sind bei Verwendung von <isy:formActionInputWithFourEyes> auch folgende Parameter zulässig:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse des Labels, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse des Eingabebereiches, (Standard: col-lg-6)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Spezifische, globale Konfiguration. (Standard: globalConfigurationModel)

6.20.3. CheckboxWithFourEyes

Die Komponente <isy:formCheckboxWithFourEyes> stellt ein Eingabefeld nach dem Vier-Augen-Prinzip für eine Checkbox innerhalb von Formularen zur Verfügung.

demopanel formCheckboxWithFourEyes
Abbildung 39. Komponente isy_formCheckboxWithFourEyes

Folgende Komponentenattribute müssen angegeben werden:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • disabled: Gibt an, ob die Checkbox deaktiviert ist oder nicht. (Standard: false)

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Folgende Komponentenattribute sind optional:

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • label: Der Text für das Label,

  • labelRight: Fontawesome char-Zeichen für die Anzeige rechts neben dem Eingabefeld, (Standard: offenes Vorhängeschloss)

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • optional: Gibt an, ob die Eingabe eine Optionale-Pflichteingabe ist (blaues Sternchen). (Standard: false, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • valueChangeListener: Value Change Listener,

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld.

Listing 75. Codebeispiel für formCheckboxWithFourEyes JSP-Komponente
<!-- formCheckbox with FourEyes -->

<div class="form-horizontal">
    <div class="row">
        <div class="col-lg-12">
            <isy:formCheckboxWithFourEyes
                    id="cbtest2FourEyes" reference="cbtest2FourEyes"
                    value="#{jsfSteuerelementeModel.checkboxBoolean1}"
                    label="Eine Auswahl" disabled="false"
                    labelStyleClass="col-lg-3"
                    inputStyleClass="col-lg-1"
                    valueChangeListener="#{jsfSteuerelementeController.checkboxAusgewaehlt}"
                    fourEyesMode="unlock">
            </isy:formCheckboxWithFourEyes>
        </div>
    </div>
</div>

6.20.4. CurrencyInputWithFourEyes

Die Komponente <isy:formCurrencyInputWithFourEyes> stellt ein Eingabefeld für eine Fließkommazahl nach dem Vier-Augen-Prinzip innerhalb von Formularen zur Verfügung.

demopanel formCurrencyInput
Abbildung 40. Ansicht von isy_formCurrencyInputWithFourEyes

Die Komponente besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • placeholder: Der Platzhalter, welcher im Eingabefeld angezeigt wird.

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false, Typ: Boolean)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255, Typ: Integer)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • onchange: onchange JavaScript-Funktion wird aufgerufen, wenn der Cursor das Feld verlässt. (Standard: formatAmountOfMoney(this))

  • onkeyup: onkeyup JavaScript-Funktion wird aufgerufen, wenn eine Tastatureingabe in dem Feld gemacht wurde. (Standard: deleteNonDigitCharacters(this))

  • decimalplaces: Die Anzahl der Nachkommastellen, (Standard: 2, Typ: Integer)

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld,

  • alignright: Gibt an, ob der Text innerhalb des Eingabefeldes rechts ausgerichtet sein soll. (Standard: false, Typ: Boolean)

Folgender Hinweis ist bei der Eingabe von Geldbeträgen zu beachten:

  • die eingegebene Zahl wird ab einer Länge von mehr als 15 Ziffern automatisch gerundet. Daraus lassen sich folgende Beispiele ableiten:

    • Ohne Nachkommastelle ist 999999999999999

    • für 1 Nachkommastelle ist 99999999999999,9

    • für 2 Nachkommastellen ist 9999999999999,99 der maximale Betrag ohne Rundung.

Listing 76. Codebeispiel für formCurrencyInputWithFourEyes JSP-Komponente
<!-- formCurrencyInputWithFourEyes -->

<div class="form-horizontal">
	<div class="row">
		<isy:formCurrencyInputWithFourEyes
				label="isy:formCurrencyInput"
				labelStyleClass="col-lg-2" inputStyleClass="col-lg-2"
				required="true" placeholder="24,00" value=""
				reference="formCurrencyInputFourEyes" fourEyesMode="locked"
				fourEyesLastValue="Letzter Wert">
		</isy:formCurrencyInputWithFourEyes>
	</div>
</div>

6.20.5. FormDateWithFourEyes

Die Komponente <isy:formDateInputWithFourEyes> stellt ein Eingabefeld für eine Datumseingabe mit dem Vier-Augen-Prinzip innerhalb von Formularen zur Verfügung.

demopanel formDate
Abbildung 41. Demo-Anwendung: isy_formDateWithFourEyes Varianten

Folgende Komponentenattribute müssen angegeben werden:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Folgende Komponentenattribute sind optional:

  • tooltip: Tooltip, (Standard: '')

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • inputFieldClass: Die CSS-Klasse für das Input-Feld im Eingabebereich, (Standard: ``)

  • placeholder: Der Platzhalter, welcher im Eingabefeld angezeigt wird. (Standard: TT.MM.JJJJ)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

  • language: Die Sprache für den Datepicker, (Standard: de)

  • dateFormat: Das Datumsformat für den Datepicker, (Standard: dd.mm.yyyy)

  • inputmask: Das Maskenformat für das Eingabefeld, (Standard: 99.99.9999)

  • inputmaskInsertMode: Die Eingabemaske: Gibt an, ob der Text beim Eintippen überschrieben werden soll. (Standard: true, Typ: Boolean)

  • inputmaskClearOnBlur: Die Eingabemaske: Gibt an, ob beim Verlassen des Feldes die Maskierungsplatzhalter ausgeblendet werden sollen. (Standard: true, Typ: Boolean)

  • showPicker: Gibt an, ob Picker angezeigt werden soll. (Standard: true, Typ: java.lang.Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld.

Listing 77. Codebeispiel für formDateWithFourEyes JSP-Komponente
<div class="row">
	<h2>isy:formDateWithFourEyes</h2>
</div>

<div class="col-lg-12">
	<div class="row">
		<div class="col-lg-8">
			<isy:formDateWithFourEyes
					reference="formDate"
					label="formDate mit fourEyesMode=unlocked" value=""
					readonly="#{false}" fourEyesMode="unlocked"
					fourEyesLastValue="letzter Wert"
					inputStyleClass="col-lg-3"
					placeholder="#{msg.MEL_Components_formDate_Datum_Placeholder}"/>
		</div>
	</div>
</div>

6.20.6. FormInputWithFourEyes

Die Komponente <isy:formInputWithFourEyes> stellt ein Eingabefeld unter Verwendung des Vier-Augen-Prinzips innerhalb von Formularen zur Verfügung.

demopanel formInput
Abbildung 42. Demo-Anwendung: isy_formInputWithFourEyes Varianten

Folgende Facets können innerhalb des Tags verwendet werden:

  • contentRight: Das Icon, welches rechts neben dem Feld angezeigt wird.

Die Komponente besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Außerdem gibt es folgende optionale Parameter:

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • placeholder: Der Platzhalter, welcher im Eingabefeld angezeigt wird.

  • inputmask: Die Eingabemaske,

  • inputmaskInsertMode: Die Eingabemaske: Gibt an, ob text soll überschrieben werden beim eintippen. (Standard: true, Typ: Boolean)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255, Typ: Integer)

  • width: Die maximale Breite des Eingabefeldes, (Standard: 100%)

  • showPrintView: Zur aktuellen Druckansicht-Anzeige aus dem BasisModel, (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • tooltip: Tooltip, (Standard: '')

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • charpicker: Gibt an, welche Eingabe für Sonderzeichen verwendet werden soll. Wird der Wert auf dinNorm gesetzt, wird der neue Character-Picker verwendet, welcher alle Zeichen der DIN NORM 91379 unterstützt. Für Rückwärtskompatibilität kann weiterhin der Wert dinSpec verwendet werden. Soll der alte Legacy-Character-Picker verwendet werden, muss der Wert auf special gesetzt werden. Standardmäßig wird kein Character-Picker verwendet.

  • type: Der Typ des Eingabefelds, sodass diese Komponente z.B. auch für Passwort-Felder verwendet werden kann. Mögliche Werte alle Werte für das Feld type des HTML Input Felds. (Standard: text)

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld.

Der CharPicker funktioniert wie im Abschnitt Character-Picker beschrieben.

Codebeispiel:

Listing 78. Codebeispiel für formInputWithFourEyes JSP-Komponente
<div class="row">
	<h2>isy:formInputWithFourEyes</h2>
</div>

<div class="form-horizontal">
	<div class="row">
		<isy:formInputWitohFurEyes
			id="formInputFourEyes"
			type="text" label="Text: "
			labelStyleClass="col-lg-2"
			inputStyleClass="col-lg-2"
			reference="formInputReferenz"
			value="#{jsfSteuerelementeModel.formInputField8}"
			fourEyesMode="locked"
			fourEyesLastValue="Letzter Wert"/>
	</div>
</div>

6.20.7. FormNumericInputWithFourEyes

Die Komponente <isy:formNumericInputWithFourEyes> stellt ein Eingabefeld unter Verwendung des Vier-Augen-Prinzips innerhalb von Formularen zur Verfügung.

demopanel formNumericInputWithFourEyes
Abbildung 43. Demo-Anwendung: isy_formNumericInputWithFourEyes Varianten

Die Komponente besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Außerdem gibt es folgende optionale Parameter:

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label, (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • placeholder: Der Platzhalter, welcher im Eingabefeld angezeigt wird.

  • disabled: Gibt an, ob das Eingabefeld deaktiviert ist. (Standard: false, Typ: Boolean)

  • maxlength: Die maximale Länge der Eingabe, (Standard: 255, Typ: Integer)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • onchange: onchange JavaScript-Funktion wird aufgerufen, wenn der Cursor das Feld verlässt. (Standard: formatNumericValue(this))

  • onkeyup: onkeyup JavaScript-Funktion wird aufgerufen, wenn eine Tastatureingabe in dem Feld gemacht wurde. (Standard: deleteNonDigitCharacters(this))

  • decimalplaces: Die Anzahl der Nachkommastellen: Default ist 0. (Standard: 0, Typ: Integer)

  • tausenderPunkt: Wird ein Tausender-Punkt gewünscht? (Standard: false, Typ: Boolean)

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld,

  • alignright: Gibt an, ob der Text innerhalb des Eingabefeldes rechts ausgerichtet sein soll. Default ist false.(Standard: false, Typ: Boolean)

Codebeispiel:

Listing 79. Codebeispiel für formNumericInputWithFourEyes JSP-Komponente
<div class="row">
	<h2>isy:formNumericInputWithFourEyes</h2>
</div>
<div class="col-lg-12">
	<div class="row">
				<isy:formNumericInputWithFourEyes
				label="formNumericInput mit fourEyesMode=unlocked"
				placeholder="24,00" fourEyesMode="unlocked"
				fourEyesLastValue="letzter Wert" value="" readonly="false"
				reference="formNumericInput2"/>

		<isy:formNumericInputWithFourEyes
				label="formNumericInput mit fourEyesMode=locked Fehler"
				placeholder="24,00" fourEyesMode="locked"
				fourEyesLastValue="letzter Wert" value="36,00" readonly="false"
				reference="fehlerPlatzhalter"/>
	</div>
</div>

6.20.8. FormSelectOneDropDownWithFourEyes

Die Komponente <isy:formSelectOneDropDownWithFourEyes> stellt ein Eingabefeld für ein Dropdownfeld mit dem Vier-Augen-Prinzip innerhalb von Formularen zur Verfügung.

demopanel formSelectOneDropdownWithFourEyes
Abbildung 44. Demo-Anwendung: isy_formSelectOneDropdownWithFourEyes Varianten

Folgende Komponentenattribute müssen angegeben werden:

  • reference: Die Referenz des Objekts,

  • value: Der Wert der Auswahl für das Databinding,

  • fourEyesMode: Events müssen explizit deklariert werden.

Folgende Komponentenattribute sind optional:

  • invalid: Gibt an, ob die Auswahl invalide ist oder nicht. (Standard: false, Typ: Boolean)

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

Besonderheit: Das formSelectOneDropDownWithFourEyes-Widget wird im Modus readonly="true" als Label gerendert und ohne Schloss-Icon dargestellt.

  • valueChangeListener: Value Change Listener,

  • fourEyesLastValue: 4 Augen Prinzip Mode, (locked, unlock)

  • converter: Letzter Wert im 4-Augen-Eingabefeld,

  • converterAttribute: Konverter-Bean für die angezeigten Elemente,

  • label: Parameter für den Konverter,

  • labelStyleClass: Formspezifisch, (Standard: col-lg-6)

  • inputStyleClass: Der Text für das Label, (Standard: col-lg-6)

  • dropdownStyleClass: Die CSS-Klasse für das Label, (Standard: form-selectonedropdown)

  • showPrintView: Die CSS-Klasse für den Eingabebereich, (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Zur aktuellen Druckansicht-Anzeige aus dem BasisModel. (Standard: #{globalConfigurationModel})

6.20.9. FormTextAreaWithFourEyes

Die Komponente <isy:formTextAreaWithFourEyes> stellt ein mehrzeiliges Texteingabefeld nach dem Vier-Augen-Prinzip innerhalb von Formularen zur Verfügung.

demopanel formTextarea
Abbildung 45. Demo-Anwendung: isy_formTextareaWithFourEyes

Folgende Komponentenattribute müssen angegeben werden:

  • reference: Die Referenz des Objekts,

  • value: Der Wert für das Databinding im Eingabefeld,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Folgende Komponentenattribute sind optional:

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • required: Gibt an, ob die Eingabe eine Pflichteingabe ist. (Standard: false, Typ: Boolean)

  • disabled: Gibt an, ob die Bearbeitung aktiviert ist oder nicht(Standard: false, Typ: Boolean)

  • readonly: Gibt an, ob auf das Feld nur lesend zugegriffen wird. (Standard: false, Typ: Boolean)

  • label: Der Text für das Label,

  • labelStyleClass: Die CSS-Klasse für das Label. (Standard: col-lg-6)

  • inputStyleClass: Die CSS-Klasse für den Eingabebereich, (Standard: col-lg-6)

  • textareaStyleClass: Die CSS-Klasse für die Textarea, (Standard: ``)

  • tooltip: Der Tooltip, welcher angezeigt wird.

  • placeholder: Der Platzhalter, welcher im Eingabefeld angezeigt wird.

  • rows: Die Anzahl an Zeilen, (Standard: 5, Typ: Integer)

  • cols: Die Anzahl an Spalten, (Typ: Integer)

  • maxlength: Die maximal Anzahl von Zeichen, (Standard: 4000, Typ: Integer)

  • showPrintView: Zur aktuellen Druckansicht-Anzeige aus dem BasisModel, (Standard: #\{not empty basisModel and basisModel.showPrintView}, Typ: Boolean)

  • validationModel: Ein spezifisches Validation-Model, falls benötigt. (Standard: #{validationModel})

  • globalConfig: Eine spezifische globale Konfiguration, falls benötigt. (Standard: #{globalConfigurationModel})

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld.

Listing 80. Codebeispiel für formTextAreaWithFourEyes JSP-Komponente
<div class="row">
	<h2>isy:formTextareaWithFourEyes</h2>
</div>
<div class="col-lg-12">
	<div class="row">
		<isy:formTextareaWithFourEyes
				id="formTextarea2"
				label="formTextarea mit  grey normal"
				reference="formTextarea2"
				readonly="false" value="" fourEyesMode="unlocked"
				fourEyesLastValue="letzter Wert" rows="3"/>
	</div>
</div>

6.20.10. SelectOneDropdownWithFourEyes

Die Komponente <isy:selectOneDropdownWithFourEyes> stellt ein Dropdownfeld nach dem Vier-Augen-Prinzip zur Verfügung, aus dem man einen Eintrag auswählen kann.

demopanel selectOneDropdownWithFourEyes
Abbildung 46. Demo-Anwendung: isy_selectOneDropdownWithfourEyes

Gegenüber der Komponente <isy:selectOneDropdownWithfourEyes> besitzt <isy:selectOneDropdownWithfourEyes> kein (vorangestelltes) Label, sondern nur eine Tooltip-Beschreibung, welches über das Attribut 'title' gesetzt werden kann.

Die Komponente besitzt folgende notwendige Parameter:

  • reference: Die Referenz des Objekts,

  • value: Der Wert der Auswahl für das Databinding,

  • fourEyesMode: 4 Augen Prinzip Mode (locked, unlock).

Außerdem gibt es folgende optionale Parameter:

  • referenceId: Der Wert der id, (Standard: #\{jsfHelper.escapeIdentifier(cc.attrs.reference)})

  • invalid: Gibt an, ob die Auswahl invalide ist oder nicht. (Standard: false, Typ: Boolean)

  • disabled: Gibt an, ob die Auswahl deaktiviert ist oder nicht. (Standard: false, Typ: Boolean)

  • title: Der Tooltip über dem SelectOneDropdown,

  • globalConfig: Eine spezifische globale Konfiguration, falls notwendig. (Standard: #{globalConfigurationModel})

  • dropdownStyleClass: Die CSS-Klasse für das Dropdown-Menü,

  • readonly: Gibt an, ob die Darstellung nur lesend erfolgen soll. (Standard: false, Typ: Boolean)

Besonderheit: Das formSelectOneDropDownWithFourEyes-Widget wird im Modus readonly="true" als Label gerendert und ohne Schloss-Icon dargestellt.

  • disabled: Gibt an, ob die Auswahl deaktiviert ist oder nicht. (Standard: false, Typ: Boolean)

  • converter: Konverter-Bean für die angezeigten Elemente,

  • converterAttribute: Parameter für den Konverter,

  • customId: Erlaubt, eine spezielle ID zu setzen, um die Komponente z.B. für JavaScript oder Tests zugreifbar zu machen. Diese wird im Attribut data-isy-custom-id eingetragen.

  • fourEyesLastValue: Letzter Wert im 4-Augen-Eingabefeld,

  • valueChangeListener: Value Change Listener.

Listing 81. Codebeispiel für selectOneDropdownWithFourEyes JSP-Komponente
<div class="row">
	<h2>isy:selectOneDropdownWithFourEyes</h2>
</div>
<div class="col-lg-12">
	<div class="row">
		<div class="col-lg-12">
			selectOneDropdown (kein Label, außerhalb einer Form).
		</div>
		<isy:selectOneDropdownWithFourEyes
				id="selectOneDropdownWithFourEyes"
				reference="selectOneDropdownWithFourEyes"
				readonly="false" value=""
				fourEyesMode="locked"
				fourEyesLastValue="letzter Wert">
			<f:selectItem itemvalue="" itemLabel="&nbsp; "/>
			<f:selectItems value="#{dropdownHelper.anredeListe}"/>
		</isy:selectOneDropdownWithFourEyes>
	</div>
</div>

6.21. FocusOnload

Die Komponente <isy:focusOnload> dient dazu, das initial zu fokussierende Element einer Seite anzugeben oder die initiale Fokussierung zu deaktivieren.

Die Komponente besitzt folgende notwendige Parameter:

  • element: Der Selektor für das Element, das initial fokussiert werden soll.

Außerdem gibt es folgende optionale Parameter:

  • deactivated: Gibt an, ob die initiale Fokussierung deaktiviert werden soll. (Standard: false, Typ: Boolean)

  • focus: Gibt an, ob das Element fokussiert sein soll, auch wenn im GlobalFlowModel die Fokussierung deaktiviert ist. (Standard: false, Typ: Boolean)

  • areaId: Der Selektor für das Element, das initial fokussiert werden soll. (Standard: focusOnloadArea)

6.22. PrintMetaInformationen

Das Tag <isy:printMetaInformation> dient bei Druckausgabe zur Ausgabe von Metainformationen wie z.B. eines Warnhinweises

Die Komponente besitzt folgende optionale Parameter:

  • warning: Die anzuzeigende Warnung, wenn die browserseitige Druckansicht einer Seite angezeigt wird (optional). (Standard: ``)

  • basis: BasisModel. (Standard: #{basisModel})