Victor Bello
Victor Bello

Reputation: 493

Override Primefaces Renderer

I'm developing a dynamic menu using Primefaces and JSF 2.2.

The problem is that it's not inserting the menu id. Looking primefaces' code it hits a code that will always be false:

BaseMenuRenderer:

protected boolean shouldRenderId(MenuElement element) {
    if(element instanceof UIComponent)
        return shouldWriteId((UIComponent) element);
    else
        return false;
}

TieredMenuRenderer:

 writer.startElement("li", null);
                    if(shouldRenderId(submenu)) {
                        writer.writeAttribute("id", submenu.getClientId(), null);
                    }

So, I decided to override primefaces' TieredMenuRenderer, but my override constructor classe is called but the override method is never called.

Here's how I set my facesconfig.xml

<render-kit>
        <renderer>
            <component-family>org.primefaces.component</component-family>
            <renderer-type>org.primefaces.component.TieredMenuRenderer</renderer-type>
            <renderer-class>ui.jsf.TieredMenuRenderer</renderer-class>
        </renderer>
    </render-kit>

My override class:

    public class TieredMenuRenderer extends org.primefaces.component.tieredmenu.TieredMenuRenderer {
  @Override
    protected void encodeElements(FacesContext context, AbstractMenu menu, List<MenuElement> elements) throws IOException {
        System.out.println("----------- TEST --------------");
        super.encodeElements(context, menu, elements);
    }

Sysout is never print.

Does anyone know what i'm doing wrong?

Thanks!

Edit:

Add ID to DefaultMenuItem:

  DefaultMenuItem item = new DefaultMenuItem();
  item.setId(menuItem.getMenuId());// just return a string value.

Adding menu xhtml, the "menucontroller.model" is a primefaces MenuModel which I use a DefaultMenuModel :

Iterating over renderer kit, When I execute the following command, returns the correct renderer-type org.primefaces.component.TieredMenuRenderer

Iterator<String> renderKit = kit.getRendererTypes("org.primefaces.component");

When I execute the following code returns my qualified classname ui.jsf.TieredMenuRenderer@64baec0e:

Renderer renderer = kit.getRenderer("org.primefaces.component", "org.primefaces.component.TieredMenuRenderer");

Upvotes: 2

Views: 2708

Answers (1)

Victor Bello
Victor Bello

Reputation: 493

First of all, My renderer was not overriding the correct renderer. I was overriding org.primefaces.component.tieredmenu.TieredMenuRenderer when I should override org.primefaces.component.MenubarRenderer.

Then, to correct the primefaces id problem I did the following in my rendered class:

 @Override
    protected boolean shouldRenderId(MenuElement element) {
        return true;
    }

@Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        AbstractMenu menu = (AbstractMenu) component;
        encodeMarkup(context, menu);
        encodeScript(context, menu);
    }

EncodedEnd was calling "generateIds()" from primefaces which override my ids.

Full rendered class:

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.primefaces.component.menu.AbstractMenu;
import org.primefaces.model.menu.MenuElement;

public class MenuRenderer extends org.primefaces.component.menubar.MenubarRenderer {

    @Override
    protected boolean shouldRenderId(MenuElement element) {
        return true;
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        AbstractMenu menu = (AbstractMenu) component;
        encodeMarkup(context, menu);
        encodeScript(context, menu);
    }

}

Upvotes: 2

Related Questions