将自定义属性(HTML5)支持添加到JSF 2.0 UIInput组件

我正在尝试编写一个将处理<h:inputText>组件上的placeholder属性的呈示器。 在阅读JSF 2.0去掉所需的HTML5属性之后,我走向了这条道路,看起来是正确的。 这是我的自定义渲染器

 public class InputRenderer extends com.sun.faces.renderkit.html_basic.TextRenderer{ @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { System.out.println("Rendering :"+component.getClientId()); String placeholder = (String)component.getAttributes().get("placeholder"); if(placeholder != null) { ResponseWriter writer = context.getResponseWriter(); writer.writeAttribute("placeholder", placeholder, "placeholder"); } super.encodeBegin(context, component); } @Override public void decode(FacesContext context, UIComponent component) { super.decode(context, component); } @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { super.encodeEnd(context, component); } } 

而这个渲染器在faces config中注册为

  <render-kit> <renderer> <component-family>javax.faces.Input</component-family> <renderer-type>javax.faces.Text</renderer-type> <renderer-class>com.example.renderer.InputRenderer</renderer-class> </renderer> </render-kit> 

这得到了很好的logging,没有问题。

我的意图是处理placeholder属性,插入它,然后委托处理超。 我上面的代码不起作用,因为我在错误的地方插入属性。 它必须在writer.startElement('input')执行后插入。 但是,startElement必须发生在super的encodeBegin()方法的某处。 那么如何插入一个自定义属性(在这种情况下是“占位符”),然后继续执行stream程?

注意:上面的代码确实添加了一个placeholder属性,但没有添加到我打算的input组件中,它将它写入到input的父级(因为我试图在组件本身实际写入stream之前编写属性,它将该属性应用于当前组件)

这是我的方式。 我添加了占位符和数据主题属性。 如果你想添加更多的属性,你应该只是将其名称添加到属性数组。

 import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import com.sun.faces.renderkit.html_basic.TextRenderer; public class InputRender extends TextRenderer { @Override protected void getEndTextToRender(FacesContext context, UIComponent component, String currentValue) throws java.io.IOException{ String [] attributes = {"placeholder","data-theme"}; ResponseWriter writer = context.getResponseWriter(); for(String attribute : attributes) { String value = (String)component.getAttributes().get(attribute); if(value != null) { writer.writeAttribute(attribute, value, attribute); } } super.getEndTextToRender(context, component, currentValue); } } 

你应该把这个添加到faces-config.xml文件中。

  <render-kit> <renderer> <component-family>javax.faces.Input</component-family> <renderer-type>javax.faces.Text</renderer-type> <renderer-class>your.package.InputRenderer</renderer-class> </renderer> </render-kit> 

你可以重写ResponseWriters的startElement方法,该方法只被调用一次,然后你可以恢复到原来的responsewriter对象。

 import javax.faces.context.*; import java.io.IOException; public class InputRenderer extends com.sun.faces.renderkit.html_basic.TextRenderer{ // Put all of the attributes you want to render here... private static final String[] ATTRIBUTES = {"required","placeholder"}; @Override protected void getEndTextToRender(FacesContext context, UIComponent component, String currentValue) throws IOException { final ResponseWriter originalResponseWriter = context.getResponseWriter(); context.setResponseWriter(new ResponseWriterWrapper() { @Override // As of JSF 1.2 this method is now public. public ResponseWriter getWrapped() { return originalResponseWriter; } @Override public void startElement(String name, UIComponent component) throws IOException { super.startElement(name, component); if ("input".equals(name)) { for (String attribute : ATTRIBUTES) { Object value = component.getAttributes().get(attribute); if (value != null) { super.writeAttribute(attribute,value,attribute); } } } }); super.getEndTextToRender(context, component, currentValue); context.setResponseWriter(originalResponseWriter); // Restore original writer. } } 

并覆盖MyFaces 2.0.8+

 package com.hsop.abc.eld; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.apache.myfaces.renderkit.html.HtmlTextRenderer; public class InputRenderer extends HtmlTextRenderer { @Override protected void renderInputBegin(FacesContext context, UIComponent component) throws IOException { // TODO Auto-generated method stub super.renderInputBegin(context, component); Object placeholder = component.getAttributes().get("placeholder"); if(placeholder != null) { ResponseWriter writer = context.getResponseWriter(); writer.writeAttribute("placeholder", placeholder, "placeholder"); } } }