webtier@glassfish.java.net

JSF 2.0.3 - Problems adding composite components dynamically.

From: <webtier_at_javadesktop.org>
Date: Wed, 03 Feb 2010 08:11:14 PST

Hi All,

I've been playing with the idea of creating input forms dynamically, using an XML definition file with a managed bean to read the XML and construct an arbitrary page.


Have read the article on 'dynamically creating composite components' and tried to implement the ideas there, but there appears to be a problem when applying the UIComponent (and children) to the Facelet.


Here's the code in the managed bean :


                FacesContext ctx = FacesContext.getCurrentInstance();
                Application application = ctx.getApplication();
                UIComponent parent = ctx.getViewRoot().findComponent(FORM_COMPONENT );
                //ELContext elctx = ctx.getELContext();
                //ExpressionFactory exprFactory = application.getExpressionFactory();

                List children = parent.getChildren();
        
                //Create test composite component here.
                Resource myccres = application.getResourceHandler().createResource(
                                "addresslookup.xhtml", "addresslookup");

                UIComponent testcc = application.createComponent(ctx, myccres);

                UIComponent compositeRoot = application
                                .createComponent(UIForm.COMPONENT_TYPE);
                testcc.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, myccres);
                compositeRoot.setRendererType("javax.faces.Group");
                

                try {
                        FaceletFactory factory = (FaceletFactory) RequestStateManager.get(
                                        ctx, RequestStateManager.FACELET_FACTORY);
                        Facelet f = factory.getFacelet(myccres.getURL());
                        f.apply(ctx, compositeRoot);
                        
                } catch (Exception e) {
                        System.err.println("**ERROR** Exception was :"+e.getMessage());
                        
                         
                }

                children.add(compositeRoot);


Here's the composite component XHTML :

<composite:implementation>
        <h:outputScript name="javascript/jsf.js" target="head"/>
    <h:outputScript name="addresslookup/addresslookup.js" target="head"/>
    
          <!-- Input control, label, status and helpicon -->
    <h:outputLabel for="unresolvedpostcode">
                <h:outputText id="postcodelabel" value="Postcode :"/>
        </h:outputLabel>
    <h:inputText id="unresolvedpostcode" value="#{postcodeBean.postcode}" >
            <f:ajax event="valueChange" render="addressesselection"/>
    </h:inputText>
    
  <!-- <hi:helpicon id="help_busy" for="unresolvedpostcode" outputTo="#{cc.attrs.infoComponent}"/> -->
    
    <!-- Output fields -->
    <!-- Multiline selector -->
    <br/>
    <h:outputLabel for="addressselectionpanel" rendered="#{postcodeBean.addressesAvailable}">
                <h:outputText id="addressselectionlabel" value="Matching addresses :"/>
        </h:outputLabel>
    <h:panelGroup id="addressselectionpanel" layout="block">
    <h:selectOneListbox id="addressesselection" value="#{postcodeBean.selectedAddress}">
            <f:selectItems value="#{postcodeBean.addressList}" />
            <f:ajax render="selectedaddress"/>
    </h:selectOneListbox>
    
    </h:panelGroup>
    
    <!-- Final selection textarea -->
    <h:outputText id="selectedaddress" value="#{postcodeBean.selectedAddress}"/>
    <!-- rendered="#{postcodeBean.addressSelected}" -->
</composite:implementation>

...and here's the page XHTML skeleton I'm trying to add the components to :
<h:head>
<title>Dynamic page test</title>
<meta http-equiv="Content-Type"
        content="application/xhtml+xml; charset=ISO-8859-1" />
<meta name="GENERATOR" content="Rational Software Architect" />
</h:head>
<body>
<h:form id="dynaform1">
        <h:outputScript name="javascript/jsf.js" target="head"/>
        <h:commandButton id="nothere" rendered="#{dynaPageBean.buildPage}" style="display:none"/>
</h:form>
</body>

Every time I invoke the page, the following exception gets caught when calling Facelet.apply(...) :

'/resources/addresslookup/addresslookup.xhtml @19,66 <composite:interface> Component Not Found for identifier: j_id2.getParent().'

No doubt Im being a halfwit in some sort of way. Anyone got a de-stupidifying stick that they could use on me?


PS Strange jsf.js import above is due to difficulties getting WAS 6.1 to find the resource using the normal technique. I fear I'm playing with fire even attempting to get mojarra and WAS libraries co-existing, however all the example projects work ok with the outputscript hack used above.
[Message sent by forum member 'jimmystrugglingfaces' (james.ayling_at_directline.com)]

http://forums.java.net/jive/thread.jspa?messageID=384548