0% found this document useful (0 votes)
31 views

Creating A Composite Component Tutorial

This tutorial demonstrates how to create a composite component in JSF to simplify and modularize common form field markup. The tutorial: 1. Creates a basic JSF project and page with first and last name fields. 2. Develops a "fieldSet" composite component to encapsulate the repeated field markup. 3. Updates the main page to use the new fieldSet component, simplifying the code. 4. Expands the example by adding a middle name field, showing how easily the component allows extending the form.

Uploaded by

schmalacker
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views

Creating A Composite Component Tutorial

This tutorial demonstrates how to create a composite component in JSF to simplify and modularize common form field markup. The tutorial: 1. Creates a basic JSF project and page with first and last name fields. 2. Develops a "fieldSet" composite component to encapsulate the repeated field markup. 3. Updates the main page to use the new fieldSet component, simplifying the code. 4. Expands the example by adding a middle name field, showing how easily the component allows extending the form.

Uploaded by

schmalacker
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

Creating a Composite Component Tutorial

Although Facelets and composite components were present in JSF 1.x, the release of JSF 2 has seen a strong focus on the Facelets view technology. As part of this focus composite components have been substantially improved with new features and bug fixes. This tutorial will deal with creating a custom composite component for use in our demo application. This tutorial assumes the reader has an understanding of JSF and ICEfaces and creating and working with projects related to those technologies. The goal of this tutorial is to create a basic ICEfaces 2 project and simplify it with the addition of a "fieldSet" composite component, which will wrap the common grouping of an outputlabel, inputText, and message tag. The example itself is rather simple and allows a user to input their name.

Here is the entire list of steps worked through during this tutorial: 1. 2. 3. 4. 5. 6. Make the compositeComponent Project Add ICEfaces Create main.xhtml Create NameBean.java Deploy the Application Create a Composite Component o Create Directory Structure o Create Component Page 7. Using a Composite Component o Add Namespace o Use fieldSet.xhtml 8. Add Middle Name o Add to Bean o Add to Page 9. Re-Deploy the Application

Tutorial Source Code Downloads

Development Tools Used


The following tools were used to create the project.

Eclipse IDE for Java EE Developers - Version Helios Tomcat 7.x Web Server Java 6.x ICEfaces 2

1. Make the compositeComponent Project

Using Eclipse create a new Dynamic Web Project called compositeComponent. o Target runtime: Apache Tomcat v7.0 o Dynamic web module version: 3.0 o Configuration: JavaServer Faces v2.0 Project (Mojarra)

2. Add ICEfaces
Add the icefaces.jar to your project from the ICEfaces 2 bundle. This can be added to the project through a custom User Library or by putting it into compositeComponent/WEBINF/lib/. The approach doesn't matter as long as the jar is included in the deployed war file.

3. Create main.xhtml
Create a new page called main.xhtml and paste the code below: main.xhtml
<!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"> <h:head> <title>Composite Component - Main</title> </h:head> <h:body> <h:form> <h:panelGrid columns="3"> <f:facet name="header"> Hello, what is your name? </f:facet> <h:outputLabel for="firstName" value="First Name"/> <h:inputText id="firstName" value="#{nameBean.firstName}" required="true"/> <h:message for="firstName"/> <h:outputLabel for="lastName" value="Last Name"/> <h:inputText id="lastName" value="#{nameBean.lastName}" required="true"/> <h:message for="lastName"/> <f:facet name="footer"> <h:commandButton value="Submit"/><br/> </f:facet> </h:panelGrid> <h:outputText value="Greetings '#{nameBean.firstName} #{nameBean.lastName}'." rendered="#{nameBean.hasName}"/> </h:form> </h:body> </html>

This basic page prompts the user for their first and last name, and displays the result after the user has submitted the form. The page doesn't use any composite components, but the similar, repeated markup of h:outputLabel, h:inputText, and h:message is a perfect candidate for a composite component.

4. Create NameBean.java
Create a new Java class file called NameBean in the package org.icefaces.tutorial.composite.beans and paste the code below: NameBean.java
package org.icefaces.tutorial.composite.beans; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; @ManagedBean(name="nameBean") @SessionScoped public class NameBean { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public boolean getHasName() { return firstName != null && lastName != null; } }

As with the page this backing bean is very simple. We manage the first and last name variables, and also have a convenience method to determine if a name has been entered or not.

5. Deploy the Application


Build and deploy the application. When visiting the page it will appear similar to the following:

When entering a name and pressing the "Submit" button you will see "Greetings, firstName lastName" appear at the bottom.

6. Create a Composite Component


Now that we have a basic application running we'll improve and modularize the code with a JSF 2 composite component. Composite components are more convenient to create (compared to creating a new component from the ground up) and allow imaginative combinations of markup to be packaged into an easy-to-use form. The purpose of composite components can be to modularize common, reusable functionality, or to introduce new functionality through combining existing tags. In our above example the firstName and lastName chunks of markup are similar, and instead of repeating the markup as we add more fields, we can package the markup into a composite component. 6a. Create Directory Structure First we will set up the directory structure used by the composite component. This will affect the namespace used by parent pages. Make the following directory structure in your Eclipse project:
web/resources/components/example/

6b. Create Component Page Inside the example/ directory created above, create a new page called fieldSet.xhtml and paste the code below: fieldSet.xhtml
<?xml version="1.0" encoding="utf-8"?> <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:composite="http://java.sun.com/jsf/composite"> <composite:interface> <composite:attribute name="label" /> <composite:attribute name="value" required="true" /> <composite:attribute name="required" default="false" /> <composite:editableValueHolder name="input" /> </composite:interface> <composite:implementation> <h:outputLabel for="input" value="#{cc.attrs.label}" style="float:left;"/> <h:inputText id="input" value="#{cc.attrs.value}" style="float:left;" required="#{cc.attrs.required}"/> <h:message for="input" id="msg"/> </composite:implementation> </html>

This is our composite component interface and implementation. The interface declares how the composite component will be used in a parent page, including available attributes and the

default values for those attributes. The implementation actually holds the markup that is inserted into the parent page when the composite component is used. The new markup used in our page as a result of creating the composite component: Example Usage
<ourComp:fieldSet label="Some Label Text" value="#{someBean.binding}"/>

7. Using a Composite Component


The above step is all we needed to do to create a composite component. Now let's use it! 7a. Add Namespace First add the default composite component namespace generated by our directory structure, so that we can access the fieldSet.xhtml from our main.xhtml page. The default namespace is http://java.sun.com/jsf/composite/, and the child directories of our resources/ directory specifies the remainder of the namespace. Because our directory is resources/components/example/ our final namespace is as follows: main.xhtml header
... xmlns:ourComp="http://java.sun.com/jsf/composite/components/example" ...

In the <html> container at the top of main.xhtml add the namespace above. 7b. Use fieldSet.xhtml Now let's replace our first and last name markup with the new composite component. Replace the existing <h:panelGrid> with the following code: New panelGrid
<h:panelGrid> <f:facet name="header"> Hello, what is your name? </f:facet> <ourComp:fieldSet label="First Name" value="#{nameBean.firstName}" required="true"/> <ourComp:fieldSet label="Last Name" value="#{nameBean.lastName}" required="true"/> <f:facet name="footer"> <h:commandButton value="Submit"/><br/> </f:facet> </h:panelGrid>

The markup is simpler while still remaining functional. If we needed more attributes than the three (label, value, required) we made available in the composite component, we could just modify the composite:interface to add more "passthrough" attributes, such as maxlength, size, style, etc.

8. Add Middle Name


Now let's add a new field, just to see how simple the process is. 8a. Add to Bean Add the following variable to NameBean.java and generated getters/setters for it: Middle Name Variable
private String middleName;

* Also modify the getHasName method to include the new middleName variable. 8b. Add to Page Add the new middleName by pasting another instance of our new composite component between the firstName and lastName markup in main.xhtml: Middle Name Markup
<ourComp:fieldSet label="Middle Name" value="#{nameBean.middleName}" required="true"/>

* Also modify the outputText at the bottom to include displaying the new #{nameBean.middleName} variable.

9. Re-Deploy the Application


Re-build and re-deploy the application and visit the page again. You'll see that the actual rendering of the page is very similar, but from a developer point of view the code is much cleaner to maintain and view. For example if we wanted to style the h:message we could add a single styleClass to the composite component, instead of having to copy-paste the change throughout our entire codebase (which in a large application may have hundreds of similar field setups as we've seen above).

You might also like