Developer Tools
Application Development Framework
An Oracle JDeveloper Best Practices Document
March, 2010
Pattern | Layout Pattern: Compound Component in Form |
Pattern Revision | 1.0 |
Technologies | ADF Faces |
Keywords | Form, Alignment |
Forum | |
Publish date | March 2010 |
This pattern describes the scenario where a single logical slot in a panelFormLayout needs to contain multiple physical components as is shown in this sketch:

In this case notice the following requirements
To achieve this layout there are several steps:
The core to this implementation is the use of a panelLabelAndMessage component which is designed specifically for this purpose of allowing several logical components, or components without their own label property to be correctly laid out in a panelFormLayout.
By default, the panelLabelAndMessage will lay out its children vertically. In this case we want the components side-by-side. So simply use a horizontal panelGroupLayout as the immediate child to enclose its content. The child components are then placed into this panelGroupLayout. Use a spacer, or if there are more than two components, the Separator facet of the panelGroupLayout containing a spacer, to control the precise gap between the sub-components as required.
Next you need to make sure that the layout engine does not allocate space for labels on the subcomponents. The label is being defined by the panelLabelAndMessage. To achieve this, set the simple property to “true” on each of the child components. You should also set the for property on the parent panelLabelAndMessage to the relevant child component id. This will endure that error messages are correctly displayed.
If your Form has a ragged right margin then there is no more to do, however, if you want the components to right align as well as left align within the logical form, then there is this additional step.
The approach to doing this is to increase the length of the second child to take up available space and maintain a fixed gap between the child components.
Components such as the selectOneChoice do not stretch and are controlled by the size of their data, therefore you will have to control the size manually using styles. There are two style-related options available on these components, inlineStyle and contentStyle. In the case of the selectOneChoice, setting width in the inlineStyle property will apply to the component as a whole, including its label if it has one. The contentStyle property is used to control just the width of the drop down box itself and therefore is the property to use. Unfortunately getting the exact width, is a matter of trial and error. If you use pixels as the measurement unit, bear in mind that this is probably being used to align with input fields which are sized according to their columns property. This being the case, changes to the skin or browser zoom level may disrupt this relationship. For precise alignment that can survive zooming by the user, you may have to set explicit sizes in em’s for all the components in the form, or use the fieldWidth and LabelWidth properties of the panelFormLayout.
The code for this component will look like this:
<af:selectOneChoice id="soc1"
simple="true"
value="#{bindings.Currency.inputValue}"
contentStyle="width:11em;">
<f:selectItems id="si1" value="#{bindings.Currency.items}" />
</af:selectOneChoice>
The following diagram summarizes the way in which the containers are arranged:

The following screenshot shows the implemented result:

| Complete Code |
<af:panelFormLayout id="pfl1" labelAlignment="start"> <af:inputText id="it1" <af:inputText id="it2" <af:panelLabelAndMessage id="plam1" <af:panelGroupLayout id="pgl1" <af:inputNumberSpinbox id="ins1" <af:selectOneChoice id="soc1" <f:selectItems id="si1" </af:selectOneChoice> </af:panelGroupLayout> </af:panelLabelAndMessage> <af:commandButton text="Save" id="cb1"/> |