In this recipe, we will create a simple composite custom component (a component that's made up of existing components) using JSF 2.0. As you will see, JSF 2.0 can do that very quickly and easily, and even without a line of Java code.
We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.
Our component will just display a simple text, but the idea of this recipe is to understand the mechanism of doing it. First we develop an XHTML page, which is the page itself:
<?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"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:e="http://java.sun.com/jsf/composite/login"> <h:head> <title>Creating a composite component with zero Java code</title> </h:head> <h:body> <h:form> <div id="compositeComponent" style="border: 2px solid #000;"> <e:login value="LOGIN SPACE"> </e:login> </div> <h:commandButton value="Reload" /> </h:form> </h:body> </html>
Notice that the composite component library is indicated by the URL http://java.sun.com/jsf/composite/login. Well, this is not a normal URL, it has a special construction; the http://java.sun.com/jsf/composite/ part indicates to JSF that we have a composite component in role, while the /login
part indicates the name of the component.
The next step is to develop the custom component. Notice that the component page is named login.xhtml
and must be stored in the same folder with the page itself, under the /resources/login
folder (as an obvious observation we can note the fact that the page is developed in JSF 2.0 preferred style, using Facelets). The idea is that the folder and the component page reflect the component name. Now, the login.xhtml
file looks as shown next:
<!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:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite"> <h:head> <title>Creating a composite component with zero Java code - not rendered on output </title> </h:head> <h:body> <composite:interface> <composite:attribute name="value" required="false"/> </composite:interface> <composite:implementation> <h:outputText value="#{cc.attrs.value}" style="background-color: green"/> </composite:implementation> </h:body> </html>
In the <composite:interface>
tag, we indicate that our composite component accepts a single optional attribute, named value
. In the <composite:implementation>
tag, we implement the component as an outputText
with the value
attribute set to the value
attribute that's been passed in. The value that has been passed in is captured using the #{cc.attrs.value}
expression.
That's all! Now you can test your composite custom component!
Obviously, this works thanks to JSF 2.0, which is capable of reducing the entire complex process of creating custom components to just a few lines of code. The behind scene work makes this process a walk in the park. Based on Facelets and on a few conventions (like tag library URL, or component page name and location) we can now be more productive with much clear code produced in a short time.