Skip to main content

Writing a simple Composite Component with JSF 2.0

Posted by driscoll on November 1, 2008 at 11:46 AM PDT


One of the pain points for JSF has always been the complexity that you face in creating components. In JSF 2.0, creating a new component that's made up of existing components is a snap.


Here's a quick example of how you can create a new component, and use it in your page.


For this example, I wanted to create a simple text box that has a yellow background. Useful? No. Simple? Yes :-) In fact, it only needs two files. (This may look like a bit of code for a blog entry, but bear with me - most of it is just xhtml fluff. There's only about 4 or 5 lines that you'll actually need to learn.)


The first file is the page itself. Since JSF 2.0 uses Facelets as the preferred way to create pages, we'll use that. Here's the page:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ez="http://java.sun.com/jsf/composite/simpleout">
<h:head>
    <title>Yellow Text Example</title>
</h:head>
<h:body>
        <h1>Output Text Example</h1>
        <h:form id="form1">
                <ez:out value="Test Value"/>
            <p><h:commandButton value="reload"/></p>
            <h:messages/>
        </h:form>
</h:body>
</html>



Two lines you need to care about here:

xmlns:ez="http://java.sun.com/jsf/composite/simpleout"


defines the composite component library, and

<ez:out value="Test Value"/>

then uses the composite component. But where is the "simpleout" component library? It's in the directory WEB-INF/resources/simpleout, and the "out" component is defined in a file named out.xhtml in that directory. Here's the contents of that file:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>This will not be present in rendered output</title>
</head>
<body>

<composite:interface>
    <composite:attribute name="value" required="false"/>
</composite:interface>

<composite:implementation>
    <h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>
</composite:implementation>
</body>
</html>


Again, there's really two bits to look at here. The first is

<composite:attribute name="value" required="false"/>

says that our out component can take one attribute, named "value", and that it's presence is optional. Then,

<h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>


is where we actually define the component, with the "value" attribute set to the value attribute that's been passed in.


And that's it. No Java code is required for this very simple example.


I'll do other blogs about how to create more complex composite components, but I hope that I've made my point about how very simple this new way of component creation can be.


As always, if you have any questions, feel free to ask. And remember that you can try out this example by downloading GlassFish, and updating to JSF EDR2.


Update: I've updated this example to be more clear, and to conform with the latest JSF 2.0 PR release.

Related Topics >>

Comments

Not working in Glassfish v3. Incorrect resources directory path.

In post said: ... ut where is the "simpleout" component library? It's in the directory WEB-INF/resources/simpleout, and the "out" component .. In Glassfish v3, if put resources directory inside ${root}/WEB-INF/resources don't work. Correct directory is ${root}/WEB-INF/classes/resources or ${root}/resources according to "http://java.sun.com/javaee/6/docs/tutorial/doc/girgm.html" Is correct my interpretation?

The correct directory is as

The correct composite component (CC) directory is as you noted the ${root}/resources directory. /resources/simpleout/out.xhtml

Example Not working

Hi, It seems to me Maven Project included in 2.0.2 Makorra build (Ezcomp) is not working on GlassFish V3. Same example works on GlassFishV3Domain.

Works for me, please file a bug

Hi - if you're having problems with getting demos to run, please file a bug against Mojarra.  My blog isn't the place to debug the problem. 

please help on this composite component in ERROR

Please answer also on mail :eheb@yahoo.fr. Where is the troubleshooting ? I use your example and i found the same problem. Best regards. the error is : Warning: This page calls for XML namespace http://java.sun.com/jsf/composite/greet declared with prefix greet but no taglibrary exists for that namespace. here is the source code : the composite is located in WEB-INF/resources/greet/hello.xhtml or Hello.xhtml: My First Composite Component Then here is the use of this composite : compositeComponent.xhtml: JSF 2.0: Composite JSF 2.0:Composite

Health Composite First name:
Last name:
SSN:
Complete medical history since the day you were born:


Thanks for the example. Is it possible to build this using netbeans 6.5 which deploys into glassfish v2 ? I am not able to get this working hence the question. (Followed the release notes btw).

Thanks for the example. Is it possible to build this project using netbeans 6.5 which deploys into glassfish v2 ? I have been struggling to get this working, hence the question. (Followed release notes btw).

There's a simple mistake on this post, I have tried this example long time before, it just doesn't work. The problem is resource fold should be under root content, not under WEB-INF

Inheritance? I have done similar things with Facelets following the "Facelets fits like a glove" example but as the number of my custom components increased I wanted to start inheriting base functionality but couldn't find how. I had lots of components of the style my:combo, my:float, my:text, my:checkbox containing a lot of duplicated code. Any suggestions?

>What part of the component library defines the "out" component? it's defined by the out.xhtml file's name, and the contents of that file. One source of confusion for this example seems to be the attributes on the component interface tag. As I implied in my blog, ignore them - they're there for tools, and don't mean anything to you right now. They will not be required in the final version.

The interface just specifies the interface. I'm mystified why this would be any more of a problem in large projects than in small ones. Prehaps if you could expand on that idea?

Hrm, I wonder if the showed example is an example that the contract on the composite:interface / composite:implementation is just very weak. You specify an attribute before and just refer to it later. I think that this isn't really hand able in large projects... I personally found things in this blog entry kinda right: http://tapestryjava.blogspot.com/2008/11/simple-jsf-20-component-vs-tape...

Sounds good, I wait for the next blog.

If I had 2 components in the ez component library? how would that second component look? What part of the component library defines the "out" component?

Looks like Howard Lewis Ship saw this and showed the Tapestry 5 equiv: http://tapestryjava.blogspot.com/2008/11/simple-jsf-20-component-vs-tape...

Ah, that's the next blog :-) But JSF 2.0 takes care of all that for you as well, you'll see.

How do you do for write attributes with the Java Bean convection? This is necessary for programmatic control. JSF 2.0 generated the tag Handlers for attributes in java source code?

That's a very good starting for JSF2.0 Please put more examples, with more complex and practical situations, I am eagerly awaiting for next blog on this topic :) Also can you blog on PDL? I hope somebody is also working on standarding skinning issue.

Using JSF 2.0.0 Beta 1 the code line <h:outputText value="#{compositeComponent.attrs.value}" style="background-color: yellow"/> needs to look like this <h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/> to work properly.