Problems with custom component in jsf 2
rart3001_1 Apr 25, 2013 4:53 PMRegards,
I created a component to paint a menu, the component uses HtmlCommandLink to call navigation rules. The problem is that the component is displayed correctly, but when I click on a link does not redirect to the desired page.
The code of the component is:
import java.io.IOException;
import java.text.Normalizer;
import java.util.List;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.faces.application.Application;
import javax.faces.component.FacesComponent;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponentBase;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.jboss.logging.Logger;
import com.oficcomtechnology.model.Menu;
/**
* @author rrequena
*
*/
@FacesComponent(value = "HtmlMenu")
public class HtmlMenu extends UIComponentBase implements StateHolder {
private transient Logger LOG = Logger.getLogger(HtmlMenu.class);
public static final String COMPONENT_TYPE = "oficcom.custom.component";
public static final String COMPONENT_FAMILY = "oficcom.custom.component";
private FacesContext context;
private Application application;
private ExpressionFactory expressionFactory;
private String menuSeleccionado;
public HtmlMenu() {
this.context = FacesContext.getCurrentInstance();
this.application = context.getApplication();
this.expressionFactory = application.getExpressionFactory();
setParent(findComponent("formMenu"));
setRendererType(COMPONENT_TYPE);
}
/* (non-Javadoc)
* @see javax.faces.component.UIComponent#getFamily()
*/
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
/* (non-Javadoc)
* @see javax.faces.component.UIComponentBase#getRendererType()
*/
@Override
public String getRendererType() {
return COMPONENT_TYPE;
}
/* (non-Javadoc)
* @see javax.faces.component.UIComponent#encodeAll(javax.faces.context.FacesContext)
*/
@Override
public void encodeAll(FacesContext context) throws IOException {
final ResponseWriter writer = context.getResponseWriter();
writer.startElement("ul", this);
writer.writeAttribute("class", "big-menu", null);
if (getValores() != null && getValores().size() > 0) {
for (Menu menu : getValores()) {
if (menu.getMenuVisible()) {
if (menu.getMenues() != null && menu.getMenues().size() > 0) {
encodeLiTagWithUl(menu, writer);
}else{
encodeLiTag(menu, writer);
}
}
}
}
writer.endElement("ul");
}
/**
* Crea un elemento <li> para el menu hijo.
*
* @param menu
* @param writer
*/
private void encodeLiTagWithUl(Menu menu, ResponseWriter writer){
try {
//<li class="with-right-arrow">
writer.startElement("li", this);
writer.writeAttribute("class", "with-right-arrow", null);
//<span><span class="list-count">5</span>Administracion</span>
writer.startElement("span", this);
writer.startElement("span", this);
writer.writeAttribute("class", "list-count", null);
writer.writeText(menu.getMenues().size(), null);
writer.endElement("span");
writer.writeText(menu.getNombre(), null);
writer.endElement("span");
//<ul class="big-menu">
writer.startElement("ul", this);
writer.writeAttribute("class", "big-menu", null);
//Creamos los hijos
for (Menu menuHijo : menu.getMenues()) {
if (menuHijo.getMenuVisible()) {
if (menuHijo.getMenues() != null && menuHijo.getMenues().size() > 0) {
encodeLiTagWithUl(menuHijo, writer);
}else{
encodeLiTag(menuHijo, writer);
}
}
}
writer.endElement("ul");
writer.endElement("li");
} catch (IOException e) {
LOG.error(e);
}
}
/**
* Crea un elemento <li> para el menu hijo.
*
* @param menu
* @param writer
*/
private void encodeLiTag(Menu menu, ResponseWriter writer){
//Creamos el id
String id = (removerAcentos(menu.getNombre()).replaceAll("\\s","")) + "Id";
MethodExpression me = expressionFactory.createMethodExpression(context.getELContext(), menu.getUrl(), String.class, new Class<?>[] {});
//<li><h:commandLink action="lista_configuraciones" >Configuraciones</h:commandLink></li>
try {
writer.startElement("li", this);
HtmlCommandLink link = (HtmlCommandLink) application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
link.setId(id);
link.setParent(this);
link.setActionExpression(me);
link.setValue(menu.getNombre());
link.encodeAll(context);
writer.endElement("li");
} catch (IOException e) {
LOG.error(e);
}
}
/**
* Metodo encargado de remover acentos
* @param s
* @return
*/
private String removerAcentos(String s) {
s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
return s;
}
/**
* @return the valores
*/
@SuppressWarnings("unchecked")
public List<Menu> getValores() {
return (List<Menu>) getStateHelper().eval("valores");
}
/**
* @param valores the valores to set
*/
public void setValores(List<Menu> menus) {
getStateHelper().put("valores", menus);
}
/**
* @return the menuSeleccionado
*/
public String getMenuSeleccionado() {
return menuSeleccionado;
}
/**
* @param menuSeleccionado the menuSeleccionado to set
*/
public void setMenuSeleccionado(String menuSeleccionado) {
this.menuSeleccionado = menuSeleccionado;
}
I can observe on the console after clicking on a link is the following:
16:27:04,584 INFO [stdout] (http-localhost-127.0.0.1-7777-4) Unable to find state for component with clientId 'formMenu:ConfiguracionesId', not restoring it.
if anyone can help me, thanks