Page 1 of 2

MenuItem in BreadCrumb can not have children

Posted: 20 Jan 2010, 15:49
by Oleg
Hello Cagatay,

I have faced a small bug. You said recently p:menuitem in p:menubar can have p:commandLink inside. Well, it works. Now I use p:menuitem in p:breadCrumb. But in this case we can not put p:commandLink as child component of p:menuitem. :-( For me p:menuitem either be able or not be able to contain children components (like p:commandLink) - independent of its parent component (which it's included in).

I have looked into the source code. MenuItem doesn't have own renderer. In MenubarRenderer you do

Code: Select all

	private void encodeMenuItem(FacesContext facesContext, MenuItem menuItem) throws IOException {
		ResponseWriter writer = facesContext.getResponseWriter();

		if(menuItem.getChildCount() > 0) {
			renderChildren(facesContext, menuItem);   // !!!!! RIGHT !!!!!
		}
		else {
			String menuitemStyleClass = .....;

			writer.startElement("a", null);
			writer.writeAttribute("class", menuitemStyleClass, null);
			writer.writeAttribute("href", menuItem.getUrl(), null);

			if(menuItem.getStyle() != null)  writer.writeAttribute("style", menuItem.getStyle(), null);
			if(menuItem.getTarget() != null)  writer.writeAttribute("target", menuItem.getTarget(), null);
			if(menuItem.getOnclick() != null) writer.writeAttribute("onclick", menuItem.getOnclick(), null);
			if(menuItem.getLabel() != null) writer.write(menuItem.getLabel());

			if(menuItem.getHelpText() != null) {
				writer.startElement("em", null);
				writer.writeAttribute("class", "helptext", null);
				writer.write(menuItem.getHelpText());
				writer.endElement("em");
			}

			writer.endElement("a");
		}
	}
Quite correct. But in BreadCrumbRenderer you let render MenuItem direct without check its children

Code: Select all

		for (Iterator<UIComponent> iterator = breadCrumb.getChildren().iterator(); iterator.hasNext();) {
			UIComponent child = iterator.next();

			if(child.isRendered() && child instanceof MenuItem) {
				MenuItem menuItem = (MenuItem) child;

				writer.startElement("li", null);

				writer.startElement("a", null);
				writer.writeAttribute("href", menuItem.getUrl(), null);

				if(menuItem.getTarget() != null) writer.writeAttribute("target", menuItem.getTarget(), null);
				if(menuItem.getOnclick() != null) writer.writeAttribute("onclick", menuItem.getOnclick(), null);
				if(menuItem.getLabel() != null) writer.write(menuItem.getLabel());

				writer.endElement("a");

				writer.endElement("li");
			}
		}
Can you fix this small bug please ? That is very important for us. Shall I register it in issue tracker?

Thanks in advance!
Oleg.

Re: MenuItem in BreadCrumb can not have children

Posted: 20 Jan 2010, 16:57
by Oleg
Actually, with

Code: Select all

      if(menuItem.getChildCount() > 0) {
         renderChildren(facesContext, menuItem);
      }
we could use ui:repeat to build menuitems dynamically like this one

Code: Select all

<p:breadCrumb>
 <ui:repeat value="#{breadCrumb.items}" var="item">
	<p:menuitem>
		<p:commandLink value="#{item.label}" async="true" process="@this" update="rightColumnContent" action="....."/>
	</p:menuitem>
 </ui:repeat>
</p:breadCrumb>

Re: MenuItem in BreadCrumb can not have children

Posted: 20 Jan 2010, 18:37
by cagatay.civici
Yes, breadcrumb does not support that at the moment, sounds like a good candidate for a future enhancement.

Also menuitem has no renderer, how can ui:repeat will work?

Re: MenuItem in BreadCrumb can not have children

Posted: 21 Jan 2010, 00:27
by Oleg
cagatay.civici wrote:Yes, breadcrumb does not support that at the moment, sounds like a good candidate for a future enhancement.

Also menuitem has no renderer, how can ui:repeat will work?
I have checked it. Yes, ui:repeat doesn't work. It's a component which calls encodeAll() for its children and it doesn't have any effect for p:menuitem. The solution could work with c:forEach because it's not a component and just builds component tree. All available menuitems will be added with c:forEach to the component tree. As result we must possibly manage "rendered" attribute for every p:menuitem during walking forwards / backwards along breadcrumb if not all menuitems need to be displayed.

Re: MenuItem in BreadCrumb can not have children

Posted: 21 Jan 2010, 12:15
by Oleg
Cagatay, can you add please

Code: Select all

      if(menuItem.getChildCount() > 0) {
         renderChildren(facesContext, menuItem);
      }
to the BreadCrumbRenderer in the 2.0.0-SNAPSHOT version? It's not much, but power and very flexible. We could so e.g. disable some breadcrumb entries by means of placing h:outputText instead of h:commandLink below p:menuitem. At the moment I'm wondering how I can disable some menuitems (render as grey text and not as link).

Re: MenuItem in BreadCrumb can not have children

Posted: 22 Jan 2010, 13:17
by cagatay.civici
As I'm terribly busy with other stuff, I don't think I can work on this at the moment but if you can provide a patch I can apply it.

Also for disabled, it would be better to add a generic disabled attribute to menuitem instead of placing outputTexts.

Re: MenuItem in BreadCrumb can not have children

Posted: 22 Jan 2010, 14:43
by Oleg
Hello Cagatay,

How must I delivery the patch - as SVN patch or as updated entire Java class(es)?

I have tried to check-out primefaces svn checkout http://primefaces.googlecode.com/svn/core2/trunk/ primefaces-read-only. Very strange, but I miss some packages and classes availbale in source JAR from download. The package "menuitem" under "component" is not available at all :-) Do you know why?

Best regards.
Oleg.

Re: MenuItem in BreadCrumb can not have children

Posted: 22 Jan 2010, 15:03
by cagatay.civici
Hi Oleg,

An svn patch file would be great, we generate most of the boilerplate code so you need to run mvn install once to generate those stuff. Which ide do you have?

Re: MenuItem in BreadCrumb can not have children

Posted: 22 Jan 2010, 15:59
by Oleg
I use Eclipse 3.5 (Java EE Bundle).

I will try to follow this recommendation http://code.google.com/p/primefaces/wik ... FromSource. Did I right understand that you describe your components declarative (xml?) and your maven jsf plugin generate all nessesary stuff except for Renderer classes? Wonderful, it pleases me :-)

- Oleg.

Re: MenuItem in BreadCrumb can not have children

Posted: 23 Jan 2010, 12:50
by Oleg
Ok, I have found. Descriptions are under ...\primefaces\src\main\resources-maven-jsf\ui\*.xml

Cagatay, which Java code formatter do you use? I can apply either Jaloppy or Eclipse built in formatter so that we will have changes just by those lines which have been really changed. Maybe you can export your formatter settings and send me for importing into my Eclipse.

The other question is how I can deliver my changes? Per E-mail?

Best regards.
Oleg.