I am trying to put link in the error messages produced by JSF. For this I am using the custom renderer, it works(clicking the error, focuses the respective input field) but the problem is , all the form values gets empty. ie when error occurs, all the input fields get empty. Any suggestion will be appreciated.
package custom;
public class CustomErrorRenderer extends Renderer {
@Override @SuppressWarnings("unchecked")
public void encodeEnd(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeAttribute("id", component.getClientId(context), "id");
writer.writeAttribute("style", "color: red", null);
writer.startElement("ul", null);
Iterator<String> clientIds = context.getClientIdsWithMessages();
while (clientIds.hasNext()) {
String clientId = clientIds.next();
Iterator<FacesMessage> messages = context.getMessages(clientId);
if (!messages.hasNext()) { continue; }
String javaScript = "var field = document.getElementById('"
+ clientId + "');" + "if(field == null) return false;"
+ "field.focus(); return false;";
writer.startElement("li", null);
writer.startElement("a", null);
writer.writeAttribute("onclick", javaScript, null);
writer.writeAttribute("href", "#", null);
while (messages.hasNext()) {
writer.writeText(messages.next().getSummary(), null);
}
writer.endElement("a");
writer.endElement("li");
}
writer.endElement("ul");
writer.endElement("div");
}
}
This renderer is defined in faces-config.xml:
<render-kit>
<description>add to base HTML_BASIC renderkit</description>
<display-name>HTML_BASIC</display-name>
<render-kit-id>HTML_BASIC</render-kit-id>
<renderer>
<display-name>CustomErrorRenderer</display-name>
<component-family>javax.faces.Output</component-family>
<renderer-type>custom.CustomErrorRenderer</renderer-type>
<renderer-class>custom.CustomErrorRenderer</renderer-class>
</renderer>
</render-kit>
<component>
<display-name>CustomErrorMessages</display-name>
<component-type>custom.Errors</component-type>
<component-class>javax.faces.component.UIOutput</component-class>
</component>
a tag class:
package custom;
import javax.faces.webapp.UIComponentELTag;
public class CustomErrorTag extends UIComponentELTag {
@Override
public String getComponentType() {
return "custom.Errors";
}
@Override
public String getRendererType() {
return "custom.CustomErrorRenderer";
}
}
This is defined in a TLD file:
<?xml version="1.0" encoding="UTF-8"?>
<taglib 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-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>custom</short-name>
<uri>http://custom</uri>
<tag>
<name>errors</name>
<tag-class>custom.CustomErrorTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
This goes at the top of the JSP page:
<%@ taglib prefix="custom" uri="http://custom"%>
<custom:errors />