Responsive Design for your ADF Faces Web Applications

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.

Update - since running this demo I found out that in 12.1.2 you get better results if everything relating to the style is defined just in your template and not spread in your skin file too (as shown in the video)

So For those looking to replicate this, here are the basic files:

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">


.wide {
    display: inline;
}

.narrow {
    display: none;
}

.adjustFont {
    font-size: large;
}
.icon-home {
        font-family: 'UIShellUGH';
    -webkit-font-smoothing: antialiased;
        font-size: 36px;
        color: #ffa000;
}
@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>

I placed a workspace with this sample here. Run the sample.jsf page in the viewController project.

Comments:

Hi,
thanks for the video. Is there a reason, why the css is split into a skin and into a css resource? Any thoughts about which definition (portrait or landscape) should get into the skin?
As far as I know, some css at-rules are not supported by the skinning framework. Was that the reason?

Posted by Angelo Hannes on November 04, 2013 at 01:41 AM PST #

Angelo - I just discovered that at least in the current 12.1.2 version the better approach is to have everything including both the original style and the @media and @font-face be defined in the page template and not in the skin.
Adding those to the skin file is something we are planning for future versions.

Posted by Shay on November 04, 2013 at 01:38 PM PST #

Hello Shay,

in my personal opinion that is not a good approach for responsive design. Your approach delivers the content twice. One part is hidden, but it is there. A mobile device must download and handle this overload. Media Queries should be used to rearrange the content and not just hiding it. What about different DPI and displays?

Regards
Simon

Posted by Simon on November 22, 2013 at 02:13 AM PST #

Hello Shay,

First of all, thanks for this post, it's very helpful. I did encounter a problem though. I am using JDeveloper 11.1.1.6 and I added a CSS resource for my file, just like you did, with the same @media syntax. The changes invoked by this structure get applied if I have "DISABLE_CONTENT_COMPRESSION" set to true in the web.xml file, but if that parameter is set to false nothing happens. I know that disabled_content_compression should be set to false when delivering the application because otherwise it affects performance. Any thoughts on how to deal with this?

Thanks,
Tom

Posted by Toma Popescu on November 25, 2013 at 12:11 AM PST #

Toma,
In upcoming versions, when Media queries will be supported in the skin itself, you won't need to change the DISABLE_CONTENT_COMPRESSION property.

Posted by Shay on November 26, 2013 at 01:14 PM PST #

Hello Shay,

Thanks for your answer. Do those upcoming versions you talk about include 11.1.1.7?

Thanks,
Tom

Posted by Tom on November 30, 2013 at 09:41 AM PST #

Shay,
I'm working from ADF 11.1.2.4.0 - in this version the Media Query doesn't seem to work at all. jDeveloper throws syntax errors when using keywords such as "and". The IDE states that the '{' is expected. Now this happens even though DISABLE_CONTENT_COMPRESSION is set to "true". I wonder if you could speak to this at all.

Shawn

Posted by Shawn on January 14, 2014 at 12:32 PM PST #

Hi Sir,

Is there any option to implement the same feature using JSF1.2..?

Awaiting for your answer.

Thanks in advance,
Shivaraj

Posted by Shivaraj on March 20, 2014 at 04:13 AM PDT #

I am not able to run sample .jsf.I am using 11.1.1.4.0 version of Jdev.
I have opened the Responsive project.Trying to run the sample.jsf, not getting any "run" option.
If we select sample.jsf as a target on project label,no action for the same.

Posted by guest on April 10, 2014 at 12:35 AM PDT #

guest - this demo was built with JDeveloper 12c - you won't be able to just pick up the project and run it in older JDevs.

Posted by Shay on April 16, 2014 at 02:10 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

me
I'm a Director of Product Management for the Oracle Java Development Tools.
Follow me:
Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today