Download - JSF2 Composite Components - Ian Hlavats

Transcript

Ian Hlavats | Tarantula Consulting Inc.

JSF2 Composite Components Workshop

Ian Hlavats •  JSF Consultant •  [email protected] •  Author, JSF 1.2 Components (Packt) •  JSFToolbox for Dreamweaver

(www.jsftoolbox.com)

JSF2 Composite Components Workshop

•  Goals: – To review new features in JSF2 – To understand composite components,

how they work, what problem they solve, when to use them, etc.

– To gain experience writing JSF2 composite components with several examples

Overview: JSF2 •  What’s new in JSF2?

– Facelets integration (VDL) – Composite components – Resource libraries – EL 2.2 (method params) – Standardized Ajax – @ManagedBean – New scopes – Much more

Overview: JSF2

•  Why focus on composite components? – Exciting new feature – Requires Facelets – Fully declarative UI components – Great potential for simplifying JSF – Unlock developer productivity

Composite Components

•  What problem do they solve? – Lightweight, rapid UI development – Traditional JSF component development is

cumbersome (component, renderer, TLD, taglib.xml, faces-config.xml, web.xml)

•  Developers need a faster way to build/reuse user interface elements

Composite Components •  How do they work?

–  Define with new <composite> JSF tags –  Uses naming convention (namespace prefix, URI) –  No configuration needed –  Facelets only (no JSP) –  Can be packaged/deployed as a jar –  Can use resources (images, stylesheets, scripts, etc.) –  Special EL objects: #{cc}, #{resource}

•  Some terminology: –  Using page: the file that uses the composite

component –  Component definition: the file that declares the

composite component

Composite Components •  Important naming convention: <html xmlns:foo=“http://java.sun.com/jsf/composite/foo”> <body> <foo:hello /> </body> </html> •  The component is defined in

/resources/foo/hello.xhtml •  JSF 2 automatically detects and renders the

component

JSF 2.1 <composite> taglib <composite:actionSource> <composite:attribute> <composite:clientBehavior /> <composite:editableValueHolder> <composite:extension> <composite:facet> <composite:implementation> <composite:insertChildren> <composite:insertFacet> <composite:interface> <composite:renderFacet> <composite:valueHolder>

<composite:interface>

•  Declares the usage contract of the component

<composite:interface> … </composite:interface>

<composite:implementation> •  Defines the component implementation <composite:interface /> <composite:implementation> <h:outputText value=“Hello World” /> </composite:implementation> … <foo:hello />

<composite:attribute> •  Defines a tag attribute exposed to developer <composite:interface> <composite:attribute name=“message” required=“true” default=“Howdy” /> </composite:interface> <composite:implementation> <h:outputText value=“#{cc.attrs.message}” /> </composite:implementation> … <foo:hello message=“Hello World” />

<composite:facet> •  Defines a custom facet supported by this component

<composite:interface> <composite:facet name=“header” /> </composite:interface> <composite:implementation> <composite:renderFacet name=“header” /> </composite:implementation> … <foo:facetExample> <f:facet name=“header”> <h:outputText value=“My Header” /> </f:facet> </foo:facetExample>

<composite:renderFacet> •  Renders the facet’s content

<composite:implementation> <div class=“content”> <composite:renderFacet name=“content” /> </div> </composite:implementation> … <foo:myComponent> <f:facet name=“content”> <h:outputText value=“My Content” /> </f:facet> </foo:myComponent>

<composite:insertFacet> •  Inserts the facet into the component subtree

<composite:implementation> <h:dataTable …> <composite:insertFacet name=“header” /> <composite:insertFacet name=“footer” /> </h:dataTable> </composite:implementation> … <foo:myComponent> <f:facet name=“header”> <h:outputText value=“My Header” /> </f:facet> <f:facet name=“footer”> <h:outputText value=“My Footer” /> </f:facet> </foo:myComponent>

<composite:actionSource> •  Defines ActionListener event published by the component <composite:interface> <composite:actionSource name=“helloButton” targets=“helloButton” /> </composite:interface> <composite:implementation> <h:commandButton id=“helloButton” value=“Say Hello” /> </composite:implementation> … <foo:myComponent> <f:actionListener for=“helloButton” binding=“#{bean.sayHello(ActionEvent)}” /> </foo:myComponent>

<composite:valueHolder> •  Exposes a component’s non-editable value to the page author

for registering a converter or validator

<composite:interface> <composite:valueHolder name=“country” /> </composite:interface> <composite:implementation> <h:outputText value=“#{countryBean.country}” /> </composite:implementation> … <foo:country> <f:converter for=“country” converterId=“test.CountryConverter” /> </foo:country>

<composite:editableValueHolder> •  Enables registration of a ValueChangeListener, Converter or Validator

on one or more components within the composite component <composite:interface> <composite:editableValueHolder name=“country” targets=“country” /> </composite:interface> <composite:implementation> <h:selectOneMenu id=“country” value=“#{country}”> <f:selectItems value=“#{countryList}” /> </h:selectOneMenu> </composite:implementation> … <foo:countries> <f:converter for=“country” converterId=“countryConverter” /> <f:validator for=“country” validatorId=“countryValidator” /> </foo:countries>

<composite:insertChildren> •  Inserts the child UI components into the component

subtree

<composite:implementation> <span style=“font-weight:bold”> <composite:insertChildren /> </span> </composite:implementation> … <foo:myComponent> <h:outputText value=“Hello ” /> <h:outputText value=“World” /> </foo:myComponent>

<composite:clientBehavior> •  Declares Ajax events that can be handled by the page author <composite:interface> <composite:clientBehavior name=“speak” event=“action” targets=“speakButton” /> </composite:interface> <composite:implementation> <h:commandButton value=“Speak” id=“speakButton” /> <h:commandButton value=“Don’t Speak” id=“noSpeakButton” /> </composite:implementation> … <foo:speak> <f:ajax event=”speak" onevent=”alert(‘Hello’)"/> </foo:speak>

<composite:extension> •  Enables design-time metadata to be

included in the component interface

<composite:interface> <composite:attribute name=“message”> <composite:extension> <!-- Metadata XML here --> </composite:extension> </composite:attribute> </composite:interface>

Composite Component Implicit EL Object

•  #{cc} –  Refers to the current composite component

•  #{cc.attrs} –  Refers to attributes map of composite component,

e.g. #{cc.attrs.message} is reference to <foo:hello message=“Hello” />

•  #{cc.resourceBundleMap.key} –  Refers to composite component’s resource bundle –  Must be in same dir and have same name as

component definition file: /resources/foo/hello.xhtml /resources/foo/hello.properties

Lab Exercises

1.  Hello World Component 2.  Country List Component 3.  Customer Info Panel Component 4.  Customer Registration Wizard

Hello World Component

1.  Write a JSF2 composite component that prints “Hello World”.

2.  Use this component from another page.

3.  Deploy and test using JBoss 7.

Country List Component

1.  Write a JSF2 composite component that renders a list of countries for selection.

2.  Use this component from another page.

3.  Implement the TODO comments. 4.  Deploy and test using JBoss 7.

Customer Info Panel Component

1.  Write a JSF2 composite component that receives input for a new customer.

2.  Include the country list component from lab #2.

3.  Use this component from another page.

4.  Implement the TODO comments. 5.  Deploy and test using JBoss 7.

Customer Registration Wizard

1.  Write a JSF2 composite component that uses the PrimeFaces Wizard component.

2.  Reuse the customer info panel component from lab 3.

3.  Implement a Feedback tab. 4.  Implement the TODO comments. 5.  Deploy and test using JBoss 7.