Nik*_*hil 11 html jsf html5 jsf-2 mojarra
我正在尝试编写一个渲染器来处理组件placeholder
上的属性<h:inputText>
.在阅读了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);
}
}
Run Code Online (Sandbox Code Playgroud)
此渲染器在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>
Run Code Online (Sandbox Code Playgroud)
这个注册很好,没有问题.
我的目的是处理placeholder
属性,插入它,然后将处理委托给super.我上面的代码不起作用,因为我将属性插入错误的地方.它必须在writer.startElement('input')
执行后插入.但是,startElement必须在super的encodeBegin()
方法中的某个地方发生.那么如何插入自定义属性(在这种情况下为"占位符")然后继续执行流程?
注意:上面的代码确实添加了一个placeholder
属性,但没有添加到我想要的输入组件,它将它写入Input的父级(因为我试图在组件本身实际写入流之前编写一个属性,它将属性应用于当前组件)
小智 19
这是我的方式.我添加了占位符和数据主题属性.如果要添加更多属性,只需将其名称添加到attributes数组即可.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
您应该将此添加到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>
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以只覆盖ResponseWriters startElement方法,该方法只调用一次,然后您可以还原到原始的响应编写器对象.
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.
}
}
Run Code Online (Sandbox Code Playgroud)