views:

136

answers:

0

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&lt;/uri&gt;
  <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"%&gt;
<custom:errors />