All posts by Marco

Automatisches Styling von nicht validen Eingabe-Komponenten

Cagatay Civici (Lead Developer von PrimeFaces) hat heute in seinem Blog einen Artikel veröffentlicht, der beschreibt, wie man Input Elementen auf einfachem Weg ein anderes Styling verpasst, wenn die Validierung fehlgeschlagen ist: Styling Invalid Input Fields with JSF.

Die vorgestellte Möglichkeit setzt dabei auf einen PostValidationListener, der am Ende der Validierungsphase aufgerufen wird und alle zu diesem Zeitpunkt invaliden Elementen eine zusätzliche CSS-Klasse gibt, die dann z.B. dem Text einen roten Hintergrund gibt.

Der Nachteil dieser Lösung ist, dass alle Änderungen am Zustand von Komponenten, die nach der Validierungsphase gemacht werden, nicht über diesen Listener laufen und somit auch kein Fehler-Styling bekommen.

So schön die Validierungsphase im JSF ist, ist es aber zumindest in meinen Projekten oft so, dass noch zusätzliche Validierungen in der Application-Phase notwendig sind, die natürlich auch in der GUI irgendwie dargestellt werden müssen. Das spätere Validieren ist z.B. oft notwendig, wenn es Abhängigkeiten zwischen verschiedenen Feldern gibt (z.B. ein Datum ist nur dann gültig, wenn es nach einem anderen Datum liegt) oder wenn ein eingegebener Wert komplexe Logik erfordert, die über EJB/JPA/Hibernate laufen muss und somit eine Transaktion und einen Datenbankzugriff erfordert.

Um dies nicht für jeden Einzelfall neu implementieren zu müssen oder pro Komponente einzeln im Template definieren zu müssen, setze ich einen PhaseListener ein, der in der Render-Phase aktiv wird (also nach der Validierungs- und nach der Aplication-Phase) und allen Komponenten, an denen direkt eine FacesMessage hängt, eine zusätzliche CSS-Klasse gibt. Der Code sieht ungefähr so aus:

public class CssStylePhaseListener implements PhaseListener {
	private static final String INVALID_INPUT_STYLE_CLASS = "error";
    
    public PhaseId getPhaseId() {  
		return PhaseId.RENDER_RESPONSE;  
	}  

	public void beforePhase(PhaseEvent arg0) {
		FacesContext context = FacesContext.getCurrentInstance();  
		UIViewRoot root =  context.getViewRoot();  
		Iterator<String> i = context.getClientIdsWithMessages();

		while (i.hasNext()) {  
			String id = i.next();  
			if (id==null||id.isEmpty()) {
				continue;
			}
			UIComponent component = root.findComponent(id);  		
			if (component instanceof UIInput) {  
				String style = (String) component.getAttributes().get("styleClass");  
				style = style == null ? "" : " " + style;  
				component.getAttributes().put("styleClass", INVALID_INPUT_STYLE_CLASS + style);  
			}  
		}  
		
	}
}

Ein Eintrag in der faces-config.xml ist auch hier noch notwendig:

<lifecycle>
	<phase-listener>com.entwicklertagebuch.CssStylePhaseListener</phase-listener>
</lifecycle>

Der PhaseListener geht dabei von der Annahme aus, dass direkt an einer Komponente ausschließlich Fehlermeldungen vorliegen und allgemeine Meldungen der Anwendung nicht direkt an einer Komponente hängen. Die automatisch erzeugten JSF-Fehlermeldungen aus der Validierungsphase erfüllen diese Voraussetzung immer. Möchte man eine Fehlermeldung aus der Anwendung heraus direkt an eine Komponente hängen, muss man dessen Client-ID kennen:

public void invalidateComponent(String id, String message) {
	UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(id);
	UIInput input = (UIInput) component;
	input.setValid(false);
	FacesContext.getCurrentInstance().addMessage(input.getClientId(), new FacesMessage(message));
}

Als Entwickler muss man jetzt nur noch wissen und beachten, dass man Validierungs-Fehler bzw. “richtige” Fehlermeldungen an eine Komponente hängen muss, um dem Benutzer automatisch einen optische Rückmeldung zu geben, dass hier eine Fehleingabe vorliegt.

Ich finde diesen Ansatz kompletter, als den Ansatz von Cagatay, wobei auch mein Ansatz durchaus noch Abhängigkeiten hat, die man als Entwickler kennen muss, so z.B. die ID-Ermittlung der Komponente, die man entweder hard-codieren muss oder die – wenn man sie wie oben beschrieben ermitteln möchte – die verschiedenen NamingContainer auf der Seite berücksichtigen muss, siehe den JavaDoc-Kommentar von “findComponent”.

Download Full Movie Passengers (2016)

Poster Movie Passengers 2016

Passengers (2016) HD

Director : Morten Tyldum.
Writer : Jon Spaihts.
Producer : Stephen Hamel, Michael Maher, Ori Marmur, Neal H. Moritz.
Release : December 21, 2016
Country : United States of America.
Production Company : Columbia Pictures, Village Roadshow Pictures, Original Film, Company Films, Start Motion Pictures, LStar Capital, Wanda Pictures.
Language : English.
Runtime : 116 min.
Genre : Adventure, Drama, Romance, Science Fiction.

‘Passengers’ is a movie genre Adventure, was released in December 21, 2016. Morten Tyldum was directed this movie and starring by Jennifer Lawrence. This movie tell story about A spacecraft traveling to a distant colony planet and transporting thousands of people has a malfunction in its sleep chambers. As a result, two passengers are awakened 90 years early.

Streaming Full Movie Passengers (2016)

Do not miss to Watch movie Passengers (2016) Online for free with your family. only 2 step you can Watch or download this movie with high quality video. Come and join us! because very much movie can you watch free streaming.

Watch and Download Full Movie Passengers (2016)

Incoming search term :

streaming movie Passengers, download movie Passengers 2016, Passengers 2016 Online Free Megashare, watch film Passengers now, Passengers live streaming movie, Watch Passengers 2016 Online Putlocker, film Passengers, Passengers 2016 English Full Episodes Download, movie Passengers 2016, Passengers 2016 HD Full Episodes Online, Passengers 2016 Full Episodes Watch Online, Passengers 2016 Full Episodes Online, watch Passengers 2016 film online now, film Passengers 2016 trailer, Watch Passengers 2016 Online Free Putlocker, film Passengers download, movie Passengers 2016 streaming, Passengers 2016 English Episodes, live streaming movie Passengers 2016 online, watch Passengers movie online now, Watch Passengers 2016 Online Free, watch Passengers movie now, Watch Passengers 2016 Online Megashare, Watch Passengers 2016 Online Free putlocker, Passengers 2016 English Full Episodes Free Download, Watch Passengers 2016 Online Free Viooz, Passengers 2016 HD English Full Episodes Download, Watch Passengers 2016 Online Free megashare, Passengers 2016 English Full Episodes Online Free Download, Passengers 2016 For Free Online, Passengers 2016 film trailer, watch full movie Passengers 2016, watch full Passengers 2016 film, Passengers 2016 English Episodes Free Watch Online, Passengers 2016 English Episode, Passengers 2016 Episodes Online, Passengers 2016 English Full Episodes Watch Online, Passengers 2016 For Free online, Passengers 2016 Watch Online, Passengers 2016 Full Episode, Watch Passengers 2016 Online Viooz, Passengers 2016 Episodes Watch Online,

MySql Administration: Leichtgewichtige Alternativen zu phpMyAdmin

Fast jeder der sich mal etwas ambitionierter mit PHP-Anwendungen beschäftigt hat, wird früher oder später wohl mal über phpMyAdmin gestolpert sein … DEM Administrationswerkzeug für MySql-Datenbanken für PHP. phpMyAdmin ist die eierlegende Wollmilchsau unter den Werkzeugen und dementsprechend schwergewichtig und unübersichtlich ist die Software. Für Profis jedoch sicher erste Wahl, wenn es darum geht MySql-Datenbanken zu verwalten.

Auf t3n.net gab es heute einen schönen Artikel der zwei Alternativen vorstellt, die beide nur aus jeweils einer einzigen Datei (jeweils rund 150 kb groß) bestehen: Adminer und DBKiss.

Fazit des Artikels: Da Adminer etwas schöner aussieht, deutlich mehr Funktionen bietet (unter anderem können auch Stored Procedures erstellt und bearbeitet werden) und sich außerdem über ein Plugin nahtlos in WordPress integrieren läßt, gewinnt es den Vergleich zu DBKiss recht deutlich.

Ich habe Adminer als WordPress-Plugin eben kurz ausgetestet und bin ebenfalls sehr angetan. phpMyAdmin werde ich nun vom Server löschen.

Verwendung von eindeutigen IDs in JSF2-Naming-Containern

JSF2 bietet mit dem <f:ajax>-Tag wirklich einfach zu verstehende aber trotzdem mächtige Ajax-Funktionen. Die ersten einfachen Versuche gelingen meist innerhalb weniger Minuten und man glaubt dies quasi sofort in eigenen Projekten verwenden zu können.

Mein erster Versuch Ajax in einem JSF2-Projekt für einen Kunden einzusetzen hat mir aber bei der ersten relativ komplexen Seite zumindest für ein bis zwei Stunden eine Menge Kopfzerbrechen bereitet. Dabei ist das Problem reinste Unkenntnis gewesen, weil die wenigsten Tutorials deutlich darauf hinweisen.

Aber was war überhaupt passiert?

Ich hatte eine recht komplexe JSF-Seite erstellt, die über den Facelet-Template-Mechanismus aus mehr als 10 einzelnen XHTML-Seiten gerendert wurde. Eine Datei enthielt einen Primefaces-Dialog mit einer bestimmten ID, der in einer völlig anderen XHTML manipuliert werden sollte. Genauer: nach Klick auf einen Button sollte ein Ajax-Request Daten aus der Datenbank nachladen, die danach in diesem Dialog angezeigt werden sollten.

Der Ajax-Request wurde korrekt abgesetzt, die Daten wurden geladen (über Breakpoints sichtbar) und der Dialog wurde auch geöffnet, allerdings enthielt er keine Daten. Es sah so aus, als wenn er weiter im jungfräulichen Auslieferungszustand wäre. Irgendetwas verhinderte als das neu-rendern des Dialogs.

Nach ein bis zwei Stunden rumrätseln und googeln, sind uns aber die Schuppen von den Augen gefallen und wir machten Bekanntschaft mit dem Konzept der NamingContainer.

Wenn eine JSF-Komponente das NamingContainer-Interface implementiert ist dies eine natürlich Grenze innerhalb derer Komponenten-IDs eindeutig sein müssen und auch sind. Alles was außerhalb des NamingContainers im Komponentenbaum existiert, kann dieselbe ID haben wie eine Komponente innerhalb des NamingContainers. Um trotzdem auf diese äußeren Komponenten zugreifen zu können, muss die ID “fully qualified” vom UIViewRoot aus gesehen angegeben werden. Die einzelnen NamingContainer werden dabei normalerweise durch einen Doppelpunkt getrennt. Die ID muss also in der Form “:ID:ID:ID” angegeben werden. Gestartet wird mit dem Doppelpunkt des UIViewRoot und danach jede ID einer Komponente die einen NamingContainer implementiert.

Die häufigsten Komponenten, die man so benutzt und einen eigenen NamingContainer darstellen sind <h:form>, <h:dataTable> und jede Composite Component. Bei Komponenten aus einer Komponentenbibliothek hängt es von dessen Hersteller ab, ob eine Komponente einen NamingContainer implementiert.

Ein Beispiel:

	<h:form id="form">
		<h:outputText value="Namen eingeben:" />
		<h:inputText value="#{testBean.name}" />
		<h:commandButton value="Abschicken" action="#{testBean.speichern}">
			<f:ajax render=":form:panel:name" />
		</h:commandButton>
	</h:form>
	<et:myPanel id="panel">
		<h:outputText id="name" value="Ihr Name: #{testBean.name}" />
	</et:myPanel>

Der Code zeigt ein Eingabefeld und einen Button innerhalb einer Form an und außerhalb der Form wird über eine Composite Component ein Panel gerendert, das den eingegebenen Namen anzeigen soll. Im <f:ajax>-Tag darf man nun nicht nur die ID “name” angeben, sondern die komplette ID inkl. der IDs der Form und der Composite Component, weil beide einen NamingContainer implementieren.

Übrigens lässt sich der Trenner zwischen den einzelnen IDs auch umkonfigurieren. Dazu muss man den Parameter “javax.faces.SEPARATOR_CHAR” in der web.xml entsprechend setzen.

Mehr Informationen über NamingContainer und Komponenten-IDs finden sich bei Illegal Argument Exception

Wirklich unabhängige Composite Components

Im (sehr übersichtlichen) Blog von Michael Kurz habe ich eine sehr interessante Umsetzung einer Composite Component für JSF 2.0 gefunden, die einen komponentenspezifischen Zustand/Information völlig unabhängig von der aufrufenden Seite im JSF Komponentenbaum speichern kann. Die aufrufende Seite muss somit nichts über die Internas der Composite Component wissen und für die Komponente auch keine extra definierten Attribute in einer Managed Bean zur Verfügung stellen. best places to visit . Wenn die Composite Component auf vielen verschiedenen Seiten benutzt wird, führte das meist dazu, dass ein Zustand der Composite Component in vielen verschiedenen Managed Beans gespeichert wurde.

Mit der Lösung von Michael kann eine Composite Component jedoch völlig unabhängig von der aufrufenden Seite Informationen über interne Zustände im JSF Komponentenbaum ablegen, obwohl es weiterhin eine Composite Component bleibt und deutlich schlanker erheblich unkomplizierteer als eine “full fledged” Komponente ist.

Dabei ist zusätzlich zur bekannten XHTML-Datei der Composite Component nur eine weitere Java-Klasse zu erstellen, die noch dazu sehr übersichtlich und unkompliziert ausfällt.

Als ersten Schritt muss man im Kopf der Composite Component auf eine eigene Komponentenklasse verweisen:

<cc:interface componentType="at.jsflive.CollapsiblePanel">
  <cc:attribute name="collapsed"/>
  <cc:actionSource name="toggle"/>
  <cc:facet name="header"/>
</cc:interface>

Die Implementation dieser Klasse könnte so aussehen:

@FacesComponent("at.jsflive.CollapsiblePanel")
public class CollapsiblePanel extends UINamingContainer {

  enum PropertyKeys {collapsed}

  public boolean isCollapsed() {
    return (Boolean)getStateHelper().eval(
        PropertyKeys.collapsed, Boolean.FALSE);
  }

  public void setCollapsed(boolean collapsed) {
    getStateHelper().put(PropertyKeys.collapsed, collapsed);
  }

  public void toggle(ActionEvent e) {
    setCollapsed(!isCollapsed());
  }
}

Neben der Annotation muss man sich ausschließlich um das Speichern eines Zustands und das Verändern dieses Zustands kümmern. Auf die Methoden kann man innerhalb der Composite Component über das implizite “cc”-Objekt zugreifen, diesmal aber nicht über das attrs-Attribut sondern direkt:

<cc:implementation>
    ....
    <h:commandButton id="toggle" actionListener="#{cc.toggle}"
      image="#{resource[cc.collapsed
          ? 'jsflive:plus.png' : 'jsflive:minus.png']}"/>
    ....
</cc:implementation>

That’s it.

Das ausführliches Beispiel findet ihr im oben verlinkten Blog. Michael Kurz ist übrigens einer der Autoren von Java Server Faces 2.0. Außerdem betreut er das umfangreiche JSF-Tutorial jsfatwork

Pagination mit Standard-JSF

Ich bin heute über ein Feature der datatable-Komponente im Standard-JSF gestolpert, das ich die letzten Jahre übersehen habe: Pagination. Die letzten Jahre dachte ich, dass dies ein Feature von Frameworks wie Richfaces oder Primefaces wäre oder man dies selbst per Hand entwickeln müsste. Aber nein, man kann auch mit der <h:dataTable> Komponente auf einfache Weise das seitenweise Blättern über eine Liste von Objekten implementieren.

Alles was man dazu braucht, ist die zwei Attribute first und rows korrekt zu setzen. Also ungefähr so:

<h:dataTable value="#{pricelistBean.products}" var="item" first="#{pricelistBean.first}" rows="5">
	<h:column>
		<h:outputText value="#{item.name}" />
	</h:column>
   
	<h:column>
		<h:outputText value="#{item.price}" />
	</h:column>
	<f:facet name="footer">
		<h:panelGroup>
			<h:commandButton value="Zurück" action="#{pricelistBean.zurueck}" rendered="#{pricelistBean.zurueckVisible}" />
			<h:commandButton value="Weiter" action="#{pricelistBean.weiter}" rendered="#{pricelistBean.weiterVisible}"/>
		</h:panelGroup>
	</f:facet>
</h:dataTable>

Der Code in den Methoden “weiter()” und “zurueck()” muss nur dafür sorgen, dass die Property first korrekt hoch- bzw. runtergezählt wird. Das könnte zum Beispiel so aussehen:

	public String weiter() {
		first = first + 5;
		if (first &gt; products.size()) {
			first = products.size() - 5;
		}
		return null;
	}
	
	public String zurueck() {
		first = first - 5;
		if (first &lt;= 0) {
			first = 1;
		}
		
		return null;
	}