Question

I have created a custom control "ccMyLayout" added the extension Library ApplicationLayout to it. On the custom control I have created a Property Definition of type tree.complex.PageTreeNode, called it titleBarTabs allowed multiple instances of it. I have then created a and XPage called "xpDemoLayout" ans placed the "ccMyLayout" in it. In the titleBarTabs property I have created several pageTreeNodes that I now want to display in the Title Bar area of the ext. Lib. applicationLayout. I'm sure there is a way to accomplish this but I'm not sure where the code to do this would go and what it might look like. Thanks in advance.

Was it helpful?

Solution

The most ideal way to accomplish this behavior is with a "Managed Bean Node". This term is slightly misleading, because you don't necessarily have to register the Java class as a managed bean.

First, define a Java class that extends com.ibm.xsp.extlib.tree.impl.BasicNodeList. For example:

package com.timtripcony.xsp.demo;

import com.ibm.xsp.extlib.tree.impl.BasicLeafTreeNode;
import com.ibm.xsp.extlib.tree.impl.BasicNodeList;

public class DynamicFooterNodeList extends BasicNodeList {
    private static final long serialVersionUID = 1L;

    public DynamicFooterNodeList() {
        // replace the following with your own hardcoded or dynamic nodes
        String[] labels = new String[] { "LICENSE", "timtripcony.com" };
        String[] hrefs = new String[] { "http://www.apache.org/licenses/LICENSE-2.0.html", "http://timtripcony.com/" };
        for (int i = 0; i < labels.length; i++) {
            String label = labels[i];
            String href = hrefs[i];
            BasicLeafTreeNode node = new BasicLeafTreeNode();
            node.setLabel(label);
            node.setHref(href);
            addChild(node);
        }
    }
}

Next, define a custom property on your Custom Control that just accepts a String; it need not specify that it accepts multiple values, because a BasicNodeList is inherently capable of containing one or more child nodes.

Wherever you would ordinarily just explicitly define tree nodes (for example, the footerLinks property of a layout control, just add one tree node, but select "Managed Bean Node" as the type of tree node. This node type only has two properties: loaded and nodeBean; you'll want to set both.

nodeBean should have a value of #{compositeData.footerLinks}, where footerLinks is the name of the custom property you defined previously.

loaded should have a value of ${not(empty(compositeData.footerLinks))} (same caveat as before). This ensures the page won't 500 on you if the property wasn't passed to the Custom Control by its container, thereby making the property optional.

Finally, update each container (i.e. XPage) to specify the name of the class to use for that context, e.g.:

<xc:layoutWithConfigurableTreeNodes
footerLinks="com.timtripcony.xsp.demo.DynamicFooterNodeList" />

Here's where it can be a managed bean, but doesn't need to be. If you have defined a managed bean that points to an instance of the class, then instead of specifying the canonical class name as the property value, you can just give it the name of the managed bean instead. If, for instance, calculating which nodes to include will be computationally expensive, you may want to register the class as a managed bean in the application scope so the node list will only be calculated once; similarly, if the node list will be specific to each user, registering it as a bean in the session scope ensures it will be unique to each user but only calculated once per session.

The example class above only illustrates inclusion of BasicLeafTreeNode instances, but you can add any type of tree node in this fashion. Here's another example:

public class DynamicUtilityNodeList extends BasicNodeList {
    private static final long serialVersionUID = 1L;

    public DynamicUtilityNodeList() {
        addChild(new UserTreeNode());
        addChild(new LoginTreeNode());
    }
}

You mentioned that you're defining page tree nodes, so you might end up with code that looks akin to the following:

PageTreeNode node = new PageTreeNode();
node.setLabel("Some Page");
node.setPage("/somePage.xsp");
addChild(node);

...and you can even define entire node hierarchies in this fashion. This article from Jesse Gallagher demonstrates how you can use this same core technique to construct a tree node hierarchy that maps to the design of an Outline element. You could also base it on NSF data, JDBC, REST, SOAP... the sky's the limit here.

For convenience, you can see the concepts described above in action here and also download the salient XML and Java example files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top