Responsive Design for your ADF Faces Web Applications
- by Shay Shmeltzer
Responsive web applications are a common pattern for designing web pages that adjust their UI based on the device that access them. With the increase in the number of ADF applications that are being accessed from mobile phones and tablet we are getting more and more questions around this topic.
Steven Davelaar wrote a comprehensive article covering key concepts in this area that you can find here. The article focuses on what I would refer to as server adaptive application, where the server adapts the UI it generates based on the device that is accessing the server.
However there is one more technique that is not covered in that article and can be used with Oracle ADF - it is CSS manipulation on the client that can achieve responsive design. I'll cover this technique in this blog entry. The main advantage of this technique is that the UI manipulation does not require the server to send over a new UI when a change is needed. This for example allows your page to change immediately when you change the orientation of your device.
(By the way this example was developed for one of the seminars in the upcoming Oracle ADF OTN Virtual Developer Day).
In the demo that you'll see below you'll see a single page that changes the way it is displayed based on the orientation of the device. Here is the page with the tablet in landscape and portrait:
To achieve this I'm using a CSS media query in my page template that changes the display property of a couple of style classes that are used in my page.
The media query has this format:
@media screen and (max-width:700px) { .narrow { display: inline; } .wide { display: none; } .adjustFont { font-size: small; } .icon-home { font-size: 24px; } }
This changes the properties of the same styleClasses that are defined in my application's skin.
Here is a quick demo video that shows you the full application and explains how it works.
For those looking to replicate this, here are the basic files:
skin1.css
@charset "UTF-8";/**ADFFaces_Skin_File / DO NOT REMOVE**/@namespace af "http://xmlns.oracle.com/adf/faces/rich";@namespace dvt "http://xmlns.oracle.com/dss/adf/faces";.wide { display: inline;}.narrow { display: none;}.adjustFont { font-size: large;}.icon-home { font-family: 'UIShellUGH'; -webkit-font-smoothing: antialiased; font-size: 36px; color: #ffa000;}
pageTemplate:
<?xml version='1.0' encoding='UTF-8'?><af:pageTemplateDef xmlns:af="http://xmlns.oracle.com/adf/faces/rich" var="attrs" definition="private" xmlns:afc="http://xmlns.oracle.com/adf/faces/rich/component"> <af:xmlContent> <afc:component> <afc:description>A template that will work on phones and desktop</afc:description> <afc:display-name>ResponsiveTemplate</afc:display-name> <afc:facet> <afc:facet-name>main</afc:facet-name> </afc:facet> </afc:component> </af:xmlContent> <meta name="viewport" content="width=device-width, initial-scale=1"/> <af:resource type="css">@media screen and (max-width:700px) { .narrow { display: inline; } .wide { display: none; } .adjustFont { font-size: small; } .icon-home { font-size: 24px; } }@font-face { font-family: 'UIShellUGH'; src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRk9UVE8AA..removed code here...AzV6b1g==)format('truetype'); font-weight: normal; font-style: normal; } </af:resource> <af:panelGroupLayout id="pt_pgl4" layout="vertical" styleClass="sizeStyle"> <af:panelGridLayout id="pt_pgl1"> <af:gridRow marginTop="5px" height="40px" id="pt_gr1"> <af:gridCell marginStart="5px" width="100%" marginEnd="5px" id="pt_gc1"> <af:panelGroupLayout id="pt_pgl3" halign="center" layout="horizontal"> <af:outputText value="h" id="ot2" styleClass="icon-home"/> <af:outputText value="HR System" id="ot3" styleClass="adjustFont"/> </af:panelGroupLayout> </af:gridCell> </af:gridRow> <af:gridRow marginTop="5px" height="auto" id="pt_gr2"> <af:gridCell marginStart="5px" width="100%" marginEnd="5px" id="pt_gc2" halign="stretch"> <af:panelGroupLayout id="pt_pgl2" layout="scroll"> <af:facetRef facetName="main"/> </af:panelGroupLayout> </af:gridCell> </af:gridRow> <af:gridRow marginTop="5px" height="20px" marginBottom="5px" id="pt_gr3"> <af:gridCell marginStart="5px" width="100%" marginEnd="5px" id="pt_gc3"> <af:panelGroupLayout id="pt_pgl5" layout="vertical" halign="center"> <af:separator id="pt_s1"/> <af:outputText value="Copyright Oracle Corp. 2013" id="pt_ot1" styleClass="adjustFont"/> </af:panelGroupLayout> </af:gridCell> </af:gridRow> </af:panelGridLayout> </af:panelGroupLayout></af:pageTemplateDef>
Example from the page:
<af:gridRow id="gr3"> <af:gridCell id="gc7" columnSpan="2"> <af:panelGroupLayout id="pgl8" styleClass="narrow"> <af:link text="Menu" id="l1"> <af:showPopupBehavior triggerType="action" popupId="p1" align="afterEnd"/> </af:link> </af:panelGroupLayout> <af:panelGroupLayout id="pgl7" styleClass="wide"> <af:navigationPane id="np1" hint="buttons"> <af:commandNavigationItem text="Departments" id="cni1"/> <af:commandNavigationItem text="Employees" id="cni2"/> <af:commandNavigationItem text="Salaries" id="cni3"/> <af:commandNavigationItem text="Jobs" id="cni4"/> <af:commandNavigationItem text="Services" id="cni5"/> <af:commandNavigationItem text="Support" id="cni6"/> <af:commandNavigationItem text="Help" id="cni7"/> </af:navigationPane> </af:panelGroupLayout> </af:gridCell> </af:gridRow>