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