Custom JSF components with Facelets

There are several reasons to use Facelets, like:

  • Problems in JSF 1.1 “Content Interweaving”
  • lightweight Templating Framwork (XHTML-based templates)
  • very friendly to designers (similar to Tapestry)
  • performance
  • JSF 1.2 w/o JavaEE 5 Container

Another is the very easy way of creating custom JSF components. In plain JSF you need these artifacts:

  • a lot of Java (Component, Renderer, JSP-Tag Class)
  • some XML (faces-config, TLD)

With Facelets, it is this:

  • XHTML file
  • Facelets Taglib XML file (very simple syntax)

With Facelets it is very easy to create sexy components, using 3rd party JavaScript libraries, such as Dojo Toolkit. The XHTML file contains all the markup want. The “taglib” is the glue code between the XHTML file and the user’s page, where a page author is using the (new) component.

The Dojo Toolkit contains lot of cool “components”, such as an accordion. It is not hard to make your layout (<div> elements) become a “AccordionContainer”, that contains several “AccordionPane” components, as the previews link shows. But every time reusing this, you repeat your self. So… you finally want a (jsf) component. Easy with Facelets.

All you need is two XHTML files (one for the container and one for the pane) and a little bit of XML to wire the two tags to the new components.

The container xhtml:

<div
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets">

  <link rel="stylesheet" type="text/css" 
     href="dtk/dijit/themes/tundra/tundra.css" />
  <script type="text/javascript"
    src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
    djConfig="parseOnLoad: true"></script>
  <script type="text/javascript">
    dojo.require("dojo.parser");
    dojo.require("dijit.layout.AccordionContainer");
   </script>

    <div dojoType="dijit.layout.AccordionContainer"
         duration="#{duration}" style="#{style}">

     <ui:insert/>

    </div>
</div>

Simply import the required CSS and JavaScript files and make the <div> element a “AccordionContainer” by using the dojoType attribute. The value for the attributes duration and style is provided with a ValueExpression. The user of the accordionContainer tag has to specify the correct value. Inside the <div> element there is a <ui:insert />. This allows us to nest other content (such as the later described pane component) inside the accordion.The pane xhtml:

<div xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  dojoType="dijit.layout.AccordionPane"
  title="#{title}">

  <ui:insert/>

</div>

This one is very simple, just a <div> that is representing the AccordionPane and a <ui:insert/> to nest content. Please note that this “component” doesn’t need to import CSS or JavaScript files. Why? Because it is only used inside the accordion which is already loading the needed files.The XML for the “taglib”:

<facelet-taglib>
  <namespace>

http://wessendorf.net/kickstart

  </namespace>
  <tag>
    <tag-name>accordionContainer</tag-name>
    <source>facelets/components/accordionContainer.xhtml</source>
  </tag>
  <tag>
    <tag-name>accordionPane</tag-name>
    <source>facelets/components/accordionPane.xhtml</source>
  </tag>
</facelet-taglib>

The taglib file is pretty trivial. It just contains a bunch of tags and points to the source code of the component, the location of the XHTML files.The finally result (the page, that uses these new components) looks like:

<mw:accordionContainer duration="250"
style="margin-right: 30px; width: 400px; height: 300px; overflow: hidden">
  <mw:accordionPane title="html content">
    <p>Hello</p>
  </mw:accordionPane>
  <mw:accordionPane title="some more html content">
    <ul>
      <li>hey!</li>
    </ul>
  </mw:accordionPane>
  <mw:accordionPane title="JSF component content">
    <tr:inputDate />
  </mw:accordionPane>
</mw:accordionContainer>

It is possible to mix content such as regular HTML or some other JSF components, like the <tr:inputDate> component from Trinidad.Very easy and straightforward to add to your project!I updated FacesGoodies to ship this example (only via SVN).

About these ads

Howdy!

Posted in dojo, facelets, javascript, jsf, jsp, myfaces, web²
9 comments on “Custom JSF components with Facelets
  1. Steve McCoole says:

    Thanks! This is a great summary that helps put a good concrete example to point folks to when I start listing the advantages of using facelets rather than JSP for JSF development.

  2. Alin-T says:

    Very nice article, good job!

  3. Kevin Kelleher says:

    Thanks also! Very very good article!

    I have a question.

    This example hooks up to a Dojo layout component – the accordion component.Is is possible to hook up to a Dojo widget component – say for the purpose of example – the dojo tree component.

  4. matthiaswessendorf says:

    Rick Hightower has somewhere an article on dojo tree and Facelets. That is indeed more “complex” than a simple layout container ;-)

  5. Joerg Schaefer says:

    Hi,
    nice article!
    But there is a big question.
    Is it possible to mix facelets and JSPs?
    Can i create a taglib with Facelets and use it within a JSP-page?

    Thanks

  6. Hiho Joerg

    i don’t think that is possible. With a JSP Page you have a Servlet for each Page itself and for Facelets you have mostly one Facelet that renders the whole output from many jspx Pages. In Fact it is a very differnt approach.

  7. matthiaswessendorf says:

    Same is true when there is a JSP-Tag, that is not present in your facelets lib (see Tomahawk, for issues like that…)

  8. [...] Custom JSF components with Facelets « Matthias Wessendorf’s Weblog (tags: jsf facelets) [...]

  9. Robert McAuliffe says:

    I know this is quite an old post, but I was wondering if in the vein of “JSF 1.2 w/o JavaEE 5 Container” facelets let you use JSF 1.2 without Java 5?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 34 other followers

%d bloggers like this: