Die Lösung, die ich fand, war, die encodeMarkup-Methoden für die Eingabe-Renderer zu erweitern und neu zu implementieren. Ich wollte eine allgemeinere Lösung, aber nachdem ich den Primefaces-Quellcode angeschaut hatte, sah ich keine generischen Hooks, damit die Komponenten-Renderer benutzerdefinierte Attribute hinzufügen konnten. Das Markup ist in den encodeMarkup(FacesContext context, InputText inputText)
Methoden der Renderer ausgeschrieben. Es ruft die Klassenhierarchie zu renderPassThruAttributes(FacesContext context, UIComponent component, String[] attributes)
auf aber es speist nur statische endgültige String [] - Arrays von org.primefaces.util.HTML
.
In meinem Fall wollte ich Unterstützung für das 'Autofokus' Attribut auf InputMask, InputText, InputTextarea und Passwort-Komponenten. Darüber hinaus ist die Implementierung für jede Komponente die gleiche, daher werde ich den Autofokus der InputText-Komponente implementieren, aber es sollte offensichtlich sein, wie er erweitert werden kann, um mehr Attribute und mehr Komponenten zu unterstützen.
Um einen Renderer zu erweitern/zu überschreiben, müssen Sie die Primefaces-Quelle verfügbar haben und die encodeMarkup-Methode suchen und deren Inhalt kopieren. Hier ist das Beispiel für InputTextRenderer:
protected void encodeMarkup(FacesContext context, InputText inputText) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = inputText.getClientId(context);
writer.startElement("input", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("name", clientId, null);
writer.writeAttribute("type", inputText.getType(), null);
String valueToRender = ComponentUtils.getValueToRender(context, inputText);
if(valueToRender != null) {
writer.writeAttribute("value", valueToRender , null);
}
renderPassThruAttributes(context, inputText, HTML.INPUT_TEXT_ATTRS);
if(inputText.isDisabled()) writer.writeAttribute("disabled", "disabled", null);
if(inputText.isReadonly()) writer.writeAttribute("readonly", "readonly", null);
if(inputText.getStyle() != null) writer.writeAttribute("style", inputText.getStyle(), null);
writer.writeAttribute("class", createStyleClass(inputText), "styleClass");
writer.endElement("input");
}
Erweiterung/Aufschalten den Renderer mit Ihrem eigenen (siehe Kommentare zu wichtigen Code):
public class HTML5InputTextRenderer extends InputTextRenderer {
Logger log = Logger.getLogger(HTML5InputTextRenderer.class);
//Define your attributes to support here
private static final String[] html5_attributes = { "autofocus" };
protected void encodeMarkup(FacesContext context, InputText inputText) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = inputText.getClientId(context);
writer.startElement("input", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("name", clientId, null);
writer.writeAttribute("type", inputText.getType(), null);
String valueToRender = ComponentUtils.getValueToRender(context, inputText);
if (valueToRender != null) {
writer.writeAttribute("value", valueToRender, null);
}
renderPassThruAttributes(context, inputText, HTML.INPUT_TEXT_ATTRS);
//Make an extra call to renderPassThruAttributes with your own attributes array
renderPassThruAttributes(context, inputText, html5_attributes);
if (inputText.isDisabled())
writer.writeAttribute("disabled", "disabled", null);
if (inputText.isReadonly())
writer.writeAttribute("readonly", "readonly", null);
if (inputText.getStyle() != null)
writer.writeAttribute("style", inputText.getStyle(), null);
writer.writeAttribute("class", createStyleClass(inputText), "styleClass");
writer.endElement("input");
}
}
Konfigurieren der Rendering Überschreibung in faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<!-- snip... -->
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.InputTextRenderer</renderer-type>
<renderer-class>com.mycompany.HTML5InputTextRenderer</renderer-class>
</renderer>
</render-kit>
<!-- snip... -->
</faces-config>
und Just-in-Case, wenn Sie die faces-config in Ihrer web.xml nicht konfiguriert haben. Add:
Dann ist diese in einem gewissen Markup zu verwenden:
<p:inputText id="activateUserName" value="${someBean.userName}"
autofocus="on">
</p:inputText>
Hinweis: JSF mit Attributen nicht glücklich ist, die Werte nicht haben. Während der Autofokus in HTML5 keinen Wert verwendet, gibt JSF einen Fehler aus, wenn einer nicht angegeben wird. Stellen Sie daher sicher, dass Sie einen Wegwerfwert definieren, wenn Sie solche Attribute hinzufügen.
Großartig, das sieht viel schöner aus als die pro-Komponenten-Lösung. Ich bin sicher, dass bestimmte Anwendungsfälle Argumente liefern könnten. Wenn ich Zeit bekomme, probiere ich das aus, da es viel schneller ist, als alle Komponenten zu entwickeln. – Rich
Die UIComponent # getCurrentComponent (FacesContext) scheint die Signatur zu sein, also im Kontext der startElement-Methode, die nicht verfügbar ist. Ich habe in Ihrem Omnifaces-Commit gesehen, dass Sie Components.getCurrentCompnent() verwendet haben, das den Kontext nicht benötigt, obwohl das eine OmniFaces-Klasse ist, die nicht nur in PrimeFaces verfügbar ist. An diesem Punkt wäre es gefährlicher für mich, auch jede Komponente zu überschreiben, die Null an startElement übergeben könnte. Schlägst du vor, ich ziehe OmniFaces ein oder gibt es einen anderen Weg? – Rich
Das Formular 'Components # getCurrentComponent()' OmniFaces delegiert nur an 'UIComponent # getCurrentComponent()'. Du bist nicht klar, ob du es getestet hast oder nicht, aber es funktioniert für mich. – BalusC