tags:

views:

55

answers:

1

I am interested in creating a dynamic component in JSF. By that I mean a component that looks and acts differently dependent on the variables it is passed.

Let's take an easy example that actually works. A composite component (facelet) that hides/shows different parts of itself dependent on the data. In this case, it takes an attribute named "myBean", which you may imagine having a "value" field and "type" field. The "type" field determines what component should be rendered.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:cc="http://java.sun.com/jsf/composite"&gt;

    <cc:interface>
        <cc:attribute name="myBean" />
    </cc:interface>

    <cc:implementation>

        <!-- Small input field if type is "shorttext"  -->
        <h:inputText value="#{myBean.value}" rendered="#{myBean.type == 'shorttext'}" />

        <!-- Text area input field if type is "longtext"  -->
        <h:inputTextArea value="#{myBean.value}" rendered="#{myBean.type == 'longtext'}" />

    </cc:implementation>
</html>

While this works, it quickly becomes unwieldy. If I have twenty different types, I have them all specified in the same document and that clearly violates good design.

Instead, I would like to be able to replace the implementation with something like:

    <ui:include value="#{myBean.type}"/>

Which I understand is not possible, since ui:include occurs when building the component tree, and the the component is processed during the rendering phase.

Yet this must be a common problem. What is the best approach to achieve dynamic components? I am using JSF 2.0, if that makes a difference.

+1  A: 

I don't see better ways. XML is not an OO language. This is the best what you can get with XML. If you want to do it the OO way, then you should create a real component with a renderer.

By the way, composite components was introduced in JSF 2.0 and are thus not available in JSF 1.x. So it doesn't make much difference ;)

BalusC
You know, I am coming to the same conclusion myself. It seems there might even be a benefit to this approach over dynamically modifying the component tree: the component will only be ONCE in the component tree even if it's inside a ui:repeat (fly-weight pattern). +1, but for now I will leave the question open.
waxwing