You are on page 1of 34

Marrying together the worlds of

ADF and HTML5 & AngularJS


Lucas Jellema (& Paco van der Linden)

Oracle OpenWorld 2014, San Francisco, CA, USA


Overview

• Why – Objectives
• Exploration –rich HTML5 component, reusable in ADF
• Approach
– Stand alone AngularJS/HTML5 application
– Extract ‘3D Tag Cloud component’
– Create ADF Taskflow wrapper around Tag Cloud component
– Creating ‘plumbing’ – connect Tag Cloud to HTML5 ADF
pageFlowScope and contextual events AngularJS Faces
– Further integration: absorb ADF skins, i18n and customization
into Tag Cloud component
• Demonstration
• Conclusion:
– We can leverage the world of HTML5/AngularJS resources to add spiffy, productive
functionality to ADF Faces Web Applications
3

ADF Match Center application


4

ADF Match Center application


Model
World Cup
database
schema

ViewController MatchCenter.jspx

Taskflow match

Rich Table
Taskflow taglist

Popup
Taskflow match-details
5

Objective: Interactive Tag


Cloud integrated into ADF app
Thick Client Thin Client

Presentation Presentation Presentation Presentation


Rendering Rendering Rendering Rendering

Client == Browser
Presentation Logic
Presentation Presentation
Logic Logic

Business
Business Logic
Logic

Presentation
Presentation
Logic
Logic

Server
Business Business Business
Business Logic Logic Logic
Logic

Enterprise Resources
(Data & Documents)
Angular ADF APEX

session state
Rich Client Thin Client
Client
HTML5/JS
SPA
Client
XML
Server HTML HTML

session state
Web Application
JSON JSON
XML XML
stateless

Presentation Services
POJO
XML

Business Services

Enterprise Resources
8

Final Result

Web Developer
community

World Cup
database
schema
3D interactive,
animated Tag Cloud

ADF World Cup 2014 Match Center application

AngularJS TagCloud applicatio


Taskflow Angular
TagCloud
Taskflow Module
Databound
ADF Rich Table
9

Step One – Stand Alone


AngularJS TagCloud application
• Locate reusable JavaScript/HTML5
Tag Cloud: TagCanvas
10

Step One – Stand Alone


AngularJS TagCloud application
• Locate reusable JavaScript/HTML5
Tag Cloud: TagCanvas
• Set up HTML5/AngularJS development
environment:
– IDE: Sublime Text Editor
– Package Manager: Node.js - NPM
– Build (Ant-like): Gulp
– Dependency Management (Maven-style): Bower
– Run Time: Google Chrome browser
11

Step One – Stand Alone


AngularJS TagCloud application
• Locate reusable JavaScript/HTML5
Tag Cloud: TagCanvas
• Set up HTML5/AngularJS development
environment:
– IDE: Sublime Text Editor
– Package Manager: Node.js - NPM
– Build (Ant-like): Gulp
– Dependency Management (Maven-style): Bower
– Run Time: Google Chrome browser
• Construct AngularJS application
– tagcloud-html
– bower.json
– gulpfile
– AngularJS Module TagCloud
tagcloud-
html.html

tagcloud.html
tagcloud.js
Angular Module myApp Angular
myController Module
$scope.tags = [ … ];
$scope.tagClicked = function (tag) {…} tagcloud

Angular scope
log
tags
tagClicked()
13

Step 2 - Bridge

• Multiple tag-cloud components in a single page


• Exchange events from the host-page to the guest-tagcloud and back
• New AngularJS Module: angularGuest
– Uses the OTNBridge JavaScript library
• Guests register with the bridge
• The bridge can receive messages from the guests angularGuest.js
and callback to host to pass
them through angularGuest – bridge1 Angular
Module
• Host can call bridge to call
guests to pass message angularGuest
• Guests can embed other
AngularJS modules
– Such as tagcloud OTNBridge Angular
hostCallBack() toGuest() Module

guests guestCallbacks Angular


Module
tagcloud-
bridge.html

angularGuest.js

angularGuest – bridge1 Angular


Module
Angular scope
toHost(msg) angularGuest
myTagcloud
tagClicked()
Angular
OTNBridge Module
hostCallBack() toGuest()
tagcloud
guests guestCallbacks

tagcloud.html
tagcloud.js
tagcloud-
bridge.html

angularGuest.js

angularGuest – bridge1 angularGuest – bridge 2 Angular


Module
Angular scope Angular scope
toHost(msg) toHost(msg) angularGuest
myTagcloud myTagcloud
tagClicked() tagClicked()
Angular
OTNBridge OTNBridge Module
hostCallBack() toGuest() hostCallBack() toGuest()
tagcloud
guests guestCallbacks guests guestCallbacks

tagcloud.html
tagcloud.js
16

Integrating Angular Bridge into


ADF applications
• Containerize the AngularJS + Tagcloud + Bridge application (single JS file)
• Create an ADF TaskFlow with a page fragment and PageFlowScope beans
otnBridge and tagCloudBean
– The former (generic) loads the JavaScript and publishes data to the AngularJS Scope
– The latter (special) handles the ’tag is clicked event’
17

Integrating Angular Bridge into


ADF applications

MainPage.jspx

Taskflow tagcloud

ViewController
Page Fragment tagcloud.jsff

Taskflow tagcloud

integration.js
OTNBridge
OTNBootstrapper

pageflowScope
tagcloud.js
otnBridge
angularGuest
tagCloudBean
tagcloud
18

3 2

TagCloudBean
5
19

Make AngularJS component


bound on ADF Data Binding
• The input parameter for the tagcloud Taskflow is set with a reference to
the animalCloud bean in the (page’s) viewScope
– This bean returns a list of tags
– Alternatively, a reference to an ADF data bound collection could have been used
ViewController

Taskflow tagcloud

viewScope
animalCloud
pageflowScope
otnBridge
tags tagCloudBean
Two TagClouds embedded in20
ADF page
ViewController
`
Taskflow tagcloud

viewScope
animalCloud
carsCloud

pageflowScope
otnBridge
tags tagCloudBean

Taskflow tagcloud

pageflowScope
otnBridge
tags tagCloudBean
21

Forwarding the tag clicked


event from tagcloud to ADF
• Event in Angular component is turned into ADF Contextual Event to be
consumed in host (ADF) application
ViewController

Taskflow tagcloud

zebra

pageflowScope
viewScope tagCloudBean
zooKeeper
22

Client Side events in Angular –


pushed to ADF client => server

ViewController

Taskflow tagcloud

OTNBridge
hostCallBack()

zebra

pageflowScope
tagCloudBean
23

Consume ADF Contextual


Event into Angular component
• Actions in the ADF side
of the applications can
[need to have] consequences
in the embedded components
• ADF Contextual Events are
the vehicle for this ‘from host
to guest’ interaction
– Just like they are for the
reverse route
• For example: add a tag from
outside the TagCloud Taskflow
Consume ADF Contextual
Event into Angular component

ViewController

Taskflow tagcloud

1
7
5
horse pageflowScope
4 tagCloudBean
6

3
2 viewScope
zooKeeper
parkingAttendant
25

Apply ADF Skinning to


embedded Angular components
• Skinning is a server side mechanism that generates CSS styles to apply
to UI components rendered in the browser
– CSS generation depends on selected skin, browser (version), locale, etc.
• The objective right now:
– apply these generated styles to the UI elements inside the embedded Angular
TagCloud component – to make them assume the same look and feel
• The challenge:
– Skinning knows nothing about the embedded elements and vice versa.
• The trick:
– Add a number of invisible ‘dummy’ components in the ADF Tasfklow
– At run time, using JavaScript, retrieve the skin-based CSS styles that are applied to
these dummy components
– Pass the style properties to the Angular scope [for each interested guest] and inside
the guest, apply these properties to the target components
ViewController

Taskflow tagcloud
pageflowScope
tagCloudBean

integration.js
sendMessage
ToGuest

inspectStyles
28

Apply Resource Bundles & i18n to


embedded Angular components
• Internationalization (i18n) is the adaptation of the user interface to current
locale (language, region)
– ADF (and Java) uses resource bundles per language that contain key-value pairs for
locale specific attributes – such as boilerplate text
• The objective right now:
– apply these translated values to i18n-enabled attributes in the embedded component
• The challenge:
– AngularJS and our JavaScript component are unaware of ADF Faces and of i18n
based on resource bundles
• The trick:
– Add an invisble inputText component in the ADF Tasfklow
– Define a clientAttribute on this component with a JSON collection that contains
resource bundle entries
– At run time, ADF Faces ensures that
these entries are translated
– Read the clientAttribute in JavaScript
and pass the value to the guest
ViewController

Taskflow tagcloud
pageflowScope
tagCloudBean

integration.js
sendMessage
ToGuest

extractTagsFor
Resource
BundleEntries
31

Customize and Personalize the


embedded AngularJS component
• Customization and Personalization is the adaptation of the user interface
based on context specific and personal settings and preferences
– ADF supports design time and run time customizations to be created (in MDS) and to be
applied at run time to UI components
• The objective right now:
– Create and apply customizations and personalizations to embedded Angular components
such as the 3D Tag Cloud
• The challenge:
– AngularJS and our JavaScript component are unaware of ADF Faces and of customization
and MDS
• The trick:
– Add invisible ADF Faces components in the ADF Tasfklow and define customizations on
their properties in the regular way
– To define customizations at run time – open a popup that shows ‘proxies’ for the UI
elements in the embedded component and define customizations on those
– At run time, ADF Faces ensures that customizations are applied according to the current
content
– Read the relevant customized properties in JavaScript and pass the values to the guest
32

World Cup 2014 Match Center


33

Summary and Conclusion

• Rich Client web applications are popular


– User experience is smooth and rich, optimally benefitting from HTML5 capabilities
– Development is relatively simple and productive
– Many resources are available
• ADF provides an enterprise application framework
– With a number of robust enterprise infrastructure facilities
– Fairly thick-server architecture with large but limited set of UI components
• ADF Web Applications can be enhanced using HTML5 components
– (for example) AngularJS modules can be created as stand-alone components, then
containerized and embedded in a reusable ADF Taskflow
– Using contextual events, embedded components can exchange data and events with
the ADF host and vice versa
• Without sacrificing the benefits of ADF, organizations can benefit from
many of the richness of HTML5

You might also like