You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Madhav Bhargava <Ma...@infosys.com> on 2006/12/14 15:43:58 UTC

RE: Problems while programmatically adding components - Gone wierd

Hi All,

Something really strange is happening here. The final that I had to try
was to create a custom component to render a left navigation
programmatically.

Guess what, it does not work.

Here is the method that created the <t:panelNavigation2> with child <t:
commandNavigation2> items.

private UIComponent constructLeftPanelNavigationMenu() {
	Document doc = null;
	//Parse the XML file
	ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
	InputStream xmlStream =
classLoader.getResourceAsStream("xml/UIMenuConfig.xml");
	try {
		doc = XMLParser.parse(xmlStream);
	}catch(Exception e) {
		e.printStackTrace();
	}

	FacesContext context = FacesContext.getCurrentInstance();
	Application app = context.getApplication();
	//Get the parent component
	//UIComponent parentUIComponent =
context.getViewRoot().findComponent("subnavigation");
	HtmlPanelNavigationMenu panelNavigationComponent =
(HtmlPanelNavigationMenu)app.createComponent(HtmlPanelNavigationMenu.C
OMPONENT_TYPE);
	panelNavigationComponent.setId("leftNav");
panelNavigationComponent.setLayout("list");
	//Set the CSS classes
	panelNavigationComponent.setActiveItemClass("navSelected");
	panelNavigationComponent.setOpenItemClass("navOpen");
	panelNavigationComponent.setItemClass("navNormal");
	Element rootElem = doc.getRootElement();
	List children = rootElem.getChildren();
	Iterator parentIter = children.iterator();
	while(parentIter.hasNext()) {
		HtmlCommandNavigationItem commandNavigationItem = null;
		Element node = (Element)parentIter.next();
		if ("true".equals(node.getAttributeValue("visible"))) {
			commandNavigationItem =
(HtmlCommandNavigationItem)app.createComponent(HtmlCommandNavigationItem
.COMPONENT_TYPE);

commandNavigationItem.setId(node.getAttributeValue("id"));
				MethodBinding action =
app.createMethodBinding(node.getAttributeValue("action"), null);
				commandNavigationItem.setAction(action);

//commandNavigationItem.setRendered(true);
				//Create the panel grid child
				HtmlPanelGrid panelGrid =
(HtmlPanelGrid)app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
				panelGrid.setColumns(2);
				HtmlGraphicImage image =
(HtmlGraphicImage)app.createComponent(HtmlGraphicImage.COMPONENT_TYPE);

image.setUrl(node.getAttributeValue("imgurl"));
				//image.setRendered(true);
				HtmlOutputText outputText =
(HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);

outputText.setValue(node.getAttributeValue("text"));
				//outputText.setRendered(true);
				//Add children for the panel Grid
component
				panelGrid.getChildren().add(image);
				panelGrid.getChildren().add(outputText);
				//panelGrid.setRendered(true);
			
				//Add the panel Grid component to the
commandNavigation component

commandNavigationItem.getChildren().add(panelGrid);
				addChildComponents(node,
commandNavigationItem);
			
			}

panelNavigationComponent.getChildren().add(commandNavigationItem);
		}
		return panelNavigationComponent;
	}

	/*
	 * This method will recursively construct a list of child
components of type HtmlCommandNavigationItem
	 * The component passed in as a paramter will be updated with
the child components.
	 */
	private void addChildComponents(final Element parent,
HtmlCommandNavigationItem component) {
		FacesContext context =
FacesContext.getCurrentInstance();
		Application app = context.getApplication();
		//Exit condition
		if (null == parent.getChildren()) return;
	
		List children = parent.getChildren();
		Iterator childIter = children.iterator();
		while(childIter.hasNext()) {
			Element child = (Element)childIter.next();
			if
("true".equals(child.getAttributeValue("visible"))) {
				HtmlCommandNavigationItem childComponent
=
(HtmlCommandNavigationItem)app.createComponent(HtmlCommandNavigationItem
.COMPONENT_TYPE);

childComponent.setId(child.getAttributeValue("id"));
				MethodBinding action =
app.createMethodBinding(child.getAttributeValue("action"), null);
				childComponent.setAction(action);
				HtmlOutputText outputText =
(HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);

outputText.setValue(child.getAttributeValue("text"));

childComponent.getChildren().add(outputText);
			
				//Add the child component

component.getChildren().add(childComponent);
				//recursive call
				addChildComponents(child,
childComponent);
			}
		}
	}


The <t:panelNavigation2> component gets created and gets added as a
child to the custom component.

Here is how I use it:
Below is the content of the jsp that is included in the layout.jsp (via
tiles).

<t:div id="subnavigation_outer" forceId="true">
    <t:div id="subnavigation" forceId="true">
	 <custom:leftNavigationMenu/>
    </t:div>
</t:div>

layout.jsp - the portion where it is included:

<td width="170px" valign="top" bgcolor="#F8F6F7" nowrap="nowrap">
	<f:subview id="leftnav">
		<tiles:insert attribute="leftnavigation" flush="false"/>

	</f:subview>
</td>


However if I hard code the entire menu in the leftNavigation.jsp it
works just fine.

If someone can point out the problem then It will be really appreciated.

Thanks,
madhav


> -----Original Message-----
> From: Simon Kitching [mailto:simon.kitching@rhe.co.nz]
> Sent: Thursday, December 14, 2006 11:49 AM
> To: MyFaces Discussion
> Subject: Re: Problems while programmatically adding components
>
> Madhav Bhargava wrote:
> > Hi Simon,
> >
> > You are right. But as I have mentioned i am binding the DIV
component
> > with a property in the backing bean instead of getting the
UIViewRoot
> > and then invoking findComponent.
> >
> > It does give me the proper instance of the DIV component
> >
> > I tried to add a dummy DIV component outside the outer DIV
component. In
> > the rendered property of the dummy DIV component I called the method
> > which will add children for DIV component with id="subnavigation"
which
> > is also retrieved using value binding. This will ensure that DIV
> > components are constructed before the dummy DIV component's method
is
> > invoked.
> >
> > The method gets invoked, children get added but the left menu is not
> > rendered.
> >
> > I guess I will have to create a custom component just to add
something
> > programmatically to the JSF tree. This sucks!!
>
> Maybe this page is of some use:
>    http://wiki.apache.org/myfaces/Programmatic
>
>


**************** CAUTION - Disclaimer *****************
This e-mail contains PRIVILEGED AND CONFIDENTIAL INFORMATION intended solely for the use of the addressee(s). If you are not the intended recipient, please notify the sender by e-mail and delete the original message. Further, you are not to copy, disclose, or distribute this e-mail or its contents to any other person and any such actions are unlawful. This e-mail may contain viruses. Infosys has taken every reasonable precaution to minimize this risk, but is not liable for any damage you may sustain as a result of any virus in this e-mail. You should carry out your own virus checks before opening the e-mail or attachment. Infosys reserves the right to monitor and review the content of all messages sent to or from this e-mail address. Messages sent to or from this e-mail address may be stored on the Infosys e-mail system.
***INFOSYS******** End of Disclaimer ********INFOSYS***