Composite component collapsiblePanel

JavaServer Faces claims to be a component based framework since the first version. This claim is completely  fulfilled as components are an integral part of JSF. Furthermore components are the most import extension point.

Prior to JSF 2.0 developing custom components tended to be a troublesome task. JSF 2.0 makes a big step forward in this area and considerably simplifies component developement. The new composite components allow users to develop components without writing one line of Java code or xml configuration. Composite components are plain xhtml view fragments just like your views.

In my opinion composite components are one of the most important features of JSF 2.0. This post will not give an introduction to this topic. Its main purpose is to present the composite component collapsiblePanel which will be used in subsequent posts.

The composite component collapsiblePanel renders a panel that can be collapsed and expanded with the click of a button. This button is rendered as an icon that changes if the component is collapsed or expanded. Next to the button the content of the facet header is rendered if specified.

The following listing shows the composite component collapsiblePanel:

<cc:interface>
  <cc:attribute name="model" required="true">
    <cc:attribute name="collapsed" required="true"/>
    <cc:attribute name="toggle" required="true"
        method-signature="java.lang.String f()"/>
  </cc:attribute>
  <cc:actionSource name="toggle"/>
  <cc:facet name="header"/>
</cc:interface>
<cc:implementation>
  <h:panelGroup layout="block" styleClass="collapsiblePanel-header">
    <h:commandButton id="toggle" action="#{cc.attrs.model.toggle}"
        styleClass="collapsiblePanel-img"
        image="#{resource[cc.attrs.model.collapsed
                 ? 'jsflive:plus.png' : 'jsflive:minus.png']}"/>
    <cc:renderFacet name="header"/>
  </h:panelGroup>
  <h:panelGroup layout="block" rendered="#{!cc.attrs.model.collapsed}">
    <cc:insertChildren/>
  </h:panelGroup>
  <h:outputStylesheet library="jsflive" name="components.css"/>
</cc:implementation>

The content inside the second h:panelGroup is collapsed and expanded with the attributes collapsed and toggle. Both of them are embedded in the model attribute. This allows the user to pass in a managed bean with a property collapsed and a method toggle.

The different images for the button are fetched directly out of the component’s resource library with the implicit object resource.

The following listing shows the usage of the component in a page:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:jl="http://java.sun.com/jsf/composite/jsflive">
<h:head>
  <title>JSFlive test page</title>
</h:head>
<h:body>
  <h:form id="form">
    <h:outputText value="JSFlive collapsible panel test page"/>
    <jl:collapsiblePanel id="addressPanel" model="#{testController}">
      <f:facet name="header">
        <h3><h:outputText value="Collapsible information"/></h3>
      </f:facet>
      <h:outputText value="This information is collapsible."/>
    </jl:collapsiblePanel>
  </h:form>
</h:body>
</html>

The following listing shows the code of the managed bean class TestController:

@ManagedBean @SessionScoped
public class TestController {
  private boolean collapsed = false;

  public boolean isCollapsed() {
    return collapsed;
  }
  public void setCollapsed(boolean collapsed) {
    this.collapsed = collapsed;
  }
  public String toggle() {
    collapsed = !collapsed;
    return null;
  }
}

The following figure shows the content and folder structure of the library containing the component and all required resources:

So far, so good – the composite component collapsiblePanel presented in this post works without problems. But there is a major design flaw. The logic for collapsing and expanding the content must be supplied by the user in the model attribute. This is against the definition of the term component as self-contained and reusable artefact. I will take care of this problem in on of my next posts.

The source code for the presented example can be found in the Github repository collapsible01.

Advertisements

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