Monday, June 19, 2017

Fixes for ADF Cloud User Experience Rapid Development Kit (RDK) UI Layout Issues

If you was evaluating Oracle RDK UI template, probably you noticed information popup coming up, when RDK home page is loaded. Popup is loaded through showPopupBehavior listener, which is executed on Welcome page load event. Such popup is not required in practice, and usually is disabled. But as soon as you disable it, there will be layout issues with Welcome page. User information widget will not align the name and menu navigation items will not be ordered correctly:


This is not nice. And you will get such behaviour only when popup is not loaded:


I looked into it in more detail and I saw there is a second HTTP PPR request executed, when popup is loaded. It seems this second HTTP request was triggering partial response and this was forcing UI to load correctly:


Fortunately I found a simple fix for that. Need to set layout="horizontal" for springboard panelGroupLayout component located in Welcome page:


This change makes job done and now Welcome page layout is rendered correctly from the start, even without loading popup and forcing second HTTP PPR request:


There is another issue - related to panelGridLayout usage in ADF Task Flows loaded through Film Strip page. You can check my previous example about customising/extending RDK template - Extending ADF Cloud User Experience Rapid Development Kit (RDK). Let's assume use case with ADF Task Flow implementing two fragments (search and edit functionality):


Search screen renders ADF list implemented using panelGridLayout:


Navigate to edit screen:


Try to navigate back to search screen, you will get empty list displayed:


Fix is simple. RDK is using property stretchChildren="first" in FilmStrip page and this seems to break UI layout for regions with panelGridLayout component:


Remove stretchChildren="first" property from FilmStrip page, showDetailItem component assigned with id="sdi1":


With this fix applied, try to navigate from edit to search:


This time search page layout with panelGridLayout component is displayed as it should:


Download extended RDK application code with applied fixes - AppsCloudUIKit_v3.zip.

Wednesday, June 14, 2017

Nice Trick to Get ADF LOV Description Text

I will tell you about nice trick to display LOV description. Usually you would create separate attribute in VO for LOV description and base LOV on this attribute (read about it in my previous post - Defining the LOV on a Reference Attribute in Oracle ADF 11g). But there is one more way - it makes it much faster to define LOV on description, but you should be aware about additional SQL statement executed to fetch description text.

You could set converter for ADF UI LOV, and then LOV component would use description by itself, without any additional configuration.

It is important to set correct order for LOV display attributes. Make sure to set description attribute to be first in the list for converter approach to work:


Go to ADF UI LOV component and set converter property. This must point to binding object, converter expression:


What you get - LOV field displays description, converter is able to mask ID value behind it:


It offers nice usability option - you could start typing description, press tab and value will be auto completed (if autoSubmit is set to true):


Behind the scenes it executes LOV SQL to get description text (this SQL is executed on page load too, which is not ideal when you have many LOV fields - in such situation is better to use separate attribute for description in the same VO):


When LOV value is changed and changes are saved, ADF BC updates ID value only (as expected):


Download sample application - ADFLovDescriptionApp.zip.

Saturday, June 3, 2017

Running ADF BC REST Service Together with ADF Faces Application

ADF 12c provides out of the box support for ADF BC REST API. It is straightforward to create ADF BC REST service and run it. But what if you would like to expose ADF BC REST for existing ADF application with ADF Faces UI. This could be useful if there is a requirement to handle ADF Bindings access to ADF BC along with light ADF BC REST service API implementation for Oracle JET or other JavaScript clients. The same ADF application could handle two types of client access - ADF Faces and REST.

When you create ADF BC REST application, JDeveloper creates REST Model and WebService projects. Technically speaking, if you have existing ADF application with Model and ViewController, you could add third project for REST Web Service by yourself. Two configuration files are required - web.xml and weblogic.xml (if ADF Security is enabled):


ADF BC REST is exposed to the client through ADF servlet. It doesnt work to enable ADF BC REST servlet in ADF Faces project web.xml. This requires to have separate WAR deployment for ADF BC REST and different context root.

ADF Faces and ADF BC REST are sharing the same ADF Security context and this means we are using the same set of Application Roles for both.

In my example, ADF Bindings are mapped with Employees VO instance - this brings data to be displayed in ADF Faces:


The same VO instance is exposed through ADF BC REST:


ADF BC REST servlet is defined in REST project web.xml. It doesnt work to define it in the same web.xml where ADF Faces are configured - context conflict error comes on runtime. Thats the reason why I have separate WAR for ADF BC REST:


There is one WAR for ADF Faces app and one for ADF BC REST. Both WARs are packaged into single EAR. This means there is one deployment, but two context roots, one for each WAR:


If you download my sample app and want to run it, make sure to build REST project first:


Then click Run for ADF Faces app - ADF BC REST WAR will be packaged automatically (if you deploy it on standalone, simply build EAR - it will include both WARs):


We can see it in the deployment log - both WARs are packaged into single EAR:


This is the result - ADF Faces UI is accessed through adfapp context root:


ADF BC REST from the same application is accessed through restapp context root, authenticated with the same ADF Security context as ADF Faces app:


Download sample application - ADFFacesRESTApp.zip.

Tuesday, May 30, 2017

ADF PopUp Event Context Launcher

I will describe how you could use ADF popup event context to pass parameters into popup. This could be useful if you want to develop reusable popup, which should accept different type of parameters from various launcher components.

In this example - popup is loaded from context info. Launcher component - output text is assigned with attribute, reading its value from binding. Our goal is to pass attribute value into popup:


In order to be able to read attribute value from launcher parent component, make sure to set eventContext="launcher" for ADF popup:


You can reference parent UI component from launcher property, this can be done in popup fetch listener - where value will be copied to managed bean property:


We could process launcher parent component in managed bean, extract values, etc.:


Value retrieved from popup launcher is displayed in the popup:


Download sample application - PopUpEventContextApp.zip

Thursday, May 18, 2017

Oracle JET Hybrid - NavDrawer Template Menu/Header Structure

Oracle JET provides NavDrawer template for Web and for Hybrid. Read how to create JET Hybrid application based on template - Create a Hybrid Mobile Application. There is significant difference in NavDrawer template implementation when we compare Web and Hybrid application.

Hybrid template draws menu structure on top of the form. Web template is pushing form to the right, when menu is opened. Such approach works fine on the Web, but you would see significant UI lag each time when menu item is selected. Probably thats the reason why hybrid NavDrawer template draws menu on top of the form - visually this provides better performance when switching between menu items. Menu is rendered on the top of the form in JET Hybrid Nav Drawer template:


Form is loaded instantly, when menu item is selected. Header in JET Hybrid NavDrawer template stays fixed, it doesnt scroll. This gives good opportunity to put there common actions:


NavDrawer template in JET Web application moves form to the right, when menu is opened - thats the main visual difference when comparing to NavDrawer Hybrid:


Index page of NavDrawer hybrid template is almost identical to Web NavDrawer, except that it doesn't contain header part. Header is implemented separate module:


I have customized default header implementation with additional items - logo and user preferences:


Header module is constructed in appController, this is how it is generated by default. If we want to have access to variables/functions from appController in the header, we need to create a mapping:


Every module must include div with fixed top JET CSS class (thats why it doesnt scroll and stays on top), where you would copy header code:


Header is bind with module, which is defined by headerConfig variable (must be located in each module) - which is initialized in appController:


Thats all about menu/header implementation.

Let's learn how to push update to Google Play. Make sure to increase application version in Cordova config.xml file:


Go to Google Play and upload new APK, it will be parsed and Google Play automatically will deactivate previous version:


You can initiate roll-out to production:


This will push new release to Google Play. Users will be automatically notified about new version:


Version 2 of our JET Hybrid app is available on Google Play:

Wednesday, May 10, 2017

Oracle JET Hybrid Mobile Application on Google Play

Oracle JET Hybrid mobile application can be published to Google Play and installed on Android device. We have tested this process from beginning to the end. Of course JET Hybrid mobile app can be published on Apple Store too, but we are using Google Plain and Android for now.

Where to get started if you want to publish your own Oracle JET Hybrid (open source and free to use) mobile app? First of all you need to build APK (if building for Android) file in release mode. Read about it in my previous post - How To Package JET Hybrid Mobile Application for Release (Android Platform).

Search for JellyHouse in Google Play to install and test our JET app:


You can use demo data account redsam/welcome1 to login and check how JET runs on your Android mobile:


Let's walk through the main steps about how to upload and publish JET APK file in Google Play. First of all you need to login into Google Play Developer console and pay license fee 25 USD (if you are publishing first time). Second, prepare APK file compiled in release mode (read above how to do it). APK file typically is located in hybrid folder, build/outputs directory:


In Google Play Developer console create new application - press Create Application button:


Before you could publish APK to Google Play, you will be asked to complete various forms with information about the app, content rating and upload application graphics:


APK file is uploaded under Release Management -> Artifact library:


To verify upload, click on show details icon and you should see additional information for uploaded APK:


There are options to manage test releases. But you could opt out directly for production - this is what I did. Press publish button and wait about 30 - 60 minutes. Status should be changed to published:


Once published, search for your app in Google Play. Google Play for JellyHouse app: