Oracle® Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1.5.0) Part Number B31973-09 |
|
|
PDF · Mobi · ePub |
This chapter describes how to use several of the ADF Faces layout components to organize content on web pages.
This chapter includes the following sections:
Section 8.1, "Introduction to Organizing Content on Web Pages"
Section 8.5, "Arranging Page Contents in Predefined Fixed Areas"
Section 8.9, "Displaying or Hiding Contents in Accordion Panels and Tabbed Panels"
Section 8.11, "Displaying a Bulleted List in One or More Columns"
Section 8.13, "Separating Content Using Blank Space or Lines"
ADF Faces provides a number of layout components that can be used to arrange other components on a page. Usually, you begin building your page with these components. You then add components that provide other functionality (for example rendering data or rendering buttons) either inside facets or as child components to these layout components.
Tip:
You can create page templates that allow you to design the layout of pages in your application. The templates can then be used by all pages in your application. For more information, see Chapter 19, "Creating and Reusing Fragments, Page Templates, and Components."In addition to layout components that simply act as containers, ADF Faces also provides interactive layout components that can display or hide their content, or that provide sections, lists, or empty space. Some layout components also provide geometry management functionality, such as stretching their contents to fit the browser windows as the window is resized, or the capability to be stretched when placed inside a component that stretches. For more information about stretching and other geometry management functionality of layout components, see Section 8.2.1, "Geometry Management and Component Stretching."
Table 8-1 briefly describes each of the ADF Faces layout components.
Table 8-1 ADF Faces Layout Components
Component | Description | Can Stretch Children | Can Be Stretched | |
---|---|---|---|---|
Page Management Components |
||||
|
Creates each of the standard root elements of an HTML page: |
X |
||
|
Creates an HTML |
|||
Page Layout Containers |
||||
|
Contains |
X |
X (when the |
|
|
Divides a region into two parts ( |
X |
X (when the |
|
|
Provides a columnar display of child components (usually |
X |
X (when the |
|
|
Can have child components, which are placed in its center, and also contains 12 facets along the border where additional components can be placed. These will surround the center. For more information, see Section 8.5, "Arranging Page Contents in Predefined Fixed Areas." |
|||
|
Positions input form controls, such as |
|||
Components with Show/Hide Capabilities |
||||
|
Can hide or display contents below the header. Often used as a child to the |
X (if the |
X (if the |
|
|
Used to hold the content for the different panes of the |
X (if it contains a single child component) |
||
|
Titled box that can contain child components. Has a toolbar facet. For more information, see Section 8.8, "Displaying and Hiding Contents Dynamically." |
X |
||
|
Used in conjunction with |
X (when the |
||
|
Used in conjunction with If you want the tabs to be used in conjunction with navigational hierarchy, for example each tab is a different page or region that contains another set of navigation items, you may instead want to use a |
X (when the |
||
|
Hides or displays content through a toggle icon. For more information, see Section 8.8, "Displaying and Hiding Contents Dynamically." |
|||
Miscellaneous Containers |
||||
|
Contains child components and provides a header that can include messages, toolbars, and help topics. For more information, see Section 8.10, "Displaying Items in a Static Box." |
X (if the |
X (if the |
|
|
Used in conjunction with collection components such as |
X (only a single table, tree, or tree table) |
X |
|
|
Creates a container component whose facets use style themes to apply a bordered look to its children. This component typically acts as a look and feel transition between areas on a page. For example, a page that has a dark background for its template can use the decorative box to transition to a white background for its main area. For more information, see Section 8.10, "Displaying Items in a Static Box." |
X (in the Center facet) |
X (when the |
|
|
Creates an inline |
X |
||
|
Creates a series of navigation items representing one level in a navigation hierarchy. For more information, see Section 18.5, "Using Navigation Items for a Page Hierarchy." |
X (if configured to display tabs) |
||
|
Renders each child component as a list item and renders a bullet next to it. Can be nested to create hierarchical lists. For more information, see Section 8.11, "Displaying a Bulleted List in One or More Columns." |
|||
|
Displays child components inside a popup window. For more information, see Section 13.2, "Declaratively Creating Popup Elements." |
|||
|
Displays child toolbar and menu components together. For more information, see Section 14.3, "Using Toolbars." |
|||
Grouping Containers |
||||
|
Groups child components either vertically or horizontally. Used in facets when more than one component is to be contained in a facet. For more information, see Section 8.12, "Grouping Related Items." |
X (only if set to scroll or vertical layout) |
||
|
Groups child components without regard to layout unless handled by the parent component of the group. Used in facets when more than one component is to be contained in a facet. For more information, see Section 8.12, "Grouping Related Items." |
|||
Spacing Components |
||||
|
Creates a horizontal line between items. For more information, see Section 8.13, "Separating Content Using Blank Space or Lines." |
|||
|
Creates an area of blank space. For more information, see Section 8.13, "Separating Content Using Blank Space or Lines." |
JSF pages that use ADF Faces components must have the document
tag enclosed within a view
tag. All other components that make up the page then go in between <af:document>
and </af:document>
. The document
tag is responsible for rendering the browser title text, as well as the invisible page infrastructure that allows other components in the page to be displayed. For example, at runtime, the document
tag creates the root elements for the client page. In HTML output, the standard root elements of an HTML page, namely, <html>
, <head>
, and <body>
, are generated.
By default, the document
tag is configured to allow capable components to stretch to fill available browser space. You can further configure the tag to allow a specific component to have focus when the page is rendered, or to provide messages for failed connections or warnings about navigating before data is submitted. For more information, see Section 8.2.5, "How to Configure the document Tag."
Typically, the next component used is the ADF Faces form
component. This component creates an HTML form
element that can contain controls that allow a user to interact with the data on the page.
Note:
Even though you can have multiple HTML forms on a page, you should have only a single ADF Facesform
tag per page. For more information, see Section 8.6, "Arranging Content in Forms."JDeveloper automatically inserts the view
, document,
and form
tags for you, as shown in Example 8-1. For more information, see Section 2.4, "Creating a View Page."
Example 8-1 Initial JSF Page Created by JDeveloper Wizard
<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"> <jsp:directive.page contentType="text/html;charset=UTF-8"/> <f:view> <af:document> <af:form/> </af:document> </f:view> </jsp:root>
Once those tags are placed in the page, you can use the layout components to control how and where other components on the page will render. The component that will hold all other components is considered the root component. Which component you choose to use as the root component depends on whether you want the contained components to display their contents so that they stretch to fit the browser window, or whether you want the contents to flow, using a scrollbar to access any content that may not fit in the window. For more information about stretching and flowing, see Chapter 8, "Geometry Management and Component Stretching."
Tip:
Instead of creating your layout yourself, you can use JDeveloper's quick layout templates, which provide correctly configured components that will display your page with the layout you want. For more information, see Section 8.2.3, "Using Quick Start Layouts."Geometry management is the process by which the user, parent components, and child components negotiate the actual sizes and locations of the components in an application. At the heart of the RCF geometry management solution is a resize notification mechanism that allows components that support geometry management to be notified of browser resize activity. The following scenarios trigger the notification:
Load: When the page contents are first loaded, allowing initial sizing to take place.
Browser resize: When the browser window is resized.
Partial replacement: When a portion of the page is updated through partial page rendering, any newly inserted components are notified, allowing them to perform any necessary geometry management.
Visibility change: When a component that was initially configured to be invisible is made visible (components that are initially not visible do not receive notification).
Explicit resize: When components that allow themselves to be resized (for example the panelSplitter
), are resized by the user.
By default, the root component will stretch automatically to consume the browser's viewable area, provided that component supports geometry management and therefore can stretch its child components. Examples of geometry management components are panelStretchLayout
and panelSplitter
.
Note:
The framework does not consider popup dialogs, popup windows, or non-inline messages as root components. If aform
component is the direct child component of the document
component, the framework will look inside the form
tag for the visual root. For information on sizing a popup, see Chapter 13, "Using Popup Dialogs, Menus, and Windows."When the user resizes the browser window, and when there is a single maximized root visual component inside of the document
component, that visual root component will also resize along with the browser window. If the root component supports stretching its child components (and they in turn support being stretched), the size of the child components will also recompute, and so on down the component hierarchy until a flowing layout area is reached; that is, an area that does not support stretching of its child components. You do not have to write any code to enable the stretching.
As shown in Table 8-1, the panelStretchLayout
, panelSplitter
, and panelDashboard
components are components that can be stretched and can also stretch their child components. Additionally, when the showDetailItem
component is used as a direct child of the panelAccordion
or panelTabbed
component, the contents in the showDetail
Item
component can be stretched. Therefore, the panelStretchLayout
, panelSplitter
, panelDashboard
, panelAccordion
with a showDetailItem
component, and a panelTabbed
with a showDetailItem
component, are the components you should use as root components when you want to make the contents of the page fill the browser window.
For example, Figure 8-1 shows a table placed in the center
facet of the panelStretchLayout
component. The table stretches to fill the browser space. When the entire table does not fit in the browser window, scrollbars are added in the data body section of the table.
Figure 8-2 shows the same table, but nested inside a panelGroupLayout
component, which cannot stretch its child components (for clarity, a dotted red outline has been placed around the panelGroupLayout
component). The table component displays only a certain number of columns and rows, determined by properties on the table.
Even though you choose a component that can stretch its child components, only the following components will actually stretch:
inputText
(when configured to stretch)
decorativeBox
(when configured to stretch)
panelAccordion
(when configured to stretch)
panelBox
panelCollection
panelDashboard
(when configured to stretch)
panelGroupLayout
(with the layout
attribute set to scroll
or vertical
)
panelSplitter
(when configured to stretch)
panelStretchLayout
(when configured to stretch)
panelTabbed
(when configured to stretch)
region
table
(when configured to stretch)
tree
(when configured to stretch)
treeTable
(when configured to stretch)
The following layout components cannot be stretched when placed inside a facet of a component that stretches its child components:
panelBorderLayout
panelFormLayout
panelGroupLayout
(with the layout
attribute set to default
or horizontal
)
panelHeader
panelLabelAndMessage
panelList
showDetail
showDetailHeader
tableLayout
(MyFaces Trinidad component)
Because these components cannot be stretched, you cannot place them in a facet of any component that stretches its child components. So if you want to use one of these components within the facet of component that does stretch its child components, you must wrap it in a component that can be stretched, but one that does not stretch its child components. If you do not, you may see unexpected results when the component renders.
For example, suppose you have a panelStretchLayout
as the first component on your page. You then add a panelSplitter
component that is configured to be stretched. Now to the first facet of the panelSplitter
component, say you add a panelGroupLayout
component with its layout
attribute set to scroll
(which means it can stretch), and inside that, you add a panelCollection
component, and then finally a table
component.
To the second facet of the panelSplitter
, suppose you add just the panelCollection
and table
components, as shown in Figure 8-3. Components that can stretch their children are green and components that can be stretched (but cannot stretch their children) are blue.
As shown in Figure 8-4, when the page is run, the panelCollection
and table
components in the panelGroupLayout
do not stretch, while the ones directly in the panelSplitter
component do stretch.
Because the panelStretchLayout
component can stretch its child components, and because the panelSplitter
component was configured to stretch, both stretch to fill up available browser space. Because panelSplitter
component can stretch its child components and because on the left, panelGroupLayout
component with its layout
attribute set to scroll
can be stretched, and on the right, the panelCollection
component can be stretched, both of those stretch to fill up available browser space. However, the panelGroupLayout
component cannot stretch its child components, while the panelCollection
component can stretch a single table. Therefore, the panelCollection
component on the left does not stretch, even though its parent does.
Tip:
Do not attempt to stretch any of the components in the list of components that cannot stretch by setting their width to 100%. You may get unexpected results. Instead, surround the component to be stretched with a component that can be stretched. For components that can be stretched, see Table 8-1.Now suppose on the left, instead of a table
component, you want to add a panelList
component. You would not need the panelCollection
component (as that is used only for tables), so you might also think you would not need to use the panelGroupLayout
component to group the panelList
component with another component. However, because the panelList
component would then be a direct child of the panelSplitter
component, and because the panelSplitter
component stretches its child components and the panelList
component cannot be stretched, you would need to keep the panelGroupLayout
(set to scroll
) and place the panelList
component as a child to the panelGroupLayout
component.
This way, the panelSplitter
component can stretch the panelGroupLayout
component, but the panelGroupLayout
component will not try to stretch the panelList
component. Because the panelGroupLayout
component can be stretched, but does not stretch its child components, it allows the transition between a layout that stretches and one that flows.
Components that can be stretched but do not stretch their children are considered transition components. Transition components must always be used between a component that stretches its children and a component that does not stretch.
When you use the New Gallery Wizard to create a JSF JSP page (or a page fragment), you can choose from a variety of predefined quick start layouts. When you choose one of these layouts, JDeveloper adds the necessary components and sets their attributes to achieve the look and behavior you want. You can choose from one-, two-, and three-column formats. Within those formats, you can choose how many separate panes will be displayed in each column, and if those panes can stretch or remain a fixed size. Figure 8-5 shows the different layouts available in the two-column format.
Along with adding layout components, you can also choose to apply a theme to the chosen quick layout. These themes add color styling to some of the components used in the quick start layout. To see the color and where it is added, see Appendix D, "Quick Start Layout Themes." For more information about themes, see Section 20.3.4, "How to Apply Themes to Components."
In addition to saving time, when you use the quick layouts, you can be sure that layout components are used together correctly to achieve the desired outcome. For more information about creating pages using the quick layouts, see Section 2.4, "Creating a View Page."
To ensure your page is displayed as expected in all browsers, use one of the quick layouts provided by JDeveloper when you create a page. These ensure that the correct components are used and configured properly. For more information, see Section 8.2.3, "Using Quick Start Layouts."
However, if you wish to create your layout yourself, follow these tips for creating a layout that includes both stretched and flowing components:
Place the page contents inside a root component that performs geometry management, either panelStretchLayout
, panelSplitter
, panelAccordion
with a showDetailItem
, or panelTabbed
with a showDetailItem
.
Never specify a height value with percent units. Instead, build a component structure out of components that support being stretched and that stretch their child components.
Inside this stretchable structure, create islands of nonstretched or flowing components by using transition components, such as the panelGroupLayout
component with the layout
attribute set to scroll
. This component will provide the transition between stretched and flowing components because it supports being stretched but will not stretch its child components.
Never try to stretch something vertically inside a nonstretched or flowing container because it will not act consistently across web browsers.
For components contained in a parent flowing component (that is, a component that does not stretch its children), do not set widths greater than 95%. If you do, you may get unexpected results.
If the parent component is 768 pixels or greater, set the styleClass
attribute on the component to be stretched to AFStretchWidth
. This style will stretch the component to what appears to be 100% of the parent container, taking into account different browsers and any padding or borders on the parent.
If the parent component is 768 pixels or less, set the styleClass
attribute on the component to be stretched to AFAuxiliaryStretchWidth
. This style will stretch the component to what appears to be 100% of the parent container, taking into account different browsers and any padding or borders on the parent.
Note:
The two different styles are needed due to how Microsoft Internet Explorer 7 computes widths inside scrolling containers (this has been resolved in Internet Explorer 8). Unless you can control the version of browser used to access your application, you should use these styles as described.Never use the position
style.
Ensure that the maximized
attribute on the document
tag is set to true
(this is the default). For more information about setting the attribute, see Section 8.2.5, "How to Configure the document Tag."
The remainder of this chapter describes the ADF Faces layout components and how they can be used to design a page. You can find information about how each component handles stretching in the respective "What You May Need to Know About Geometry Management" sections.
The document
tag contains a number of attributes that you can configure to control behavior for the page. For example, you can configure the tag so that one component has focus when the page is first rendered. You can also configure the tag to display a warning message if a user attempts to navigate off the page and the data has not been submitted. You can also set the document to use a different state saving method than the rest of the application.
To configure the document tag:
In the Structure window, select the af:document node.
In the Property Inspector, expand the Common section and set the following:
InitialFocusId: Use the dropdown menu to choose Edit. In the Edit Property dialog, select the component that should have focus when the page first renders.
Because this focus happens on the client, the component you select must have a corresponding client component. For more information, see Section 3.4, "Instantiating Client-Side Components."
Maximized: Set to true
if you want the root component to expand to fit all available browser space. When the document
tag's maximized
attribute is set to true
, the framework searches for a single visual root component, and stretches that component to consume the browser's viewable area, provided that the component can be stretched. Examples of components that support this are panelStretchLayout
and panelSplitter
. The document
tag's maximized
attribute is set to true
by default. For more information, see Section 8.2.1, "Geometry Management and Component Stretching."
Title: Enter the text that should be displayed in the title bar of the browser.
Expand the Appearance section and for the FailedConnectionText attribute, enter the text you want to be displayed if a connection cannot be made to the server.
Expand the Other section and set the following:
UncommitedDataWarning: Set to on
if you want a warning message displayed to the user when the application detects that data has not been committed. This can happen because either the user attempts to leave the page without committing data or there is uncommitted data on the server. By default, this is set to off
.
StateSaving: Set to the type of state saving you want to use for a page.
For ADF Faces applications, it is recommended to have the application use client state saving with tokens, which saves page state to the session and persists a token to the client. This setting affects the application globally, such that all pages have state saved to the session and persist tokens with information regarding state.
However, there may be a page for which you which you want the state saved differently. For example, when a user posts back to a login page after an extended period of time, you do not want the session time out error to be displayed. By changing the stateSaving
attribute on the page to client
, then when the user posts back to the login page, the time out error will not display.
You can override the global setting in web.xml
to one of the following for the page:
client: The state is saved fully to the client, without the use of tokens. This setting keeps the session expired messages from being displayed.
default: The state of the page is based on whatever is set in web.xml
.
server: The state of the page is saved on the server.
For more information about state saving, see Appendix A, "Configuration in web.xml."
Use the panelStretchLayout
component to arrange content in defined areas on a page and when you want the content to be able to stretch when the browser is resized. The panelStretchLayout
component is one of the components that can stretch components placed in its facets. Figure 8-6 shows the component's facets.
Note:
Figure 8-6 shows the facets when the language reading direction of the application is configured to be left-to-right. If instead the language direction is right-to-left, thestart
and end
facets are switched.When you set the height of the top
and bottom
facets, any contained components are stretched up to fit the height. Similarly, when you set the width of the start
and end
facets, any components contained in those facets are stretched to that width. If no components are placed in the facets, then that facet does not render. That is, that facet will not take up any space. If you want that facet to take up the set space but remain blank, insert a spacer component. See Section 8.13, "Separating Content Using Blank Space or Lines." Child Components components in the center
facet are then stretched to fill up any remaining space. For more information about component stretching, see Section 8.2.1, "Geometry Management and Component Stretching."
Instead of setting the height of the top or bottom facet, or width of the start or end facet to a dimension, you can set the height or width to auto
. This allows the facet to size itself to use exactly the space required by the child components of the facet. Space will be allocated based on what the web browser determines is the required amount of space to display the facet content.
Performance Tip:
Usingauto
as a value will degrade performance of your page. You should first attempt to set a height or width and use the auto
attribute sparingly.The File Explorer application uses a panelStretchLayout
component as the root component in the template. Child components are placed only in the center
and bottom
facets. Therefore, whatever is in the center
facet stretches the full width of the window, and from the top of the window to the top of the bottom
facet, whose height is determined by the bottomHeight
attribute. Example 8-2 shows abbreviated code from the fileExplorerTemplate
file.
Example 8-2 panelStretchLayout in the File Explorer's Template File
<af:panelStretchLayout bottomHeight="#{attrs.footerGlobalSize}"> <f:facet name="center"> <af:panelSplitter orientation="vertical" ...> . . . </af:panelSplitter </f:facet> <f:facet name="bottom"> <af:panelGroupLayout layout="vertical"> . . . </af:panelGroupLayout> </f:facet> </af:panelStretchLayout>
The template uses an EL expression to determine the value of the bottomHeight
attribute. This expression resolves to the value of the footerGlobalSize
attribute defined in the template, which by default is 0
. Any page that uses the template can override this value. For example, the index.jspx
page uses this template and sets the value to 30
. Therefore, when the File Explorer application renders, the contents in the panelStretchLayout
component begin 30 pixels from the bottom of the page.
The panelStretchLayout
component cannot have any direct child components. Instead, you place components within its facets. The panelStretchLayout
is one of the components that can be configured to stretch any components in its facets to fit the browser. You can nest panelStretchLayout
components. For more information, see Section 8.2.2, "Nesting Components Inside Components That Allow Stretching."
To create and use the panelStretchLayout component:
In the Component Palette, from the Layout panel, drag and drop a Panel Stretch Layout to the JSF page.
In the Property Inspector, expand the Common section and set the attributes as needed.
When there are child components in the top
, bottom
, start
, and end
facets, these components occupy space that is defined by the topHeight
, bottomHeight
, startWidth
, and endWidth
attributes. For example, topHeight
attribute specifies the height of the top
facet, and startWidth
attribute specifies the width of the start
facet. Child components in top
and bottom
facets are stretched up to the height set by topHeight
and bottomHeight
attributes, respectively, and child components in start
and end
facets are stretched up to the width set by startWidth
and endWidth
attributes, respectively. Instead of setting a numeric dimension, you can set the topHeight
, bottomHeight
, startWidth
and endWidth
attributes to auto
and the browser will determine the amount of space required to display the content in the facets.
Note:
If you set a facet to useauto
as a value for the width or height of that facet, the child component does not have to be able to stretch. In fact, it must use a stable, standalone width that is not dependent upon the width of the facet.
For example, you should not use auto
on a facet whose child component can stretch their children automatically. These components have their own built-in stretched widths by default which will then cause them to report an unstable offsetWidth
value, which is used by the browser to determine the amount of space.
Additionally, you should not use auto
in conjunction with a child component that uses a percentage length for its width. The facet content cannot rely on percentage widths or be any component that would naturally consume the entire width of its surrounding container.
If you do not explicitly specify a value, by default, the value for the topHeight
, bottomHeight
, startWidth
, and endWidth
attributes is 50 pixels each. The widths of the top
and bottom
facets, and the heights of the start
and end
facets are derived from the width and height of the parent component of panelStretchLayout
.
Tip:
If a facet does not contain a child component, it is not rendered and therefore does not take up any space. You must place a child component into a facet in order for that facet to occupy the configured space.By default, the panelStretchLayout
component stretches to fill available browser space. If you want to place the panelStretchLayout
component inside a component that does not stretch its children, then you need to configure the panelStretchLayout
component to not stretch.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
children
: Instead of stretching, the panelStretchLayout
component will get its dimensions from its child component.
Note:
If you use this setting, you cannot use a percentage to set the height of thetop
and bottom
facets. If you do, those facets will try to get their dimensions from the size of this panelStretchLayout
component, which will not be possible, as the panelStretchLayout
component will be getting its height from its contents, resulting in a circular dependency If a percentage is used for either facet, it will be disregarded and the default 50px
will be used instead.
Additionally, you cannot set the height of the panelStretchLayout
component (for example through the inlineStyle
or styleClass
attributes) if you use this setting. Doing so would cause conflict between the panelStretchLayout
height and the child component height.
parent
: the size of the panelStretchLayout
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container (that is, the panelStretchLayout
component will stretch).
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the panelStretchLayout
component allows stretching of its child, then the panelStretchLayout
component will stretch to fill the parent. If the parent does not stretch its children then the size of the panelStretchLayout
component will be based on the size of its child component.
To place content in the component, drag and drop the desired component into any of the facets. If you want the child component to stretch, it must be a component that supports being stretched. See Section 8.3.2, "What You May Need to Know About Geometry Management and the panelStretchLayout Component," for more details.
Because facets accept one child only, if you want to add more than one child component, wrap the child components inside a container component, for example, a panelGroupLayout
component. This component must also be able to be stretched in order for all contained components to stretch.
The panelStretchLayout
component can stretch its child components and it can also be stretched. The following components can be stretched inside the facets of the panelStretchLayout
component:
inputText
(when configured to stretch)
decorativeBox
(when configured to stretch)
panelAccordion
(when configured to stretch)
panelBox
panelCollection
panelDashboard
(when configured to stretch)
panelGroupLayout
(only with the layout
attribute set to scroll
or vertical
)
panelSplitter
(when configured to stretch)
panelStretchLayout
(when configured to stretch)
panelTabbed
(when configured to stretch)
region
table
(when configured to stretch)
tree
(when configured to stretch)
treeTable
(when configured to stretch)
The following components cannot be stretched when placed inside a facet of the panelStretchLayout
component:
panelBorderLayout
panelFormLayout
panelGroupLayout
(only with the layout
attribute set to default
or horizontal
)
panelHeader
panelLabelAndMessage
panelList
showDetail
showDetailHeader
tableLayout
(MyFaces Trinidad component)
You cannot place components that cannot stretch into facets of a component that stretches its child components. Therefore, if you need to place a component that cannot be stretched into a facet of the panelStretchLayout
component, wrap that component in a transition component that can stretch.
For example, if you want to place content in a panelBox
component (which does not stretch) within a facet of the panelStretchLayout
component, you could place a panelGroupLayout
component with its layout
attribute set to scroll
in a facet of the panelStretchLayout
component, and then place the panelBox
component in that panelGroupLayout
component. For more information, see Section 8.2.2, "Nesting Components Inside Components That Allow Stretching."
When you have groups of unique content to present to users, consider using the panelSplitter
component to provide multiple panes separated by adjustable splitters. The File Explorer uses a panelSplitter
to separate the navigation tree from the folder contents, as shown in Figure 8-7. Users can change the size of the panes by dragging the splitter, and can also collapse and restore the panel that displays the directories. When a panel is collapsed, the panel contents are hidden; when a panel is restored, the contents are displayed.
The panelSplitter
component lets you organize contents into two panes separated by an adjustable splitter. The panes can either line up on a horizontal line (as does the splitter shown in Figure 8-7) or on a vertical line. The File Explorer application uses another panelSplitter
component to separate the application's header contents from the main body of the page. Figure 8-8 shows the panelSplitter
component expanded to show the header contents, which includes the Oracle logo and the File Explorer name.
Clicking the arrow button on a splitter collapses the panel that holds the header contents, and the logo and name are no longer shown, as shown in Figure 8-9.
You place components inside the facets of the panelSplitter
component. The panelSplitter
component uses geometry management to stretch its child components at runtime. This means when the user collapses one panel, the contents in the other panel are explicitly resized to fill up available space.
Note:
While the user can change the values of thesplitterPosition
and collapsed
attributes by resizing or collapsing the panes, those values will not be retained once the user leaves the page unless you configure your application to use change persistence. For information about enabling and using change persistence, see Chapter 31, "Allowing User Customization on JSF Pages."The panelSplitter
component lets you create two panes separated by a splitter. Each splitter component has two facets, namely, first
and second
, which correspond to the first panel and second panel, respectively. Child components can reside inside the facets only. To create more than two panes, you nest the panelSplitter
components.
To create and use the panelSplitter component:
In the Component Palette, from the Layout panel, drag and drop a Panel Splitter onto the JSF page.
In the Property Inspector, expand the Common section.
Set Orientation to vertical
to create two vertical panes (one on top of the other). By default, the value is horizontal
, which means horizontal panes are placed left-to-right (or right-to-left, depending on the language reading direction).
Set SplitterPosition and PositionedFromEnd to determine the initial placement of the splitter. By default, the value of the splitterPosition
attribute is 200 pixels, and the positionedFromEnd
attribute is false
. This setting means that ADF Faces measures the initial position of the adjustable splitter from the start or top panel (depending on the orientation
attribute value). For example, if the orientation
attribute is set to horizontal
, the splitterPosition
attribute is 200
and the positionedFromEnd
attribute is false
(all default values), then ADF Faces places the splitter 200 pixels from the start panel, as shown in Figure 8-10.
If the positionedFromEnd
attribute is set to true
, then ADF Faces measures the initial position of the splitter from the end (or bottom panel, depending on the orientation
value). Figure 8-11 shows the position of the splitter measured 200 pixels from the end panel.
Set collapsed to determine whether or not the splitter is in a collapsed (hidden) state. By default, the collapsed
attribute is false
, which means both panes are displayed. When the user clicks the arrow button on the splitter, the collapsed
attribute is set to true
and one of the panes is hidden.
ADF Faces uses the collapsed
and positionedFromEnd
attributes to determine which panel (that is, the first or second panel) to hide (collapse) when the user clicks the arrow button on the splitter. When the collapsed
attribute is set to true
and the positionedFromEnd
attribute is false
, the first panel is hidden and the second panel stretches to fill up the available space. When the collapsed
attribute is true
and the positionedFromEnd
attribute is true
, the second panel is hidden instead. Visually, the user can know which panel will be collapsed by looking at the direction of the arrow on the button: when the user clicks the arrow button on the splitter, the panel collapses in the direction of the arrow.
By default, the panelSplitter
component stretches to fill available browser space. If you want to place the panelSplitter
into a component that does not stretch its children, then you need to change how the panelSplitter
component handles stretching.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
children
: Instead of stretching, the panelSplitter
component will get its dimensions from its child component.
Note:
If you use this setting and you set theorientation
attribute to vertical
, then the contents of the collapsible panel will not be determined by its child component, but instead will be determined by the value of splitterPosition
attribute. The size of the other pane will be determined by its child component.
Additionally, you cannot set the height of the panelSplitter
component (for example through the inlineStyle
or styleClass
attributes) if you use this setting. Doing so would cause conflict between the panelSplitter
height and the child component height.
parent
: The size of the panelSplitter
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container.
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the panelSplitter
component allows stretching of its child, then the panelSplitter
component will stretch to fill the parent. If the parent does not stretch its children then the size of the panelSplitter
component will be based on the size of its child component.
To place content in the component, drag and drop the desired component into the first
and second
facets. When you have the orientation set to horizontal, the first
facet is the left facet. When you have the orientation set to vertical, the first
facet is the top facet. If you want the child component to stretch, it must be a component that supports stretching. For more details, see Section 8.4.2, "What You May Need to Know About Geometry Management and the panelSplitter Component."
Because facets accept one child component only, if you want to add more than one child component, wrap the child components inside a container component. This component must also be able to be stretched in order for all contained components to stretch.
Tip:
If any facet is not visible in the visual editor:Right-click the panelSplitter
component in the Structure window.
From the context menu, choose Facets - Panel Splitter >facet name. Facets in use on the page are indicated by a checkmark in front of the facet name.
To create more than two panes, insert another Panel Splitter component into a facet to create nested splitter panes (as shown in Figure 8-12).
Example 8-3 shows the code generated by JDeveloper when you nest splitter components.
Example 8-3 Nested panelSplitter Components
<af:panelSplitter ...> <f:facet name="first"> <!-- first panel child components components here --> </f:facet> <f:facet name="second"> <!-- Contains nested splitter component --> <af:panelSplitter orientation="vertical" ...> <f:facet name="first"> <!-- first panel child components components here --> </f:facet> <f:facet name="second"> <!-- second panel child components components here --> </f:facet> </af:panelSplitter> </f:facet> </af:panelSplitter>
If you want to perform some operation when users collapse or expand a panel, attach a client-side JavaScript using the clientListener
tag for the collapsed
attribute and a propertyChange
event type. For more information about client-side events, see Chapter 5, "Handling Events."
The panelSplitter
component can stretch its child components and it can also be stretched. The following components can be stretched inside the first
or second
facet of the panelSplitter
component:
inputText
(when configured to stretch)
decorativeBox
(when configured to stretch)
panelAccordion
(when configured to stretch)
panelBox
panelCollection
panelDashboard
panelGroupLayout
(only with the layout
attribute set to scroll
or vertical
)
panelSplitter
(when configured to stretch)
panelStretchLayout
(when configured to stretch)
panelTabbed
(when configured to stretch)
region
table
(when configured to stretch)
tree
(when configured to stretch)
treeTable
(when configured to stretch)
The following components cannot be stretched when placed inside a facet of the panelSplitter
component:
panelBorderLayout
panelFormLayout
panelGroupLayout
(only with the layout
attribute set to default
or horizontal
)
panelHeader
panelLabelAndMessage
panelList
showDetail
showDetailHeader
tableLayout
(MyFaces Trinidad component)
You cannot place components that cannot stretch into facets of a component that stretches its child components. Therefore, if you need to place one of the components that cannot be stretched into a facet of the panelSplitter
component, wrap that component in a transition component that does not stretch its child components.
For example, if you want to place content in a panelBox
component and have it flow within a facet of the panelSplitter
component, you could place a panelGroupLayout
component with its layout attribute set to scroll
in a facet of the panelSplitter
component, and then place the panelBox
component in that panelGroupLayout
component. For more information, see Section 8.2.2, "Nesting Components Inside Components That Allow Stretching."
The panelBorderLayout
component uses facets to contain components in predefined areas of a page. Instead of a center
facet, the panelBorder
layout component takes 0
to n
direct child components (also known as indexed children), which are rendered consecutively in the center. The facets then surround the child components.
Figure 8-13 shows the facets of the panelBorderLayout
component.
The 12 supported facets of the panelBorderLayout
component are:
top
: Renders child components above the center area.
bottom
: Renders child components below the center area.
start
: Supports multiple reading directions. This facet renders child components on the left of the center area between top
and bottom
facet child components, if the reading direction of the client browser is left-to-right. If the reading direction is right-to-left, it renders child components on the right of the center area. When your application must support both reading directions, this facet ensures that the content will be displayed on the proper side when the direction changes. If you do not need to support both directions, then you should use either the left
or right
facet.
end
: Supports multiple reading directions. This facet renders child components on the right of the center area between top
and bottom
facet child components, if the reading direction of the client browser is left-to-right. If the reading direction is right-to-left, it renders child components on the left of the center area. When your application must support both reading directions, this facet ensures that the content will be displayed on the proper side when the direction changes. If you do not need to support both directions, then you should use either the left
or right
facet.
left
: Supports only one reading direction. This facet renders child components on the left of the center area between top
and bottom
facet child components. When the reading direction is left-to-right, the left
facet has precedence over the start
facet if both the left
and start
facets are used (that is, contents in the start
facet will not be displayed). If the reading direction is right-to-left, the left
facet also has precedence over the end
facet if both left
and end
facets are used.
right
: Supports only one reading direction. This facet renders child components on the right of the center area between top
and bottom
facet child components. If the reading direction is left-to-right, the right
facet has precedence over the end
facet if both right
and end
facets are used. If the reading direction is right-to-left, the right
facet also has precedence over the start
facet, if both right
and start
facets are used.
innerTop
: Renders child components above the center area but below the top
facet child components.
innerBottom
: Renders child components below the center area but above the bottom
facet child components.
innerLeft
: Renders child components similar to the left
facet, but renders between the innerTop
and innerBottom
facets, and between the left
facet and the center area.
innerRight
: Renders child components similar to the right
facet, but renders between the innerTop
facet and the innerBottom
facet, and between the right
facet and the center area.
innerStart
: Renders child components similar to the innerLeft
facet, if the reading direction is left-to-right. Renders child components similar to the innerRight
facet, if the reading direction is right-to-left.
innerEnd
: Renders child components similar to the innerRight
facet, if the reading direction is left-to-right. Renders child components similar to the innerLeft
facet, if the reading direction is right-to-left.
The panelBorderLayout
component does not support stretching its child components, nor does it stretch when placed in a component that stretches its child components. Therefore, the size of each facet is determined by the size of the component it contains. If instead you want the contents to stretch to fill the browser window, consider using the panelStretchLayout
component instead. For more information, see Section 8.3, "Arranging Contents to Stretch Across a Page."
There is no restriction to the number of panelBorderLayout
components you can have on a JSF page.
To create and use the panelBorderLayout component:
In the Component Palette, from the Layout panel, drag and drop a Panel Border Layout onto the JSF page.
From the Component Palette, drag and drop the component that will be used to display contents in the center of the window as a child component to the panelBorderLayout
component.
Child components are displayed consecutively in the order in which you inserted them. If you want some other type of layout for the child components, wrap the components inside the panelGroupLayout
component. For more information, see Section 8.12, "Grouping Related Items."
To place contents that will surround the center, drag and drop the desired component into each of the facets.
Because facets accept one child component only, if you want to add more than one child component, wrap the child components inside a container.
Tip:
If any facet is not visible in the visual editor:Right-click the panelBorderLayout
component in the Structure window.
From the context menu, choose Facets - Panel Border Layout >facet name. Facets in use on the page are indicated by a checkmark in front of the facet name.
The panelFormLayout
component lets you lay out multiple form input components such as input fields and selection list fields in one or more columns. The File Explorer application uses a panelFormLayout
component to display file properties. The component is configured to have the labels right-aligned, as shown in Figure 8-14.
Figure 8-15 shows the same page with the component configured to display the labels above the fields.
You can configure the panelFormLayout
component to display the fields with their labels in one or more columns. Each field in the form is a child component of the panelFormLayout
component. You set the desired number of rows, and if there are more child components than rows, the remaining child components are placed in a new column. For example, if there are 25 child components, and you set the component to display 15 rows, the last 10 components will be displayed in a second column.
However, the number of rows displayed in each is not solely determined by the configured number of rows. By default, the panelFormLayout
component is set to render no more than three columns (two for PDA applications). This value is what actually determines the number of rows. For example, if you have 25 child components and you set the component to display 5 rows and you leave the default maximum number of columns set to 3
, then the component will actually display 9 rows, even though you have it set to display 5. This is because the maximum number of columns can override the set number of rows. Because it is set to allow only up to 3 columns, it must use 9 rows in order to display all child components. You would need to set the maximum number of columns to 5 in order to have the component display just 5 rows.
ADF Faces uses default label and field widths, as determined by the standard HTML flow in the browser. You can also specify explicit widths to use for the labels and fields. Regardless of the number of columns in the form layout, the widths you specify apply to all labels and fields. You specify the widths using either absolute numbers in pixels or percentage values. If the length of a label does not fit, the text is wrapped.
Tip:
If your page will be displayed in languages other than English, you should leave extra space in the labels to account for different languages and characters.You can use one or more panelFormLayout
components on a page to create the desired form layout.
To create and use panelFormLayout:
In the Component Palette, from the Layout panel, drag and drop a Panel Form Layout onto the JSF page.
In the Property Inspector, expand the Common section and set the label alignment.
By default, field labels on the child input components are displayed beside the fields. To place the labels above the fields, set the labelAlignment
attribute to top
.
Note:
When you nest apanelFormLayout
component inside another panelFormLayout
component, the label alignment in the nested layout is top
.Set rows and maxColumns to determine the number of rows and columns in the form.
The rows
attribute value is the number that ADF Faces uses as the number of rows after which a new column will start. By default, it is set to 2147483647
(Integer.MAX_VALUE
). This means all the child components that are set to rendered="true"
and visible="true"
will render in one, single column.
If you want the form to contain more than one column, set the rows
attribute to a multiple of the number of rendered child components, and then set the maxColumns
attribute to the maximum amount of columns that the form should display. The default value of maxColumns
is 3
. (On PDAs, the default is 2
).
Note:
If thepanelFormLayout
component is inside another panelFormLayout
component, the inner panelFormLayout
component's maxColumns
value is always 1
.For example, if the rows
attribute is set to 6
and there are 1 to 6 rendered child components, the list will be displayed in 1 column. If there are 7 to 12 rendered child components, the list will be displayed in 2 columns. If there are 13 or more child components, the list will be displayed in 3 columns. To display all rendered child components in 1 column, set the rows
attribute back to the default value.
If the number of rendered child components would require more columns than allowed by the maxColumn
attribute, then the value of the rows
attribute is overridden. For example, if there are 100 rendered child components, and the rows
attribute is set to 30
and the maxColumns
attribute is 3
(default), the list will be displayed in 3 columns and 34 rows. If the maxColumns
attribute is set to 2
, the list will be displayed in 2 columns and 51 rows.
Tip:
Rendered child components refers only to direct child components of the form. Therefore, when a component that renders multiple rows (for exampleselectManyCheckbox
) is a child, all its rows will be treated as a single rendered child and cannot be split across separate columns.Set fieldWidth and labelWidth as needed.
ADF Faces uses default label and field widths, as determined by standard HTML flow in the browser. You can also specify explicit widths to use for the labels and fields.
The labelWidth
attribute on the panelFormLayout
component lets you set the preferred width for labels; the fieldWidth
attribute lets you set the preferred width for fields.
Note:
Any value you specify for thelabelWidth
component is ignored in layouts where the labelAlignment
attribute is set to top
, that is, in layouts where the labels are displayed above the fields.Regardless of the number of columns in the form layout, the widths you specify apply to all labels and fields, that is, you cannot set different widths for different columns. You specify the widths using any CSS unit such as em, px, or %. The unit used must be the same for both the labelWidth
and fieldWidth
attribute.
When using percentage values:
The percentage width you specify is a percent of the entire width taken up by the panelFormLayout
component, regardless of the number of columns to be displayed.
The sum of the labelWidth
and fieldWidth
percentages must add up to 100%. If the sum is less than 100%, the widths will be normalized to equal 100%. For example, if you set the labelWidth
to 10% and the fieldWidth
to 30%, at runtime the labelWidth
would be 33% and the fieldWidth
would be 67%.
If you explicitly set the width of one but not the other (for example, you specify a percentage for labelWidth
but not fieldWidth
), ADF Faces automatically calculates the percentage width that is not specified.
Note:
If your form contains multiple columns and a footer, you may see a slight offset between the positioning of the main form items and the footer items in web browsers that do not honor fractional divisions of percentages. To minimize this effect, ensure that the percentagelabelWidth
is evenly divisible by the number of columns.Suppose the width of the panelFormLayout
component takes up 600 pixels of space, and the labelWidth
attribute is set at 50
%. In a one-column display, the label width will be 300 pixels and the field width will be 300 pixels. In a two-column display, each column is 300 pixels, so each label width in a column will be 150 pixels, and each field width in a column will be 150 pixels.
If the length of the label text does not fit on a single line with the given label width, ADF Faces automatically wraps the label text. If the given field width is less than the minimum size of the child content you have placed inside the panelFormLayout
component, ADF Faces automatically uses the minimum size of the child content as the field width.
Note:
If the field is wider than the space allocated, the browser will not truncate the field but instead will take space from the label columns. This potentially could cause the labels to wrap more than you would like. In this case, you may want to consider reducing the width of the field contents (for example, use a smallercontentStyle
width on an inputText
component).Insert the desired child components.
Usually you insert labeled form input components, such as Input Text, Select Many Checkbox, and other similar components that enable users to provide input.
Tip:
ThepanelFormLayout
component also allows you to use the iterator
, switcher
, and group
components as direct child components, providing these components wrap child components that would typically be direct child components of the panelFormLayout
component.Example 8-4 shows the panelFormLayout
component as it is used on the properties.jspx
page of the File Explorer application, shown in Figure 8-14.
Example 8-4 panelFormLayout Component
<af:panelFormLayout rows="5" labelAlignment="top"> <af:inputText value="#{fileItemProperties.type}" label="#{explorerBundle['fileproperties.type']}" readOnly="true"/> <af:inputText value="#{fileItemProperties.location}" label="#{explorerBundle['fileproperties.currentpath']}" readOnly="true"/> <af:inputText value="#{fileItemProperties.size}" label="#{explorerBundle['fileproperties.size']}" readOnly="true"/> <af:inputText value="#{fileItemProperties.contains}" label="#{explorerBundle['fileproperties.contains']}" readOnly="true"/> </af:panelFormLayout>
Tip:
If you use non-input components (which do not havelabel
attributes) or if you want to group several input components with one single label inside a panelFormLayout
component, first wrap the components inside a panelLabelAndMessage
component. For information about using the panelLabelAndMessage
component, see Section 17.4, "Grouping Components with a Single Label and Message."To group semantically related input components in a form layout, use the group
component to wrap those components that belong in a group. Components placed within a group will cause the panelFormLayout
component to draw a separator line above and below the group.
For more information about using the group
component, see Section 8.6.2, "What You May Need to Know About Using the group Component with the panelFormLayout Component."
To add content below the child input components, insert the desired component into the footer
facet.
Facets accept only one child component. If you have to insert more than one component in the footer
facet, use the panelGroupLayout
component or the group
component to wrap the footer
child components. Example 8-5 shows sample code that uses the panelGroupLayout
component to arrange footer
child components in a panelFormLayout
component.
Example 8-5 Footer Child Components in panelFormLayout Arranged Horizontally
<af:panelFormLayout> <f:facet name="footer"> <af:panelGroupLayout layout="horizontal"> <af:commandButton text="Save"/> <af:commandButton text="Cancel"/> <f:facet name="separator"> <af:spacer width="3" height="3"/> </f:facet> </af:panelGroupLayout> </f:facet> . . . </af:panelFormLayout>
While the group
component itself does not render anything, when it used as a child in the panelFormLayout
component, visible separators are displayed around the child components of each group
component. For example, you might want to group some of the input fields in a form layout created by the panelFormLayout
component. Example 8-15 shows sample code that groups two sets of child components inside a panelFormLayout
component.
Example 8-6 Grouping Child Components in panelFormLayout
<af:panelFormLayout binding="#{editor.component}" rows="10" labelWidth="33%" fieldWidth="67%" testId="panelFormLayout1"> <af:inputText columns="5" label="label 1"/> <af:group> <af:inputText columns="5" label="grouped 1" shortDesc="This one is secret!" secret="true"/> <af:inputText columns="5" label="grouped 2"/> <af:inputText columns="5" label="grouped 3"/> </af:group> <af:inputDate id="df1" label="label 2"/> <af:panelLabelAndMessage label="label 3" labelStyle="vertical-align: middle;"> <af:commandButton text="Submit"/> </af:panelLabelAndMessage> <af:selectOneListbox id="sol" label="label 4" shortDesc="Select One Option"> <af:selectItem label="option 1"/> <af:selectItem label="option 2"/> <af:selectItem label="option 3"/> <af:selectItem label="option 4"/> </af:selectOneListbox> <af:selectManyListbox id="rs" label="label 5" shortDesc="Select Option"> <af:selectItem label="option 1"/> <af:selectItem label="option 2"/> <af:selectItem label="option 3"/> <af:selectItem label="option 4"/>oiiiik, </af:selectManyListbox> </af:panelFormLayout>
Following along with the sample code in Example 8-15, at runtime the panelFormLayout
component renders dotted, separator lines before and after the first group
of child components, as shown in Figure 8-16.
As described in Section 8.6, "Arranging Content in Forms," the panelFormLayout
component uses certain component attributes to determine how to display its child components (grouped and ungrouped) in columns and rows. When using the group
component to group related components in a panelFormLayout
component that will display its child components in more than one column, the child components of any group
component will always be displayed in the same column, that is, child components inside a group
component will never be split across a column.
While the group
component does not provide any layout for its child components, the underlying HTML elements can provide the desired layout for the child components inside the group
component. For example, if you want child button components in a group
component to flow horizontally in a form layout, use the panelGroupLayout
component to wrap the buttons, and set the layout
attribute on panelGroupLayout
component to horizontal
. Then insert the panelGroupLayout
component into group
component, as shown in Example 8-7.
Example 8-7 panelGroupLayout Inside a Group Component
<af:group> <af:panelGroupLayout layout="horizontal"> <af:commandButton text="Save" ../> <af:commandButton text="Cancel" ../> <f:facet name="separator"> <af:spacer width="3"/> </f:facet> </af:panelGroupLayout> </af:group>
When you use the group
component to group child components in the footer
facet of the panelFormLayout
component, you must place all the group
components and other ungrouped child components in one root group
component, as shown in Example 8-8.
Example 8-8 footer Facet in panelFormLayout with One Root group Component
<af:panelFormLayout ...> <f:facet name="footer"> <!-- One root group component needed --> <af:group> <af:outputText value="Footer item 1"/> <!-- One group --> <af:group> <af:outputText value="Group 1 item 1"/> <af:outputText value="Group 1 item 2"/> </af:group> <af:panelGroupLayout layout="horizontal"> <af:commandButton text="Save"/> <af:commandButton text="Cancel"/> <f:facet name="separator"> <af:spacer width="3"/> </f:facet> </af:panelGroupLayout> </af:group> </f:facet> . . . </af:panelFormLayout>
Like grouped child components in a panelFormLayout
component, at runtime the panelFormLayout
component renders dotted, separator lines around the child components of each group
component in the footer
facet, as shown in Figure 8-17.
Note:
Thefooter
facet in the panelFormLayout
component supports only two levels of grouped components, that is, you cannot have three or more levels of nested group
components in the footer
facet. For example, the following code is not valid:
<f:facet name="footer"> <!-- Only one root group --> <af:group> <af:outputText value="Footer item 1"/> <!-- Any number of groups at this level --> <af:group> <af:outputText value="Group 1 item 1"/> <af:outputText value="Group 1 item 2"/> <!-- But not another nested group. This is illegal. --> <af:group> <af:outputText value="Nested Group 1 item 1"/> <af:outputText value="Nested Group 1 item 2"/> </af:group> </af:group> <af:outputText value="Another footer item"/> </af:group> </f:facet>
Whether you are grouping components in the footer
facet or in the main body of the panelFormLayout
component, if the first or last child inside the panelFormLayout
component or inside the footer
facet is a group
component, no separator lines will be displayed around the child components in that group. For example, both sets of code examples in Example 8-9 would produce the same visual effect at runtime.
Example 8-9 Code Producing Same Visual Effect
<!-- Example 1: Group of buttons is last child in root group --> <f:facet name="footer"> <af:group> <af:outputText value="Footer text item 1"/> <af:outputText value="Footer text item 2"/> <af:group> <af:inputText label="Nested group item 1"/> <af:inputText label="Nested group item 2"/> </af:group> <af:group> <af:panelGroupLayout layout="horizontal"> <af:commandButton text="Cancel"/> <af:commandButton text="Save"/> </af:panelGroupLayout> </af:group> </af:group> </f:facet> <!-- Example 2: panelGroupLayout of buttons is last child in root group--> <f:facet name="footer"> <af:group> <af:outputText value="Footer text item 1"/> <af:outputText value="Footer text item 2"/> <af:group> <af:inputText label="Nested group item 1"/> <af:inputText label="Nested group item 2"/> </af:group> <af:panelGroupLayout layout="horizontal"> <af:commandButton text="Cancel"/> <af:commandButton text="Save"/> </af:panelGroupLayout> </af:group> </f:facet>
The panelDashboard
component allows you to arrange its child components in rows and columns, similar to the panelForm
component. However, instead of text components, the panelDashboard
children are panelBox
components that contain content, as shown in Figure 8-18.
When you add a panelDashboard
component, you configure the number of columns it will contain, along with the height of each row. The dashboard stretches its children to fill up the configured space. If all the child components do not fit within the specified number of columns and row height, then the panelDashboard
component displays a scroll bar.
When placed in a component that stretches it children, by default, the panelDashboard
stretches to fill its parent container, no matter the number of children. This could mean that you may have blank space in the dashboard when the browser is resized to be much larger than the dashboard needs.
For example, say you have set the panelDashboard
to inherit its size from its parent by setting the dimensionsFrom
attribute to parent
. You set columns to 1 and the rowHeight
to 50px
. You then add two panelBox
components. Because columns
is set to 1, you will have 2 rows. Because the parent component is a panelStretchLayout
, the panelDashboard
will stretch to fill the panelStretchLayout
, no matter the height of the boxes, and you end up with extra space, as shown in Figure 8-19 (the color of the dashboard has been changed to fuchsia to make it more easy to see its boundaries).
If instead you don't want the dashboard to stretch, you can place it in a component that does not stretch its children, and you can configure the panelDashboard
to determine its size based on its children (by setting the dimensionsFrom
attribute to children
). It will then be as tall as the number of rows required to display the children, multiplied by the rowHeight
attribute.
In the previous example, if instead you place the dashboard in a panelGroupLayout
set to scroll
, because the rowHeight
is set to 50
, your panelDashboard
will always be just over 100px tall, no matter the size of the browser window, as shown in Figure 8-20.
The panelDashboard
component also supports declarative drag and drop behavior, so that the user can rearrange the child components. As shown in Figure 8-21, the user can for example, move panelBox 10
between panelBox 4
and panelBox
5
. A shadow is displayed where the box can be dropped.
Note:
You can also configure drag and drop functionality that allows users to drag components into and out of thepanelDashboard
component. For more information, see Section 32.6, "Adding Drag and Drop Functionality Into and Out of a panelDashboard Component."Along with the ability to move child components, the panelDashboard
component also provides an API that you can access to allow users to switch child components from being rendered to not rendered, giving the appearance of panelBoxes
being inserted or deleted. The dashboard uses partial page rendering to redraw the new set of child components without needing to redraw the entire page.
You can use the panelDashboardBehavior
tag to make the rendering of components appear more responsive. This tag allows the activation of a command component to apply visual changes to the dashboard before the application code modifies the component tree on the server. Because this opening up of space happens before the action event is sent to the server, the user will see immediate feedback while the action listener for the command component modifies the component tree and prepares the dashboard for the optimized encoding of the insert.
For example, Figure 8-22 shows a panelDashboard
component used in the right panel of a panelSplitter
component. In the left panel, list items displayed as links represent each panelBox
component in the panelDashboard
. When all panelBox
components are displayed, the links are all inactive. However, if a user deletes one of the panelBox
components, the corresponding link becomes active. The user can click the link to reinsert the panelBox
. By using the panelDashboardBehavior
tag with the commandLink
component, the user sees the inserted box drawing.
If you decide not to use this tag, there will be a slight delay while your action listener is processing before the user sees any change to the dashboard structure.
Figure 8-23 shows a practical example using a panelDashboard
component. Selecting one of the links at the top of the page changes the panelBoxes
displayed in the dashboard. The user can also add panelBoxes
by clicking the associated link on the left-hand side of the page.
After you add a panelDashboard
to a page, you can configure the dashboard to determine whether or not it will stretch. Then, add child components, and if you want to allow rearrangement the components, also add a componentDragSource
tag to the child component. If you want to allow insertion and deletion of components, implement a listener to handle the action. You can also use the panelDashboardBehavior
tag to make the panelDashboard
component appear more responsive to the insertion.
To use the panelDashboard component:
In the Component Palette, from the Layout panel drag and drop a Panel Dashboard onto the page.
In the Property Inspector, expand the Common section.
Set columns to the number of columns you want to use to display the child components. The child components will stretch to fit each column.
Set RowHeight to the number of pixels high that each row should be. The child components will stretch to this height.
By default, the panelDashboard
component stretches to fill available browser space. If instead, you want to use the panelDashboard
component as a child to a component that does not stretch its children, then you need to change how the panelDashboard
component handles stretching.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
children
: the panelDashboard
component will get its dimensions from its child components.
Note:
If you use this setting, you cannot set the height of thepanelDashboard
component (for example through the inlineStyle
or styleClass
attributes). Doing so would cause conflict between the panelDashboard
height and the child component height.parent
: the size of the panelDashboard
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container.
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the panelDashboard
component allows stretching of its child, then the panelDashboard
component will stretch to fill the parent. If the parent does not stretch its children then the size of the panelDashboard
component will be based on the size of its child component.
From the Component Palette, drag and drop child panelBox
components.
Tip:
ThepanelDashboard
component also supports the region
component as a child component.If you want users to be able to reorder the child components, in the Component Palette, from the Operations panel, drag and drop a Component Drag Source as a child to each of the child components.
If you want to be able to add and delete components, create a managed bean and implement a handler method that will handle reordering children when a child is added or dropped. This event is considered a drop event, so you must use the Drag and Drop framework. For more information about creating a handler for a drop event, see Chapter 32, "Adding Drag and Drop Functionality."
To use the optimized lifecycle, have the handler call the panelDashboard
component's prepareOptimizedEncodingOfInsertedChild()
method, which causes the dashboard to send just the inserted child component to be rendered.
Note:
If you plan on using thepanelDashboardBehavior
tag, then this API should be called from the associated command component's actionListener
handler.If you have added a componentDragSource
tag in Step 7, then you must also implement a DropEvent
handler for the panelDashboard
. With the panelDashboard
component selected, expand the Behavior section and bind the DropListener
attribute to that handler method.
If you wish to use a panelDashboardBehavior
tag, drag and drop a command component that will be used to initiate the insertion.
In the Property Inspector, bind the ActionListener for the command component to a handler on a managed bean that will handle the changes to the component tree. Have the handler call the panelDashboard
component's prepareOptimizedEncodingOfInsertedChild()
method, which causes the dashboard to send just the inserted child component to be rendered. Example 8-10 shows code on a managed bean that handles the insertion of child components.
Example 8-10 Action Listener Code for Insert Button
public void handleInsert(ActionEvent e) { UIComponent eventComponent = e.getComponent(); String panelBoxId = eventComponent.getAttributes().get("panelBoxId").toString(); UIComponent panelBox = _dashboard.findComponent(panelBoxId); // Make this panelBox rendered: panelBox.setRendered(true); // Becaue the dashboard is already shown, perform an optimized // render so the whole dashboard does not have to be re-encoded: int insertIndex = 0; List<UIComponent> children = _dashboard.getChildren(); for (UIComponent child : children) { if (child.equals(panelBox)) { // Let the dashboard know that only the one child component should be // encoded during the render phase: _dashboard.prepareOptimizedEncodingOfInsertedChild( FacesContext.getCurrentInstance(), insertIndex); break; } if (child.isRendered()) { // Count only rendered children because that is all that the // panelDashboard can see: insertIndex++; } } // Add the side bar as a partial target because we need to // redraw the state of the side bar item that corresponds to the inserted item: RequestContext rc = RequestContext.getCurrentInstance(); rc.addPartialTarget(_sideBar); }
In the Component Palette, from the Operations panel, drag a Panel Dashboard Behavior tag and drop it as a child to the command component.
In the Property Inspector, enter the following:
for: Enter the ID for the associated panelDashboard
component
index: Enter an EL expression that resolves to a method that determines the index of the component to be inserted. When you use the panelDashboardBehavior
tag, a placeholder element is inserted into the DOM tree where the actual component will be rendered once it is returned from the server. Because the insertion placeholder gets added before the insertion occurs on the server, you must specify the location where you are planning to insert the child component so that if the user reloads the page, the children will continue to remain displayed in the same order.
This component organizes its children into a grid based on the number of columns and the rowHeight
attribute. The child components that can be stretched inside of the panelDashboard
include:
inputText
(when the rows
attribute is set to greater than one, and the simple
attribute is set to true
)
panelBox
region
table
(when configured to stretch)
If you try to put any other component as a child component to the panelDashboard
component, then the component hierarchy is not valid.
Sometimes you want users to have the choice of displaying or hiding content. When you do not need to show all the functionality of the user interface at once, you can save a lot of space by using components that enable users to show and hide parts of the interface at will.
The showDetail
component creates a label with a toggle icon that allows users to disclose (show) or undisclose (hide) contents under the label. When the contents are undisclosed (hidden), the default label is Show and the toggle icon is a plus sign in a box. When the contents are disclosed (shown), the default label is Hide, and the toggle icon changes to a minus sign.
For example, the newFileItem
page of the File Explorer application uses a showDetail
component to hide and display file properties. The component is configured to hide the properties when the page is displayed, as shown in Figure 8-24.
When the user clicks the toggle icon, the properties are displayed, as shown in Figure 8-25.
If you want to use something more complex than an outputText component to display the disclosed and undisclosed text, you can add components to the showDetail
component's prompt
facet. When set to be visible, any contents in the prompt facet will replace the disclosed and undisclosed text values. To use the showDetail
component, see Section 8.8.1, "How to Use the showDetail Component."
Like the showDetail
component, the showDetailHeader
component also toggles the display of contents, but the showDetailHeader
component provides the label and toggle icon in a header, and also provides facets for a menu bar, toolbar, and text.
Tip:
TheshowDetailHeader
component is the same as a panelHeader
component, except that it handles disclosure events. For more information about the panelHeader
component, see Section 8.10, "Displaying Items in a Static Box."When there is not enough space to display everything in all the facets of the title line, the showDetailHeader
text is truncated and displays an ellipsis. When the user hovers over the truncated text, the full text is displayed in a tooltip, as shown in Figure 8-26.
When there is more than enough room to display the contents, the extra space is placed between the context
facet and the toolbar, as shown in Figure 8-27.
Additionally, you can configure the showDetailHeader
component to be used as a message for errors, warnings, information, or confirmations. The contents are hidden or displayed below the header. For example, the newFileItem
page of the File Explorer application uses a showDetailHeader
component to display help for creating a new file. By default, the help is not displayed, as shown in Figure 8-25. When the user clicks the toggle icon in the header, the contents are displayed, as shown in Figure 8-28.
You can also use the showDetailHeader
component in conjunction with the panelHeader
component to divide a page into sections and subsections, where some contents can be hidden. The showDetailHeader
component contains a number of facets, such as a toolbar and menu bar facet. These facets are the same as for the panelHeader
component. For more information about the panelHeader
component, see Section 8.10, "Displaying Items in a Static Box."
You can nest showDetailHeader
components to create a hierarchy of content. Each nested component takes on a different heading style to denote the hierarchy. Figure 8-29 shows three nested showDetailHeader
components, and their different styles.
You can change the styles used by each header level by applying a skin to the showDetailHeader
component. For details about skinning ADF Faces components, see Chapter 20, "Customizing the Appearance Using Styles and Skins."
Note:
While you can force the style of the text using thesize
attribute, (where 0 is the largest text), the value of the size
attribute will not affect the hierarchy. It only affects the style of the text.Use the panelBox
component when you want information to be able to be displayed or hidden below the header, and you want the box to be offset from other information on the page. The File Explorer application uses two panelBox
components on the properties.jspx
page to display the attributes and history of a file, as shown in Figure 8-30.
Figure 8-31 shows the same page, but with the History panelBox
component in an undisclosed state.
You can set the background color on a panelBox
component so that the contents are further delineated from the rest of the page. Two color combinations (called ramps) are offered, and each combination contains four levels of color: none, light, medium, and dark. Figure 8-32 shows the same panel boxes as in Figure 8-30, but with the bottom panelBox
component configured to show the medium tone of the core ramp.
You can set the size of a panelBox
component either explicitly by assigning a pixel size, or as a percentage of its parent. You can also set the alignment of the title, and add an icon. In addition, the panelBox
component includes the toolbar
facet that allows you to add a toolbar and toolbar buttons to the box.
If you want to show and hide multiple large areas of content, consider using the panelAccordion
and panelTabbed
components. For more information, see Section 8.9, "Displaying or Hiding Contents in Accordion Panels and Tabbed Panels."
Use the showDetail
component to show and hide a single set of content.
To create and use the showDetail component:
In the Component Palette, from the Common Components panel, drag and drop a Show Detail from the Component Palette onto the JSF page.
Tip:
This component appears in the Common Components panel of the Component Palette, and not the Layout panel.In the Property Inspector, expand the Common section and set the attributes as needed.
Set Disclosed to true
if you want the component to show its child components.
Note:
While the user can change the value of thedisclosed
attribute by displaying and hiding the contents, the value will not be retained once the user leaves the page unless you configure your application to allow user customizations. For information, see Chapter 31, "Allowing User Customization on JSF Pages."Set DisclosedText to the label you want to display next to the toggle icon when the contents are disclosed (shown). By default, the label is Hide if no value is specified.
Set UndisclosedText to the label you want to display next to the toggle icon when the contents are undisclosed (hidden). By default, the label is Show if no value is specified.
Note:
If you specify a value fordisclosedText
but not for undisclosedText
, then ADF Faces automatically uses the disclosedText
value for both the disclosed state and undisclosed state. Similarly, if you specify a value for undisclosedText
but not for disclosedText
, the undisclosedText
value is used when the contents are hidden or displayed.
Instead of using text specified in disclosedText
and undisclosedText
, you could use the prompt
facet to add a component that will render next to the toggle icon.
Expand the Behavior section and set DisclosureListener to a DisclosureListener
method in a backing bean that you want to execute when the user displays or hides the component's contents.
For information about disclosure events and listeners, see Section 8.8.4, "What You May Need to Know About Disclosure Events."
To add content, insert the desired child components inside the showDetail
component.
Use the showDetailHeader
component when you want to display a single set of content under a header, or when you want the content to be used as messages that can be displayed or hidden. You can also use the showDetailHeader
component to create a hierarchy of headings and content when you want the content to be able to be hidden.
To create and use the showDetailHeader component:
In the Component Palette, from the Layout panel, drag and drop a Show Detail Header onto the JSF page.
In the Property Inspector, expand the Common section. Set Text to the text string you want for the section header label.
Set Icon to the URI of the image file you want to use for the section header icon. The icon image is displayed before the header label.
Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.If you are using the header to provide specific messaging information, set MessageType to one of the following values:
confirmation
: The confirmation icon (represented by a note page overlaid with a green checkmark) replaces any specified icon image.
error
: The error icon (represented by a red circle with an x inside) replaces any specified icon image. The header label also changes to red.
info
: The info icon (represented by a blue circle with an I inside) replaces any specified icon image.
warning
: The warning icon (represented by a yellow triangle with an exclamation mark inside) replaces any specified icon image.
none
: Default. No icon is displayed, unless one is specified for the icon
attribute.
Figure 8-33 shows each of the icons used for message types.
Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.Set Disclosed to true
if you want the component to show its child components.
Note:
While the user can change the value of thedisclosed
attribute by displaying and hiding the contents, the value will not be retained once the user leaves the page unless you configure your application to allow user customization. For information, see Chapter 31, "Allowing User Customization on JSF Pages."Expand the Behavior section and set DisclosureListener to a disclosureListener
method in a backing bean that you want to execute when the user displays or hides the component's contents.
For information about disclosure events and listeners, see Section 8.8.4, "What You May Need to Know About Disclosure Events."
If you want to control how the showDetailHeader
component handles geometry management, expand the Other section and set Type. Set it to flow
if you do not want the component to stretch or to stretch its children. The height of the showDetailHeader
component will be determined solely by its children. Set it to stretch
if you want it to stretch and stretch its child (will only stretch a single child component). Leave it set to the default if you want the parent component of the showDetailHeader
component to determine geometry management. For more information about geometry management, see Section 8.2.1, "Geometry Management and Component Stretching."
To add buttons or icons to the header, in the Component Palette, from the Common Components panel, drag and drop the toolbar
component into the toolbar
facet. Then add any number of commandToolbarButton
or commandButton
components into the newly inserted toolbar
component. For more information about using the toolbar
component, see Section 14.3, "Using Toolbars."
Note:
Toolbar overflow is not supported inpanelHeader
components.To add menus to the header, insert menu components into the menuBar
facet. For more information about creating menus, see Section 14.2, "Using Menus in a Menu Bar."
Tip:
You can place menus in thetoolbar
facet and toolbars (and toolboxes) in the menu
facet. The main difference between these facets is location. The toolbar
facet is before the menu
facet.To create a subsection header, insert another showDetailHeader
component inside an existing showDetailHeader
component.
The size
attribute specifies the number to use for the header level. The largest number is 0
, and it corresponds to an H1 header level; the smallest is 5
, and it corresponds to an H6 header.
By default, the size
attribute is -1
. This means ADF Faces automatically calculates the header number (and thus the header level style to use) from the topmost, parent component. When you use nested components, you do not have to set the size
attribute explicitly to get the proper header style to be displayed.
Note:
While you can force the style of the text using thesize
attribute, (where 0 is the largest text), the value of the size
attribute will not affect the hierarchy. It only affects the style of the text.In the default skin used by ADF Faces, the style used for sizes above 2 will be displayed the same as size 2. That is, there is no difference in styles for sizes 3, 4, or 5–they all show the same style as size 2. You can change this by creating a custom skin. For more information, see Chapter 20, "Customizing the Appearance Using Styles and Skins."
To add content to a section or subsection, insert the desired child components inside the showDetailHeader
component.
You can insert any number of panelBox
components on a page.
To create and use a panelBox component:
In the Component Palette, from the Layout panel, drag and drop a Panel Box to the JSF page.
In the Property Inspector, expand the Appearance section, and for Ramp, select the ramp you wish to use.
The core
ramp uses variations of blue, while the highlight
ramp uses variations of yellow. You can change the colors used by creating a custom skin. For details, see Chapter 20, "Customizing the Appearance Using Styles and Skins."
Set Background to one of the following values: light
, medium
, dark
, or default
. The default background color is transparent.
Set Text to the text string you want to display as the title in the header portion of the container.
Set Icon to the URI of the icon image you want to display before the header text.
Note:
If both thetext
and icon
attributes are not set, ADF Faces does not display the header portion of the panelBox
component.Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.Set TitleHalign to one of the following values: center
, start
, end
, left
, or right
. The value determines the horizontal alignment of the title (including any icon image) in the header portion of the container.
Expand the Behavior section and set DisclosureListener to a disclosureListener
method in a backing bean that you want to execute when the user shows or hides the component's contents.
For information about disclosure events and listeners, see Section 8.8.4, "What You May Need to Know About Disclosure Events."
To add toolbar buttons, in the Component Palette, from the Common Components Panel, drag and drop a Toolbar into the toolbar
facet. Then insert the desired number of commandToolbarButton
components into the toolbar
component. For information about using toolbar
and commandToolbarButton
components, see Section 14.3, "Using Toolbars."
Tip:
If any facet is not visible in the visual editor:Right-click the panelBox
component in the Structure window.
From the context menu, choose Facets - Panel Box >Toolbar. Facets in use on the page are indicated by a checkmark in front of the facet name.
To add contents to the container for display, insert the desired components as child components to the panelBox
component.
Typically, you would insert one child component into the panelBox
component, and then insert the contents for display into the child component. The child component controls how the contents will be displayed, not the parent panelBox
component.
To change the width of the panelBox
component, set the inlineStyle
attribute to the exact pixel size you want. Alternatively, you can set the inlineStyle
attribute to a percentage of the outer element that contains the panelBox
component. Example 8-11 shows the code you might use for changing the width.
Any ADF Faces component that has built-in event functionality, as the showDetail
, showDetail
Header
, and panelBox
components do, must be enclosed in the form
component.
The disclosed
attribute on these components specifies whether to show (disclose) or hide (undisclose) the contents under its header. By default, the disclosed
attribute is true
, that is, the contents are shown. When the attribute is set to false
, the contents are hidden. You do not have to write any code to enable the toggling of contents from disclosed to undisclosed, and vice versa. ADF Faces handles the toggling automatically.
The value of the disclosed
attribute can be persisted at runtime, that is, when the user shows or hides contents, ADF Faces can change and then persist the attribute value so that it remains in that state for the length of the user's session. For more information, see Chapter 31, "Allowing User Customization on JSF Pages."
When the user clicks the toggle icon to show or hide contents, the components deliver a org.apache.myfaces.trinidad.event.DisclosureEvent
event to the server. The DisclosureEvent
event contains information about the source component and its state: whether it is disclosed (expanded) or undisclosed (collapsed). The isExpanded()
method returns a boolean
value that determines whether to expand (disclose) or collapse (undisclose) the node. If you only want the component to disclose and undisclose its contents, then you do not need to write any code.
However, if you want to perform special handling of a DisclosureEvent
event, you can bind the component's disclosureListener
attribute to a disclosureListener
method in a backing bean. The disclosureListener
method will then be invoked in response to a DisclosureEvent
event, that is, whenever the user clicks the disclosed or undisclosed icon.
The disclosureListener
method must be a public method with a single disclosureEvent
event object and a void return type, shown in Example 8-12.
Example 8-12 disclosureListener Method
public void some_disclosureListener(DisclosureEvent disclosureEvent) { // Add event handling code here }
By default, DisclosureEvent
events are usually delivered in the Invoke Application phase, unless the component's immediate
attribute is set to true
. When the immediate
attribute is set to true
, the event is delivered in the earliest possible phase, usually the Apply Request Values phase.
On the client-side component, the AdfDisclosureEvent
event is fired. The event root for the client AdfDisclosureEvent
event is set to the event source component: only the event for the panel whose disclosed
attribute is true
gets sent to the server. For more information about client-side events and event roots, see Chapter 5, "Handling Events."
When you need to display multiple areas of content that can be hidden and displayed, you can use the panelAccordion
or the panelTabbed
components. Both of these components use the showDetailItem
component to display the actual contents.
The panelAccordion
component creates a series of expandable panes. You can allow users to expand more than one panel at any time, or to expand only one panel at a time. When more than one panel is expanded, the user can adjust the height of the panel by dragging the header of the showDetailItem
component.
When a panel is collapsed, only the panel header is displayed; when a panel is expanded, the panel contents are displayed beneath the panel header (users can expand the panes by clicking either the panelAccordion
component's header or the expand icon). The File Explorer application uses the panelAccordion
component to display the Folders and Search panes, as shown in Figure 8-34.
At runtime, when available browser space is less than the space needed to display expanded panel contents, ADF Faces automatically displays overflow icons that enable users to select and navigate to those panes that are out of view. Figure 8-35 shows the overflow icon (circled in the lower right-hand corner) displayed in the Folders panel of the File Explorer application when there is not enough room to display the Search panel.
When the user clicks the overflow icon, ADF Faces displays the overflow popup menu (as shown in Figure 8-36) for the user to select and navigate to.
You can also configure the panelAccordion
so that the panes can be rearranged by dragging and dropping, as shown in Figure 8-37.
When the order is changed, the displayIndex
attribute on the showDetailItem
components also changes to reflect the new order.
Note:
Items in the overflow cannot be reordered.To use the panelAccordion
component, see Section 8.9.1, "How to Use the panelAccordion Component."
The panelTabbed
component creates a series of tabbed panes. Unlike the panelAccordion
panes, the panelTabbed
panes are not collapsible or expandable. Instead, when users select a tab, the contents of the selected tab are displayed. The tabs may be positioned above the display area, below the display area, or both. You can configure a panelTabbed
component so that the individual tabs can be closed. You can have it so that all tabs can be closed, all but the last tab can be closed, or no tabs can be closed. When tabs are configured to be closed, an X is displayed at the end of the tab. You can also configure tabs so that they display a disabled X, meaning it can be closed, but is currently disabled.
You can configure when the showDetailItem
components that contain the contents for each of the tabs will be created. When you have a small number of tabs, you can have all the showDetailItem
components created when the panelTabbed
component is first created, regardless of which tab is currently displayed. However, if the panelTabbed
component contains a large number of showDetailItem
components, the page might be slow to render. To enhance performance, you can instead configure the panelTabbed
component to create a showDetailItem
component only when its corresponding tab is selected. You can further configure the delivery method to either destroy a showDetailItem
once the user selects a different tab, or to keep any selected showDetailItem
components in the component tree so that they do not need to be recreated each time they are accessed.
The File Explorer application uses the panelTabbed
component to display the contents in the main panel, as shown in Figure 8-38.
To use the panelTabbed
component, see Section 8.9.2, "How to Use the panelTabbed Component."
Tip:
If you want the tabs to be used in conjunction with navigational hierarchy, for example, each tab is a different page or region that contains another set of navigation items, you may want to use a navigation panel component to create a navigational menu. For more information, see Section 18.5, "Using Navigation Items for a Page Hierarchy."For both the panelAccordion
and panelTabbed
components, use one showDetailItem
component to provide the contents for each panel. For example, if you want to use four panes, insert four showDetailItem
components inside the panelAccordion
or panelTabbed
components, respectively. To use the showDetailItem
component, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components." You can add a toolbar to the toolbar
facet of the showDetailItem
component, and the toolbar will be shown whenever the panel or tab is disclosed. Figure 8-38 shows the toolbar used by the showDetailItem
component in the File Explorer application.
The panelTabbed
component also supports an overflow icon if all tabs cannot be displayed. Figure 8-39 shows the overflow icon in the File Explorer application.
Performance Tip:
The number of child components within apanelAccordion
or panelTabbed
component, and the complexity of the child components, will affect the performance of the overflow. Set the size of the panelAccordion
or panelTabbed
component to avoid overflow when possible.The panelAccordion
and panelTabbed
components can be configured to be stretched, or they can be configured to instead take their dimensions from the currently disclosed showDetailItem
child.
When you configure the panelAccordion
or panelTabbed
component to stretch, then you can also configure the showDetailItem
component to stretch a single child as long as it is the only child of the showDetailItem
component.
You can use more than one panelAccordion
component in a page, typically in different areas of the page, or nested. After adding the panelAccordion
component, insert a series of showDetailItem
components to provide the panes, using one showDetailItem
for one panel. Then insert components into each showDetailItem
to provide the panel contents. For procedures on using the showDetailItem
component, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components."
To create and use the panelAccordion component:
In the Component Palette, from the Layout panel, drag and drop a Panel Accordion onto the JSF page.
In the Property Inspector, expand the Common section.
Set DiscloseMany to true
if you want users to be able to expand and see the contents of more than one panel at the same time.
By default, the value is false
. This means only one panel can be expanded at any one time. For example, suppose there is one expanded panel A and one collapsed panel B when the page first loads. If the user expands panel B, panel A will be collapsed, because only one panel can be expanded at any time.
Set the DiscloseNone to true
if you want users to be able to collapse all panes.
By default, the value is false
. This means one panel must remain expanded at any time.
If you want users to be able to rearrange the panes by dragging and dropping, expand the Other section, and set Reorder to enabled
. The default is disabled
.
Note:
If thepanelAccordion
has components other than showDetailItem
components (see the tip in Step 8), those components can be reordered on the client only. Therefore, any new order will not be preserved.By default, the panelAccordion
component stretches to fill available browser space. If instead, you want to use the panelAccordion
component as a child to a component that does not stretch its children, then you need to change how the panelAccordion
component handles stretching.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
children
: the panelAccordion
component will get its dimensions from the currently disclosed showDetailItem
component.
Note:
If you use this setting, you cannot set the height of thepanelAccordion
component (for example through the inlineStyle
or styleClass
attributes). Doing so would cause conflict between the panelAccordion
height and the child component height.
Similarly, you cannot set the stretchChildren
, flex
, and inflexibleHeight
attributes on any showDetailItem
component, as those settings would result in a circular reference back to the panelAccordion
to determine size.
parent
: the size of the panelAccordion
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container.
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the panelAccordion
component allows stretching of its child, then the panelAccordion
component will stretch to fill the parent. If the parent does not stretch its children then the size of the panelAccordion
component will be based on the size of its child component.
Note:
If you want thepanelAccordion
to stretch, and you also want the showDetailItem
to stretch its contents, then you must configure the showDetailItem
in a certain way. For details, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components."By default, all child showDetailItem
components are created when the panelTabbed
component is created. If there will be a large number of children, to improve performance you can configure the panelTabbed
either so that it creates the child showDetailItem
component only when the tab is selected, or so that it creates the child showDetailItem
component only when it's selected the first time, and from that point on it remains created.
You configure when the child components will be created using the childCreation
attribute. To do so, expand the Other section, and set ChildCreation to one of the following:
immediate
: All showDetailItem
components are created when the panelTabbed
component is created.
lazy
: The showDetailItem
component is created only when the associated tab is selected. Once a tab is selected, the showDetailItem
component remains created in the component tree.
lazyUncached
: The showDetailItem
component is created only when the associated tab is selected. Once another tab is selected, the showDetailItem
component is destroyed.
By default, one panel is added for you using a showDetailItem
component as a child component to the panelAccordion
component. To add more panes, insert the showDetailItem
component inside the panelAccordion
component. You can add as many panes as you wish.
Tip:
Accordion panels also allow you to use theiterator
, switcher
, and group
components as direct child components, providing these components wrap child components that would typically be direct child components of the accordion panel.To add contents for display in a panel, insert the desired child components into each showDetailItem
component. For procedures, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components."
Using the panelTabbed
component to create tabbed panes is similar to using the panelAccordion
component to create accordion panes. After adding a panelTabbed
component, you insert a series of showDetailItem
components to provide the tabbed panel contents for display.
To create and use the panelTabbed component:
In the Component Palette, from the Layout panel, drag and drop a Panel Tabbed onto the JSF page.
Set Position to below
if you want the tabs to be rendered below the contents in the display area.
By default, the value is above
. This means the tabs are rendered above the contents in the display area. The other acceptable value is both
, where tabs are rendered above and below the display area.
If you want users to be able to close (remove) tabs, then set TabRemoval. You can set it to allow all tabs to be removed, or all but the last tab. You must implement a handler to do the actual removal and configure the listeners for the associated showDetailItem
components. You can override this on an individual showDetail Item component, so that an individual tab cannot be removed (a close icon does not display), or so that the closed icon is disabled. For more information, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components."
By default, the panelTabbed
component stretches to fill available browser space. If instead, you want to use the panelTabbed
component as a child to a component that does not stretch its children, then you need to change how the panelTabbed
component handles stretching.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
disclosedChild
: the panelTabbed
component will get its dimensions from the currently disclosed showDetailItem
component.
Note:
If you use this setting, you cannot set the height of thepanelTabbed
component (for example through the inlineStyle
or styleClass
attributes). Doing so would cause conflict between the panelTabbed
height and the child component height.parent
: the size of the panelTabbed
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container.
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the PanelTabbed
component allows stretching of its child, then the panelTabbed
component will stretch to fill the parent. If the parent does not stretch its children then the size of the panelTabbed
component will be based on the size of its child component.
By default, one tabbed panel is created for you using a showDetailItem
component as a child to the panelTabbed
component. To add more panes, insert the showDetailItem
component inside the panelTabbed
component. You can add as many tabbed panes as you wish.
Tip:
ThepanelTabbed
component also allow you to use the iterator
, switcher
, and group
components as direct child components, providing these components wrap child components that would typically be direct child components of the panelTabbed
component.To add contents for display in a panel, insert the desired child components into each showDetailItem
component. For information about using showDetailItem
, see Section 8.9.3, "How to Use the showDetailItem Component to Display Content in panelAccordion or panelTabbed Components."
Insert showDetailItem
components into a panelAccordion
or panelTabbed
component only. Each showDetailItem
component corresponds to one accordion panel or tabbed panel. Typically, you insert two or more showDetailItem
components into the parent component. Insert the child components for display into the showDetailItem
components.
The disclosed
attribute on a showDetailItem
component specifies whether to show (disclose) or hide (undisclose) the corresponding accordion panel or tab contents. By default, the disclosed
attribute is false
, that is, the contents are hidden (undisclosed). When the attribute is set to true
, the contents are shown (disclosed). You do not have to write any code to enable the toggling of contents from disclosed to undisclosed, and vice versa. ADF Faces handles the toggling automatically.
The following procedure assumes you have already added a panelAccordion
or panelTabbed
component to the JSF page, as described in Section 8.9.1, "How to Use the panelAccordion Component," and Section 8.9.2, "How to Use the panelTabbed Component," respectively.
To add accordion panel or tabbed panel contents using a showDetailItem component:
Insert one or more showDetailItem
components inside the parent component, such as panelAccordion
or panelTabbed
, by dragging and dropping a Show Detail Item component from Common Components panel of the Component Palette.
In the Property Inspector, expand the Appearance section.
Set Text to the label you want to display for this panel or tab.
To add an icon before the label, set Icon to the URI of the image file to use.
Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.If the showDetailItem
component is being used inside a panelAccordion
component configured to stretch, you can configure the showDetailItem
to stretch and in turn stretch its contents, however, the showDetailItem
component must contain only one child component. You need to set Flex and the StretchChildren for each showDetailItem
component.
Note:
If you have set thepanelAccordion
to not stretch (that is, you've set dimensionsFrom
to children
), then you cannot set values for the flex
and stretchChildren
attributes, as it will result in a circular reference back to the panelAccordion
for size.Use the following attributes on each showDetailItem
component to control the flexibility of panel contents:
Flex: Specifies a nonnegative integer that determines how much space is distributed among the showDetailItem
components of one panelAccordion
component. By default, the value of the flex
attribute is 0
(zero), that is, the panel contents of each showDetailItem
component are inflexible. To enable flexible contents in a panel, specify a flex
number larger than 0
, for example, 1
or 2
. A larger flex
value means that the contents will be made larger than components with lower flex
values. For two flexible components, their height sizes are exactly proportionate to the flex
values assigned. If component A has flex
set to 2
and component B has flex
set to 1,
then the height of component A is two times the height of component B.
InflexibleHeight: Specifies the number of pixels a panel will use. The default is 100 pixels. This means if a panel has a flex
value of 0
(zero), ADF Faces will use 100 pixels for that panel, and then distribute the remaining space among the nonzero panes. If the contents of a panel cannot fit within the panelAccordion
container given the specified inflexibleHeight
value, ADF Faces automatically moves nearby contents into overflow menus (as shown in Figure 8-36). Also, if a panel has a nonzero flex
value, this will be the minimum height that the panel will shrink to before causing other panes to be moved into the overflow menus.
StretchChildren: When set to first
, stretches a single child component. However, the child component must allow stretching. For more information, see Section 8.9.4, "What You May Need to Know About Geometry Management and the showDetailItem Component."
For example, the File Explorer application uses showDetailItem
components to display contents in the navigator panel. Because the Search Navigator requires more space when both navigators are expanded, its flex
attribute is set to 2 and the showDetailItem
component for the Folders Navigator uses the default flex
value of 1. This setting causes the Search Navigator to be larger than the Folders Navigator when it is expanded.
Note:
Instead of directly setting the value for theflex
attribute, the File Explorer application uses an EL expression that resolves to a method used to determine the value. Using an EL expression allows you to programmatically change the value if you decide at a later point to use metadata to provide model information.The user can change the panel heights at runtime, thereby changing the value of the flex
and inflexibleHeight
attributes. Those values can be persisted so that they remain for the duration of the user's session. For information, see Chapter 31, "Allowing User Customization on JSF Pages."
Note the following additional information about flexible accordion panel contents:
There must be two or more panes (showDetailItem
components) with flex
values larger than 0
before ADF Faces can enable flexible contents. This is because ADF Faces uses the flex
ratio between two components to determine how much space to allocate among the panel contents. At runtime, two or more panes must be expanded before the effect of flexible contents can be seen.
If the showDetailItem
component has only one child component and the flex
value is nonzero, and the stretchChildren
attribute is set to first
, ADF Faces will stretch that child component regardless of the discloseMany
attribute value on the panelAccordion
component.
When all showDetailItem
components have flex
values of 0
(zero) and their panel contents are disclosed, even though the disclosed contents are set to be inflexible, ADF Faces will stretch the contents of the last disclosed showDetailItem
component as if the component had a flex
value of 1
, but only when that showDetailItem
component has one child only, and the stretchChildren
attribute is set to first
. If the last disclosed panel has more than one child component or the stretchChildren
attribute is set to none
, the contents will not be stretched.
Even with the flex
attribute set, there are some limitations regarding geometry management. For more information, see Section 8.9.4, "What You May Need to Know About Geometry Management and the showDetailItem Component."
Expand the Behavior section. Set DisclosureListener to the disclosureListener
method in a backing bean you want to execute when this panel or tab is selected by the user.
For information about server disclosure events and event listeners, see Section 8.8.4, "What You May Need to Know About Disclosure Events."
Set Disabled to true
if you want to disable this panel or tab (that is, the user will not be able to select the panel or tab).
Set Disclosed to true
if you want this panel or tab to show its child components.
By default, the disclosed
attribute is set to false
. This means the contents for this panel or tab are hidden.
Note:
Note the difference between thedisclosed
and rendered
attributes. If the rendered
attribute value is false
, it means that this accordion header bar or tab link and its corresponding contents are not available at all to the user. However, if the disclosed
attribute is set to false
, it means that the contents of the item are not currently visible, but may be made visible by the user because the accordion header bar or tab link are still visible.If none of the showDetailItem
components has the disclosed
attribute set to true
, ADF Faces automatically shows the contents of the first enabled showDetailItem
component (except when it is a child of a panelAccordion
component, which has a setting for zero disclosed panes).
Note:
While the user can change the value of thedisclosed
attribute by displaying or hiding the contents, the value will not be retained once the user leaves the page unless you configure your application to allow user customization. For information, see Chapter 31, "Allowing User Customization on JSF Pages."For showDetailItem
components used in a panelAccordion
component, expand the Other section, and set DisplayIndex to reflect the order in which the showDetailItem
components should appear. If you simply want them to appear in the order in which they are in the page's code, then leave the default, -1
.
Tip:
If someshowDetailItem
components have -1
as the value for displayIndex
, and others have a positive number, those with the -1
value will display after those with a positive number, in the order they appear in the page's code.Tip:
This value can be changed at runtime if the parentpanelAccordion
component is configured to allow reordering.If you chose to allow tab removal for a panelTabbed
component, expand the Other section and set Remove to one of the following:
inherit: The corresponding tab can be removed if the parent panelTabbed
component is configured to allow it. This is the default.
no: The corresponding tab cannot be removed, and will not display a close icon.
disabled: The corresponding tab will display a disabled close icon.
Set ItemListener to an EL expression that resolves to a handler method that will handle the actual removal of a component.
To add toolbar buttons to a panel (supported in the panelAccordion
component only), in the Component Palette, from the Common Components panel, insert a Toolbar into the toolbar
facet of the showDetailItem
component that defines that panel. Then, insert the desired number of commandToolbarButton
components into the toolbar
component. Although the toolbar
facet is on the showDetailItem
component, it is the panelAccordion
component that renders the toolbar and its buttons. For information about using toolbar
and commandToolbarButton
, see Section 14.3, "Using Toolbars."
Note:
When an accordion panel is collapsed, ADF Faces does not display the toolbar and its buttons. The toolbar and its buttons are displayed in the panel header only when the panel is expanded.To add contents to the panel, insert the desired child components into each showDetailItem
component.
Both the panelAccordion
or panelTabbed
components can be configured to stretch when they are placed inside a component that uses geometry management to stretch its child components. However, for the panelAccordion
component, the showDetailItem
component will stretch only if the discloseMany
attribute on the panelAccordion
component is set to true
(that is, when multiple panes may be expanded to show their inflexible or flexible contents), the showDetailItem
component contains only one child component, and the showDetailItem
component's stretchChildren
attribute is set to first
. By default, panel contents will not stretch.
The showDetailItem
component will allow stretching if:
It contains only a single child
Its stretchChildren
attribute is set to first
The child has no width, height, border, and padding set
The child must be capable of being stretched
When all of the preceding bullet points are true, the showDetailItem
component can stretch its child component. The following components can be stretched inside the showDetailItem
component:
inputText
(when configured to stretch)
decorativeBox
(when configured to stretch)
panelAccordion
(when configured to stretch)
panelBox
panelCollection
panelDashboard
(when configured to stretch)
panelGroupLayout
(only when the layout
attribute is set to scroll
or vertical
)
panelSplitter
(when configured to stretch)
panelStretchLayout
(when configured to stretch)
panelTabbed
(when configured to stretch)
region
table
(when configured to stretch)
tree
(when configured to stretch)
treeTable
(when configured to stretch)
The following components cannot be stretched when placed inside a showDetailItem
component:
panelBorderLayout
panelFormLayout
panelGroupLayout
(only when the layout
attribute is set to default
or horizontal
)
panelHeader
panelLabelAndMessage
panelList
tableLayout
(MyFaces Trinidad component)
You cannot place components that cannot stretch as a child to a component that stretches its child components. Therefore, if you need to place one of the components that cannot be stretched as a child of a showDetailItem
component, you need to wrap that component in different component that does not stretch its child components.
For example, if you want to place content in a panelList
component and have it be displayed in a showDetailItem
component, you might place a panelGroupLayout
component with its layout
attribute set to scroll
as the chid of the showDetailItem
component, and then place the panelList
component in that component. For more information, see Section 8.2.1, "Geometry Management and Component Stretching."
The showDetailItem
component inside of panelAccordion
and panelTabbed
components supports queuing of disclosure events so that validation is properly handled on the server and on the client.
In general, for any component with the disclosed
attribute, by default, the event root for the client AdfDisclosureEvent
is set to the event source component: only the event for the panel whose disclosed
attribute is true
gets sent to the server. However, for the showDetailItem
component that is used inside of panelTabbed
or panelAccordion
component, the event root is the panelTabbed
or panelAccordion
component (that is, the event source parent component, not the event source component). This ensures that values from the previously disclosed panel will not get sent to the server.
For example, suppose you have two showDetailItem
components inside a panelTabbed
or panelAccordion
component with the discloseMany
attribute set to false
and the discloseNone
attribute set to false
. Suppose the showDetailItem
1 component is disclosed but not showDetailItem
2. Given this scenario, the following occurs:
On the client:
When a user clicks to disclose showDetailItem
2, a client-only disclosure event gets fired to set the disclosed
attribute to false
for the showDetailItem
1 component. If this first event is not canceled, another client disclosure event gets fired to set the disclosed
attribute to true
for the showDetailItem
2 component. If this second event is not canceled, the event gets sent to the server; otherwise, there are no more disclosure changes.
On the server:
The server disclosure event is fired to set the disclosed
attribute to true
on the showDetailItem
2 component. If this first server event is not canceled, another server disclosure event gets fired to set the disclosed
attribute to false
for the showDetailItem
1 component. If neither server event is canceled, the new states get rendered, and the user will see the newly disclosed states on the client; otherwise, the client looks the same as it did before.
For the panelAccordion
component with the discloseMany
attribute set to false
and the discloseNone
attribute set to true
, the preceding information is the same only when the disclosure change forces a paired change (that is, when two disclosed states are involved). If only one disclosure change is involved, there will just be one client and one server disclosure event.
For the panelAccordion
component with the discloseMany
attribute set to true
(and any discloseNone
setting), only one disclosure change is involved; there will just be one client and one server disclosure event.
For additional information about disclosure events, see Section 8.8.4, "What You May Need to Know About Disclosure Events."
You can use the panelHeader
component when you want header type functionality, such as message display or associated help topics, but you do not have to provide the capability to show and hide content.
You can use the decorativeBox
component when you need to transition to a different look and feel on the page. The decorativeBox
component uses themes and skinning keys to control the borders and colors of its different facets. For example, depending on the skin you are using, if you use the default theme, the decorativeBox
component body is white and the border is blue, and the top-left corner is rounded. If you use the medium theme, the body is a medium blue. For information about using themes and skins, see Chapter 20, "Customizing the Appearance Using Styles and Skins"
The panelHeader
component offers facets for specific types of components and the ability to open a help topic from the header. The following are the facets supported by the panelHeader
component:
context
: Displays information in the header alongside the header text.
help
: Displays help information. Use only for backward compatibility. Use the helpTopicId
attribute on the panelHeader
component instead.
info
: Displays information beneath the header text, aligned to the right.
legend
: If help text is present, displays information to the left of the help content and under the info
facet's content. If help text is not present, the legend content will be rendered directly under the header.
toolbar
: Displays a toolbar, before the menu bar.
menuBar
: Displays a menu bar, after the toolbar.
Figure 8-40 shows the different facets in the panelHeader
component.
When there is not enough space to display everything in all the facets of the title line, the panelHeader
text is truncated and displays an ellipsis. When the user hovers over the truncated text, the full text is displayed in a tooltip, as shown in Figure 8-41.
When there is more than enough room to display the contents, the extra space is placed between the context
facet and the toolbar, as shown in Figure 8-42.
You can configure panelHeader
components so that they represent a hierarchy of sections. For example, as shown in Figure 8-43, you can have a main header with a subheader and then a heading level 1 also with a subheader.
Create subsections by nesting panelHeader
components within each other. When you nest panelHeader
components, the heading text is automatically sized according to the hierarchy, with the outermost panelHeader
component having the largest text.
Note:
While you can force the style of the text using thesize
attribute (where 0 is the largest text), the value of the size
attribute will not affect the hierarchy. It only affects the style of the text.For information about using the panelHeader
component, see Section 8.10.1, "How to Use the panelHeader Component."
The decorativeBox
component provides styling capabilities using themes. It has two facets, top and center. The top facet provides a non-colored area, while the center facet is the actual box. The height of the top facet depends on whether or not a component has been put into the top facet. When the facet is set, the topHeight
attribute is used to specify the size the content should occupy.
The color of the box for the center facet depends on the theme and skin used. Figure 8-44 shows the different themes available by default.
By default, the decorativeBox
component stretches to fill its parent component. You can also configure the decorative
Box component to inherit its dimensions from its child components. For example, Figure 8-45 shows the medium-theme decorativeBox
configured to stretch to fill its parent, while the dark-theme decorativeBox
is configured to only be as big as its child outputText
component.
You can further control the style of the decorativeBox
component using skins. Skinning keys can be defined for the following areas of the component:
top-start
top
top-end
start
end
bottom-start
bottom
bottom-end
For more information about skins, see Chapter 20, "Customizing the Appearance Using Styles and Skins."
You can use one panelHeader
component to contain specific information, or you can use a series of nested panelHeader
components to create a hierarchical organization of content. If you want to be able to hide and display the content, use the showDetailHeader
component instead. For more information, see Section 8.8.2, "How to Use the showDetailHeader Component."
To create and use a panelHeader component:
In the Component Palette, from the Layout panel, drag and drop a Panel Header onto the page.
In the Property Inspector, expand the Appearance section.
To add an icon before the label, set Icon to the URI of the image file to use.
Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.If you are using the header to provide specific messaging information, set MessageType to one of the following values:
confirmation: The confirmation icon (represented by a note page overlaid with a green checkmark) replaces any specified icon image.
error: The error icon (represented by a red circle with an "x" inside) replaces any specified icon image. The header label also changes to red.
info: The info icon (represented by a blue circle with an "I" inside) replaces any specified icon image.
none: Default. No icon is displayed.
warning: The warning icon (represented by a yellow triangle with an exclamation mark inside) replaces any specified icon image.
Figure 8-46 shows the icons used for the different message types.
Note:
Because alternative text cannot be provided for this icon, in order to create an accessible product, use this icon only when it is purely decorative. You must provide the meaning of this icon in some accessible manner.To display help for the header, enter the topic ID for HelpTopicId. For more information about creating and using help topics, see Section 17.5, "Displaying Help for Components."
If you want to control how the panelHeader
component handles geometry management, expand the Other section and set Type to one of the following. For more information about geometry management, see Section 8.2.1, "Geometry Management and Component Stretching."
flow: The component will not stretch or stretch its children. The height of the panelHeader
component will be determined solely by its children.
stretch: The component will stretch and stretch its child (will only stretch a single child component).
default: if you want the parent component of the panelHeader
component to determine geometry management.
To add toolbar buttons to a panel, insert the toolbar
component into the toolbar
facet. Then, insert the desired number of commandToolbarButton
components into the toolbar
component. For information about using toolbar
and commandToolbarButton
, see Section 14.3, "Using Toolbars."
Note:
Toolbar overflow is not supported inpanelHeader
components.To add menus to a panel, insert menu components into the menuBar
facet. For information about creating menus in a menu bar, see Section 14.2, "Using Menus in a Menu Bar."
Tip:
You can place menus in thetoolbar
facet and toolbars (and toolboxes) in the menu
facet. The main difference between these facets is location. The toolbar
facet is before the menu
facet.Add contents to the other facets as needed.
Tip:
If any facet is not visible in the visual editor:Right-click the panelHeader
component in the Structure window.
From the context menu, choose Facets - Panel Header >facet name. Facets in use on the page are indicated by a checkmark in front of the facet name.
To add contents to the panel, insert the desired child components into the panelHeader
component.
You use the decorativeBox
component to provide a colored area or box in a page. This component is typically used as a container for the navigationPane
component that is configured to display tabs. For more information, see Section 18.5, "Using Navigation Items for a Page Hierarchy."
To create and use a decorativeBox component:
In the Component Palette, from the Layout panel, drag and drop a Decorative Box onto the page.
In the Property Inspector, expand the Common section and set Top Height to the height for the top
facet.
To change the theme, expand the Style and Theme section and choose a different theme.
By default, the decorativeBox
component stretches to fill available browser space. If instead, you want to use the decorativeBox
component as a child to a component that does not stretch its children, then you need to change how the decorativeBox
component handles stretching.
You configure whether the component will stretch or not using the dimensionsFrom
attribute. To do so, expand the Other section, and set DimensionsFrom to one of the following:
children
: the decorativeBox
component will get its dimensions from its child components.
Note:
If you use this setting, you cannot use a percentage to set the height of thetop
facet. If you do, the top facet will try to get its dimensions from the size of this decorativeBox
component, which will not be possible, as the decorativeBox
component will be getting its height from its contents, resulting in a circular dependency. If a percentage is used, it will be disregarded and the default 50px
will be used instead.
Similarly, you cannot set the height of the decorativeBox
(for example through the inlineStyle
or styleClass
attributes). Doing so would cause conflict between the decorativeBox
height and the child component height.
parent
: the size of the decorativeBox
component will be determined in the following order:
From the inlineStyle
attribute.
If no value exists for inlineStyle
, then the size is determined by the parent container.
If the parent container is not configured or not able to stretch its children, the size will be determined by the skin.
auto
: If the parent component to the decorativeBox
component allows stretching of its child, then the decorativeBox
component will stretch to fill the parent. If the parent does not stretch its children then the size of the decorativeBox
component will be based on the size of its child component.
For more information, see Section 8.10.3, "What You May Need to Know About Geometry Management and the decorativeBox Component."
The decorativeBox
component can stretch child components in its center
facet and it can also be stretched. The following components can be stretched inside the center
facet of the decorativeBox
component:
inputText
(when configured to stretch)
decorativeBox
(when configured to stretch)
panelAccordion
(when configured to stretch)
panelBox
panelCollection
panelDashboard
panelGroupLayout
(only with the layout
attribute set to scroll
or vertical
)
panelSplitter
(when configured to stretch)
panelStretchLayout
(when configured to stretch)
panelTabbed
(when configured to stretch)
region
table
(when configured to stretch)
tree
(when configured to stretch)
treeTable
(when configured to stretch)
The following components cannot be stretched when placed inside a facet of the decorativeBox
component:
panelBorderLayout
panelFormLayout
panelGroupLayout
(only with the layout
attribute set to default
or horizontal
)
panelHeader
panelLabelAndMessage
panelList
showDetail
showDetailHeader
tableLayout
(MyFaces Trinidad component)
You cannot place components that cannot stretch into facets of a component that stretches its child components. Therefore, if you need to place one of the components that cannot be stretched into a facet of the decorativeBox
component, wrap that component in a transition component that does not stretch its child components.
For example, if you want to place content in a panelBox
component and have it flow within a facet of the decorativeBox
component, you could place a panelGroupLayout
component with its layout attribute set to scroll
in the facet of the decorativeBox
component, and then place the panelBox
component in that panelGroupLayout
component. For more information, see Section 8.2.2, "Nesting Components Inside Components That Allow Stretching."
The panelList
component is a layout element for displaying a vertical list of child components with a bullet next to each child, as shown in Figure 8-47. Only child components whose rendered
attribute is set to true
and whose visible
attribute is set to true
are considered for display by in the list.
Note:
To display dynamic data (for example, a list of data determined at runtime by JSF bindings), use the selection components, as documented in Section 9.6, "Using Selection Components." If you need to create lists that change the model layer, see Chapter 11, "Using List-of-Values Components."By default, the disc bullet is used to style the child components. There are other styles you can use, such as square bullets and white circles. You can also split the list into columns when you have a very long list of items to display.
Use one panelList
component to create each list of items.
To create and use the panelList component:
In the Component Palette, from the Layout panel, drag and drop a Panel List to the JSF page.
In the Property Inspector, expand the Common section, and set the listStyle
attribute to a valid CSS 2.1 list style value, such as one of the following:
list-style-type: disc
list-style-type: square
list-style-type: circle
list-style-type: lower-alpha
list-style-type: upper-alpha
For example, the list-style-type: disc
attribute value corresponds to a disc bullet, and the list-style-type: circle
value corresponds to a circle bullet.
For a complete list of the valid style values to use, refer to the CSS 2.1 Specification for generated lists at
http://www.w3.org/TR/CSS21/generate.html
Example 8-13 shows the code for setting the list style to a circle.
Insert the desired number of child components (to display as bulleted items) into the panelList
component.
Tip:
Panel lists also allow you to use theiterator
, switcher
, and group
components as direct child components, providing these components wrap child components that would typically be direct child components of the panel list.For example, you could insert a series of commandLink
components or outputFormatted
components.
Note:
By default, ADF Faces displays all rendered child components of apanelList
component in a single column. For details on how to split the list into two or more columns and for information about using the rows
and maxColumns
attributes, see Section 8.6, "Arranging Content in Forms." The concept of using the rows
and maxColumns
attributes for columnar display in the panelList
and panelFormLayout
components are the same.You can nest panelList
components to create a list hierarchy. A list hierarchy, as shown in Figure 8-48, has outer items and inner items, where the inner items belonging to an outer item are indented under the outer item. Each group of inner items is created by one nested panelList
component.
To achieve the list hierarchy as shown in Figure 8-48, use a group
component to wrap the components that make up each group of outer items and their respective inner items. Example 8-14 shows the code for how to create a list hierarchy that has one outer item with four inner items, and another outer item with two inner items.
Example 8-14 Nested PanelList Components
<af:panelList> <!-- First outer item and its four inner items --> <af:group> <af:commandLink text="item 1"/> <af:panelList> <af:commandLink text="item 1.1"/> <af:commandLink text="item 1.2"/> <af:commandLink text="item 1.3"/> <af:commandLink text="item 1.4"/> </af:panelList> </af:group> <!-- Second outer item and its two inner items --> <af:group> <af:commandLink text="item 2"/> <af:panelList> <af:commandLink text="item 2.1"/> <af:commandLink text="item 2.2"/> </af:panelList> </af:group> </af:panelList>
By default, the outer list items (for example, item 1 and item 2) are displayed with the disc bullet, while the inner list items (for example, item 1.1 and item 2.1) have the white circle bullet.
For more information about the panelGroupLayout
component, see Section 8.12, "Grouping Related Items."
To keep like items together within a parent component, use either the group
or panelGroupLayout
component. The group
component aggregates or groups together child components that are related semantically. Unlike the panelGroupLayout
component, the group
component does not provide any layout for its child components. Used on its own, the group
component does not render anything; only the child components inside of a group
component render at runtime.
You can use any number of group
components to group related components together. For example, you might want to group some of the input fields in a form layout created by the panelFormLayout
component. Example 8-15 shows sample code that groups two sets of child components inside a panelFormLayout
component.
Example 8-15 Grouping Child Components in panelFormLayout
<af:panelFormLayout> <af:inputDate label="Pick a date"/> <!-- first group --> <af:group> <af:selectManyCheckbox label="Select all that apply"> <af:selectItem label="Coffee" value="1"/> <af:selectItem label="Cream" value="1"/> <af:selectItem label="Low-fat Milk" value="1"/> <af:selectItem label="Sugar" value="1"/> <af:selectItem label="Sweetener"/> </af:selectManyCheckbox> <af:inputText label="Special instructions" rows="3"/> </af:group> <!-- Second group --> <af:group> <af:inputFile label="File to upload"/> <af:inputText label="Enter passcode"/> </af:group> <af:inputText label="Comments" rows="3"/> <af:spacer width="10" height="15"/> <f:facet name="footer"/> </af:panelFormLayout>
The panelGroupLayout
component lets you arrange a series of child components vertically or horizontally without wrapping, or consecutively with wrapping, as shown in Figure 8-49. The layout
attribute value determines the arrangement of the child components.
In all arrangements, each pair of adjacent child components can be separated by a line or white space using the separator
facet of the panelGroupLayout
component. For more information, see Section 8.13, "Separating Content Using Blank Space or Lines."
When using the horizontal layout, the child components can also be vertically or horizontally aligned. For example, you could make a short component beside a tall component align at the top, as shown in Figure 8-50.
Unlike the panelSplitter
or panelStretchLayout
components, the panelGroupLayout
component does not stretch its child components. Suppose you are already using a panelSplitter
or panelStretchLayout
component as the root component for the page, and you have a large number of child components to flow, but are not to be stretched. To provide scrollbars when flowing the child components, wrap the child components in the panelGroupLayout
component with its layout
attribute set to scroll
, and then place the panelGroupLayout
component inside a facet of the panelSplitter
or panelStretchLayout
component.
When the layout
attribute is set to scroll
on a panelGroupLayout
component, ADF Faces automatically provides a scrollbar at runtime when the contents contained by the panelGroupLayout
component are larger than the panelGroupLayout
component itself. You do not have to write any code to enable the scrollbars, or set any inline styles to control the overflow.
For example, when you use layout components such as the panelSplitter
component that let users display and hide child components contents, you do not have to write code to show the scrollbars when the contents are displayed, and to hide the scrollbars when the contents are hidden. Simply wrap the contents the be displayed inside a panelGroupLayout
component, and set the layout
attribute to scroll
.
In the File Explorer application, the Search Navigator contains a panelSplitter
component used to hide and show the search criteria. When the search criteria are hidden, and the search results content does not fit into the area, a scrollbar is rendered, as shown in Figure 8-51.
Any number of panelGroupLayout
components can be nested to achieve the desired layout.
To create and use the panelGroupLayout component:
In the Component Palette, from the Layout panel, drag and drop a Panel Group Layout to the JSF page.
Insert the desired child components into the panelGroupLayout
component.
Tip:
ThepanelGroupLayout
component also allows you to use the iterator
, switcher
, and group
components as direct child components, providing these components wrap child components that would typically be direct child components of the panelGroupLayout
component.To add spacing or separator lines between adjacent child components, insert the spacer
or separator
component into the separator
facet.
In the Property Inspector, expand the Appearance section. To arrange the child components in the desired layout, set Layout to one of the following values:
default: Provides consecutive layout with wrapping.
At runtime, when the contents exceed the browser space available (that is, when the child components are larger than the width of the parent container panelGrouplayout
), the browser flows the contents onto the next line so that all child components are displayed.
Note:
ADF Faces uses the bidirectional algorithm when making contents flow. Where there is a mix of right-to-left content and left-to-right content, this may result in contents not flowing consecutively.horizontal: Uses a horizontal layout, where child components are arranged in a horizontal line. No wrapping is provided when contents exceed the amount of browser space available.
In a horizontal layout, the child components can also be aligned vertically and horizontally. By default, horizontal child components are aligned in the center with reference to an imaginary horizontal line, and aligned in the middle with reference to an imaginary vertical line. To change the horizontal and vertical alignments of horizontal components, use the following attributes:
halign: Sets the horizontal alignment. The default is center
. Other acceptable values are: start
, end
, left
, right
.
For example, set halign
to start
if you want horizontal child components to always be left-aligned in browsers where the language reading direction is left-to-right, and right-aligned in a right-to-left reading direction.
valign: Sets the vertical alignment. Default is middle
. Other acceptable values are: top
, bottom
, baseline
.
In output text components (such as outputText
) that have varied font sizes in the text, setting valign
to baseline
would align the letters of the text along an imaginary line on which the letters sit, as shown in Figure 8-52. If you set valign
to bottom
for such text components, the resulting effect would not be as pleasant looking, because bottom
vertical alignment causes the bottommost points of all the letters to be on the same imaginary line.
Note:
Thehalign
and valign
attributes are ignored if the layout is not horizontal.scroll: Uses a vertical layout, where child components are stacked vertically, and a vertical scrollbar is provided when necessary.
vertical: Uses a vertical layout, where child components are stacked vertically.
While the panelGroupLayout
component cannot stretch its child components, it can be stretched when it is the child of a panelSplitter
or panelStretchLayout
component and its layout
attribute is set to either scroll
or vertical
.
You can incorporate some blank space in your pages, to space out the components so that the page appears less cluttered than it would if all the components were presented immediately next to each other, or immediately below each other. The ADF Faces component provided specifically for this purpose is the spacer
component.
You can include either or both vertical and horizontal space in a page using the height
and width
attributes.
The height
attribute determines the amount of vertical space to include in the page. Example 8-16 shows a page set up to space out two lengthy outputText
components with some vertical space.
Example 8-16 Vertical Space
<af:panelGroupLayout layout="vertical"> <af:outputText value="This is a long piece of text for this page..."/> <af:spacer height="10"/> <af:outputText value="This is some more lengthy text ..."/> </af:panelGroupLayout>
Figure 8-53 shows the effect the spacer
component has on the page output as viewed in a browser.
The width
attribute determines the amount of horizontal space to include between components. Example 8-17 shows part of the source of a page set up to space out two components horizontally.
Example 8-17 Horizontal Space
<af:outputLabel value="Your credit rating is currently:"/> <af:spacer width="10"/> <af:outputText value="Level 8"/>
Figure 8-54 shows the effect of spacing components horizontally as viewed in a browser.
The separator
component creates a horizontal line. Figure 8-55 shows the properties.jspx
file as it would be displayed with a separator
component inserted between the two panelBox
components.
The spacer
and separator
components are often used in facets of other layout components. Doing so ensures that the space or line stays with the components they were meant to separate.
You can use as many spacer
components as needed on a page.
To create and use the spacer component:
In the Component Palette, from the Layout panel, drag and drop a Spacer to the JSF page.
In the Property Inspector, expand the Common section. Set the width and height as needed.
Note:
If the height is specified but not the width, a block-level HTML element is rendered, thereby introducing a new line effect. If the width is specified, then, irrespective of the specified value of height, it may not get shorter than the applicable line-height in user agents that strictly support HTML standards.