但对我来说最好的解决方案是支持自动对焦(以及我可能希望在我的应用程序中支持的任何其他可能类型的属性,这些属性尚未定义).
我见过Adding custom attribute (HTML5) support to JSF 2.0 UIInput component,但这似乎适用于基本的JSF组件,并不适用于PrimeFaces组件.
解决方法
RenderKit
而不是为每个单个组件自定义渲染器,其中您提供自定义
ResponseWriter
,其中重写
startElement()
方法以检查元素名称和/或组件实例,然后相应地编写其他属性.
这是HTML5渲染工具包的启动示例:
public class Html5RenderKit extends RenderKitWrapper { private RenderKit wrapped; public Html5RenderKit(RenderKit wrapped) { this.wrapped = wrapped; } @Override public ResponseWriter createResponseWriter(Writer writer,String contentTypeList,String characterEncoding) { return new Html5ResponseWriter(super.createResponseWriter(writer,contentTypeList,characterEncoding)); } @Override public RenderKit getWrapped() { return wrapped; } }
HTML5响应编写器:
public class Html5ResponseWriter extends ResponseWriterWrapper { private static final String[] HTML5_INPUT_ATTRIBUTES = { "autofocus" }; private ResponseWriter wrapped; public Html5ResponseWriter(ResponseWriter wrapped) { this.wrapped = wrapped; } @Override public ResponseWriter cloneWithWriter(Writer writer) { return new Html5ResponseWriter(super.cloneWithWriter(writer)); } @Override public void startElement(String name,UIComponent component) throws IOException { super.startElement(name,component); if ("input".equals(name)) { for (String attributeName : HTML5_INPUT_ATTRIBUTES) { String attributeValue = component.getAttributes().get(attributeName); if (attributeValue != null) { super.writeAttribute(attributeName,attributeValue,null); } } } } @Override public ResponseWriter getWrapped() { return wrapped; } }
要使其运行,请创建此HTML5渲染工具包工厂:
public class Html5RenderKitFactory extends RenderKitFactory { private RenderKitFactory wrapped; public Html5RenderKitFactory(RenderKitFactory wrapped) { this.wrapped = wrapped; } @Override public void addRenderKit(String renderKitId,RenderKit renderKit) { wrapped.addRenderKit(renderKitId,renderKit); } @Override public RenderKit getRenderKit(FacesContext context,String renderKitId) { RenderKit renderKit = wrapped.getRenderKit(context,renderKitId); return (HTML_BASIC_RENDER_KIT.equals(renderKitId)) ? new Html5RenderKit(renderKit) : renderKit; } @Override public Iterator<String> getRenderKitIds() { return wrapped.getRenderKitIds(); } }
并在faces-config.xml中将其注册如下:
<factory> <render-kit-factory>com.example.Html5RenderKitFactory</render-kit-factory> </factory>
JSF实用程序库OmniFaces也有这样的渲染工具包,Html5RenderKit(source code here)理论上也应该在PrimeFaces组件上正常工作.然而,这个问题迫使我再次重新审视,我很尴尬地看到ResponseWriter#startElement()中的组件参数在< p:inputText>中为null. (参见line 74 of InputTextRenderer
,它应该是writer.startElement(“input”,inputText)).我不确定这是有意还是对PrimeFaces渲染器的设计进行疏忽,但你可以使用UIComponent#getCurrentComponent()来获取它.
更新:OmniFaces 1.5中已修复此问题.
值得注意的是,即将推出的JSF 2.2将支持通过新的passthrough命名空间或< f:passThroughAttribute>在视图中定义自定义属性.标签.另见What’s new in JSF 2.2? – HTML5 Pass-through attributes.
因此,所以:
<html ... xmlns:p="http://java.sun.com/jsf/passthrough"> ... <h:inputText ... p:autofocus="true" />
(您可能希望使用而不是p作为名称空间前缀来避免与PrimeFaces的默认名称空间冲突)
要么:
<h:inputText ...> <f:passThroughAttribute name="autofocus" value="true" /> </h:inputText>