Nowadays the need to create a web application based on a
responsive design is becoming very common. ADF in its latest version (as of
today), i.e. 12.2.1 provides the capability to address this. There is a feature
in ADF called Match Media Behavior which helps the developer to set the
layout and placement of UI components in a page based on the screen size. This
enables the appropriate rendering of the page regardless of whether it is being
rendered in a desktop, tablet or a mobile device. In this way, customers
can see the possibilities of getting away from building a mobile app, which
requires additional infrastructure, separate code base etc.
In this blog, I am providing a simple example of using the matchMediaBehavior
tag. My page has a bar chart and a table. When the page is rendered in a
desktop device, these components should render horizontally, and when it is
rendered in a tablet device, these components should be displayed vertically,
so that the table will be rendered below the bar chart.
Here is the code of the page:
<?xml version='1.0' encoding='UTF-8'?> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:af="http://xmlns.oracle.com/adf/faces/rich" xmlns:dvt="http://xmlns.oracle.com/dss/adf/faces" xmlns:f="http://java.sun.com/jsf/core"> <af:panelGroupLayout id="pgl1" layout="horizontal"> <af:matchMediaBehavior matchedPropertyValue="vertical" propertyName="layout" mediaQuery="screen and (max-width: 900px)"/> <dvt:barChart orientation="vertical" id="barChart1" var="row" value="#{bindings.EmpDetailsVO1.collectionModel}"> <dvt:chartLegend id="cl1"/> <f:facet name="dataStamp"> <dvt:chartDataItem id="di1" series="#{bindings.EmpDetailsVO1.hints.Salary.label}" value="#{row.Salary}" group="#{row.DepartmentName}"/> </f:facet> </dvt:barChart> <af:table value="#{bindings.EmpDetailsVO11.collectionModel}" var="row" rows="#{bindings.EmpDetailsVO11.rangeSize}" emptyText="#{bindings.EmpDetailsVO11.viewable ? 'No data to display.' : 'Access Denied.'}" rowBandingInterval="0" selectedRowKeys="#{bindings.EmpDetailsVO11.collectionModel.selectedRow}" selectionListener="#{bindings.EmpDetailsVO11.collectionModel.makeCurrent}" rowSelection="single" fetchSize="#{bindings.EmpDetailsVO11.rangeSize}" id="t1"> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.FirstName.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.FirstName.label}" id="c1"> <af:inputText value="#{row.bindings.FirstName.inputValue}" label="#{bindings.EmpDetailsVO11.hints.FirstName.label}" required="#{bindings.EmpDetailsVO11.hints.FirstName.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.FirstName.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.FirstName.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.FirstName.tooltip}" id="it1"> <f:validator binding="#{row.bindings.FirstName.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.LastName.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.LastName.label}" id="c2"> <af:inputText value="#{row.bindings.LastName.inputValue}" label="#{bindings.EmpDetailsVO11.hints.LastName.label}" required="#{bindings.EmpDetailsVO11.hints.LastName.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.LastName.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.LastName.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.LastName.tooltip}" id="it2"> <f:validator binding="#{row.bindings.LastName.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.Salary.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.Salary.label}" id="c3"> <af:inputText value="#{row.bindings.Salary.inputValue}" label="#{bindings.EmpDetailsVO11.hints.Salary.label}" required="#{bindings.EmpDetailsVO11.hints.Salary.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.Salary.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.Salary.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.Salary.tooltip}" id="it3"> <f:validator binding="#{row.bindings.Salary.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.EmpDetailsVO11.hints.Salary.format}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.DepartmentName.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.DepartmentName.label}" id="c5"> <af:inputText value="#{row.bindings.DepartmentName.inputValue}" label="#{bindings.EmpDetailsVO11.hints.DepartmentName.label}" required="#{bindings.EmpDetailsVO11.hints.DepartmentName.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.DepartmentName.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.DepartmentName.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.DepartmentName.tooltip}" id="it5"> <f:validator binding="#{row.bindings.DepartmentName.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.JobTitle.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.JobTitle.label}" id="c6"> <af:inputText value="#{row.bindings.JobTitle.inputValue}" label="#{bindings.EmpDetailsVO11.hints.JobTitle.label}" required="#{bindings.EmpDetailsVO11.hints.JobTitle.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.JobTitle.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.JobTitle.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.JobTitle.tooltip}" id="it6"> <f:validator binding="#{row.bindings.JobTitle.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.City.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.City.label}" id="c7"> <af:inputText value="#{row.bindings.City.inputValue}" label="#{bindings.EmpDetailsVO11.hints.City.label}" required="#{bindings.EmpDetailsVO11.hints.City.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.City.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.City.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.City.tooltip}" id="it7"> <f:validator binding="#{row.bindings.City.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.StateProvince.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.StateProvince.label}" id="c8"> <af:inputText value="#{row.bindings.StateProvince.inputValue}" label="#{bindings.EmpDetailsVO11.hints.StateProvince.label}" required="#{bindings.EmpDetailsVO11.hints.StateProvince.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.StateProvince.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.StateProvince.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.StateProvince.tooltip}" id="it8"> <f:validator binding="#{row.bindings.StateProvince.validator}"/> </af:inputText> </af:column> <af:column sortProperty="#{bindings.EmpDetailsVO11.hints.RegionName.name}" sortable="true" headerText="#{bindings.EmpDetailsVO11.hints.RegionName.label}" id="c10"> <af:inputText value="#{row.bindings.RegionName.inputValue}" label="#{bindings.EmpDetailsVO11.hints.RegionName.label}" required="#{bindings.EmpDetailsVO11.hints.RegionName.mandatory}" columns="#{bindings.EmpDetailsVO11.hints.RegionName.displayWidth}" maximumLength="#{bindings.EmpDetailsVO11.hints.RegionName.precision}" shortDesc="#{bindings.EmpDetailsVO11.hints.RegionName.tooltip}" id="it10"> <f:validator binding="#{row.bindings.RegionName.validator}"/> </af:inputText> </af:column> </af:table> </af:panelGroupLayout> </ui:composition>
Tip: To test the behavior
of page’s rendition in a tablet device, you can decrease size of the browser window.
When the page is rendered in desktop device
When the page is rendered in tablet device