LayeredPane

The LayeredPane component is a container which allows switching between different sets of displayed components. Each set of components, called a page, is declared within the LayeredPane component and it's possible to use both server-side and client-side API for selecting the currently displayed page. LayeredPane provides different page loading modes to allow quick client-side switching or Ajax-based page switching.


API Reference | Tag Reference
Online Demo

Key Features

Basic Information

The LayeredPane component can be declared using the <o:layeredPane> tag with list of child <o:subPanel> tags, where each <o:subPanel> specifies one page in the LayeredPane component. The <o:subPanel> tag should contain an arbitray set of components that will be displayed as the content for LayeredPane when this page is selected.

Here's a simple example where three pages are declared and a simple server-side page switching mechanism is provided:

<o:layeredPane id="layeredPane" 
               selectedIndex="#{requestScope['pageIndex']}"
               style="border: 1px solid black">
  <o:subPanel>
    <div>Page 1 content.</div>
    <h:outputText value="Hello!"/>
  </o:subPanel>
  <o:subPanel>
    <div>Page 2 content.</div>
    <o:graphicText value="Hi!" direction="45" style="font-size: 27px;"/>
  </o:subPanel>
  <o:subPanel>
    <div>Page 3 content.</div>
    <h:inputTextarea/>
  </o:subPanel>
</o:layeredPane>

<o:spinner value="#{requestScope['pageIndex']}" value="0" minValue="0" maxValue="2">
  <o:ajax event="change" render="layeredPane"/>
</o:spinner>

As you can see from the example above, the currently displayed page is identified by the value of selectedIndex attribute, which should refer to the zero-based integer number. Like the standard <h:panelGroup> and <h:panelGrid> components, <o:layeredPane> doesn't have any visual decorations for the child compoenents though it's possible to apply the style for the container using the style and styleClass attributes, as well as the style applied when the mouse hovers over the container using the rolloverStyle and rolloverClass attributes.

It is also possible to specify the list of pages that is composed at run time. This can be achieved by adding the <o:subPanels> tag inside of the <o:layeredPane> tag. The the value attribute of this tag must be a value binding expression that references a collection of org.openfaces.component.panel.SubPanel objects.

Here's an example:

<o:layeredPane>
  <o:subPanels value="#{MyBean.dynamicPanels}"/>
</o:layeredPane>
...

public List<SubPanel> getDynamicPanels() {
  ...
}

You can combine these two approaches by placing the <o:subPanel> and <o:subPanels> tags in any order you need.

Note that when referring to a page by index, e.g. with the selectedIndex attribute, the pages are indexed regardless of the value of their rendered attribute. In other words, the selectedIndex attribute refers to all of the tabs specified in the LayeredPane component, and not just visible tabs.

Client-Side Switching and Loading Modes

Besides the server-side page switching API with the selectedIndex attribute, there's the client-side API that works in combination with the customizible loading modes. The current page can be change using the client-side setSelectedIndex(index) SidePanel's method. Invoking this method makes the specified page to be shown depending on the current loading mode.

The way the data in the LayeredPane component is loaded when invoking the setSelectedIndex(index) function depends on the loadingMode attribute, which can take one of the following values:

  • "client" - The content of all pages is loaded to the client side on the initial page load. So when any LayeredPane page is selected, no content needs to be loaded from the server.
  • "ajaxLazy" (default) - The page content is retrieved from the server with Ajax request upon the first switch to the page. Once requested, the content is stored on the client and is shown without additional server requests.
  • "ajaxAlways" - The page content is retrieved from the server with Ajax request on every switch to the page.
  • "server" - Every time a when selecting a page, the whole browser's page is reloaded to show the LayeredPane's page content.

Below is a modification of the previous example which has with the "client" loading mode and uses the setSelectedIndex function, so when a page is selected it is shown immediately without any server requests.

<o:layeredPane id="layeredPane" loadingMode="client"
               style="border: 1px solid black">
  <o:subPanel>
    <div>Page 1 content.</div>
    <h:outputText value="Hello!"/>
  </o:subPanel>
  <o:subPanel>
    <div>Page 2 content.</div>
    <o:graphicText value="Hi!" direction="45" style="font-size: 27px;"/>
  </o:subPanel>
  <o:subPanel>
    <div>Page 3 content.</div>
    <h:inputTextarea/>
  </o:subPanel>
</o:layeredPane>

<o:spinner value="0" minValue="0" maxValue="2" 
           onchange="O$('form:layeredPane').setSelectedIndex(this.getValue());"/>

Note that the LayeredPane includes the current page number when the form is submitted, so even with if a page was switched without any server requests with a loadingMode of "client" explicit page submission (or Ajax submission) will save the current page in the server-side SidePanel instance and if its pageIndex attribute is declared as binding that binding will be updated as well.

Client-Side Events

The LayeredPane component supports a set of standard client-side events such as onclick, ondblclick, onmousedown, onmouseover, onmouseup, onmouseout, onmousemove, onkeydown, onkeyup, onkeypress.

Server-Side Event Listeners

To enable you to handle tab selection change on the server side, the LayeredPane component provides the selectionChangeListener attribute. This attribute is MethodBinding that must point to the method that accepts a org.openfaces.event.SelectionChangeEvent. SelectionChangeEvent extends javax.faces.event.FacesEvent and adds the oldIndex and newIndex properties to it. The specified method will be called during the Process Validations phase of the request processing lifecycle, when a selected tab in the LayeredPane is changed.

You can also add a selection change listener (which is the implementation of the org.openfaces.event.SelectionChangeListener interface) to the LayeredPane component by using the <o:selectionChangeListener> tag:

<o:layeredPane ...>
  ...
  <o:selectionChangeListener type="my.MySelectionChangeListener"/>
</o:layeredPane>

There is also immediate attribute that is used to specify whether or not selectionChangeListener should be executed immediately (during the Apply Request Values phase of the request processing lifecycle instead of Process Validations phase).

Client-Side API

All client-side API methods of the LayeredPane component are listed in the following table:

Method Description
getPageCount() Returns the number of pages in the LayeredPane component on which this method is invoked.
getSelectedIndex() Returns a zero-based index of a selected tab from the LayeredPane component on which this method is invoked.
setSelectedIndex(index) Sets the index of a selected tab for the LayeredPane component on which this method is invoked. The index parameter is a zero-based index of a tab to be selected.
OpenFaces