Follow Us on Twitter

Routing and responsive layout with Oracle JET

by Herman Brunnekreef on February 5, 2016 · 5 comments

After creating my first pages with Oracle JET, some database data visualization and an Input Form, I want to create a JET application with navigation and a responsive layout.

Here are some pictures how the application looks like after building it:

Start screen of the application

Start screen of the application

This is the startscreen of the application:

When “Table” is selected, there is a submenu where a user can make another selection:
img2

When a choice is made in the subselect, you see the results:
img3

img4

If “Chart” is selected you see a chart:
img5

Here are now some screenshots of the application when the browser is shrinked. You see also the “hamburger” icon for a replacement of the menubar.

This is the main page:
img6

After selecting “Table” and choose the “Department” option, you can see the results are located under the subselect menu
img7

When the “Chart” is selected in the menu you see the chart. Oracle JET automatically resize the bar’s of the chart
img8

The “Chart” menu option without the menu shown

img9

Now let’s dive deeper in the code.

<!DOCTYPE html>
<html>
<head>
<title>Emp Dept Application</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" href="css/images/favicon.ico" type="image/x-icon"/>
<!-- This is the main css file for the default Alta theme -->
<link rel="stylesheet" href="css/libs/oj/v1.1.2/alta/oj-alta-min.css" type="text/css"/>
<!-- These style classes are for demonstration purposes only. -->
<link rel="stylesheet" href="css/demo-alta-patterns-min.css"/>
<!-- This is where you would add any app specific styling -->
<link rel="stylesheet" href="css/override.css" type="text/css"/>
<!-- RequireJS configuration file -->
<script data-main="js/main" src="js/libs/require/require.js"></script>
</head>
<body class="demo-appheader-offcanvas-pushwrapper">
<div id="routing-container">
<div id="appDrawer" class="oj-offcanvas-start oj-panel demo-appheader-offscreencontent"
style="height:100%;">
<div data-bind="ojModule: {name: 'header', viewName: 'offcanvasheader'}"></div>
</div>
<header id="headerWrapper" role="banner" data-bind="ojModule: { name: 'header'}"></header>
<hr/>
<div id="content" data-bind="ojModule: router.moduleConfig"></div>
</div>
</body>
</html>

This is the code of index.html. In this code you can see there’s a header and a body (content) element. You can also add a footer element here.
In the header binding you find also a viewName with the name ‘offcanvasheader’. This points to the offcanvasheader.tmpl.html. More explanation about oj-module you can find here

oj.ModuleBinding.defaults.modelPath = 'modules/';
oj.ModuleBinding.defaults.viewPath = 'text!../templates/';
oj.ModuleBinding.defaults.viewSuffix = '.tmpl.html';
oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter();
var router = oj.Router.rootInstance;
router.configure( {
'main' : {
label : 'Main', isDefault : true
},
'table' : {
label : 'Table'
},
'chart' : {
label : 'Chart'
}
});
var viewModel = {
router : router, optionChangeHandler : function (event, data) {
if (data.value == undefined) {
data.value = 'main';
}
if ('AppHeaderNav' === event.target.id && event.originalEvent) {
router.go(data.value);
}
}
};
$(document).ready(function() {
oj.Router.sync().then(function() {
ko.applyBindings(viewModel, document.getElementById('routing-container'));
});
});

This is the code of main.js. In the index.html file there is a reference to this file

script data-main="js/main"

.
In this code the router instance is being created. The “AppHeaderNav” in the code points to the element in the code below.
The

oj.Router.sync()

syncs the page with the choice of the user.

<div class="demo-appheader">
<div class="oj-row demo-appheader-classic">
<div class="oj-col demo-appheader-col">
<div class="oj-row">
<div class="demo-off-canvas-toggle demo-appheader-toggle-button">
<button class='oj-button-half-chrome demo-appheader-toggle-button'
data-bind="click:toggleAppDrawer,
ojComponent: {component:'ojButton', label: offScreenButtonLabel, display: 'icons', icons: {start: offScreenButtonIconClass}} ">
</button>
</div>
<div class="demo-appheader-logo" >
<div class="demo-appheader-appname-block">
<span style="" class="demo-appheader-appname" data-bind="text: appName"></span>
</div>
</div>
<div>
<div id="AppHeaderNav" class="demo-appheader-nav
oj-lg-condense
oj-lg-justify-content-center
oj-xl-condense
oj-xl-justify-content-flex-end"
data-bind="ojComponent: {component: 'ojNavigationList',
drillMode: 'none',
edge: 'top',
selection: $root.router.stateId(),
data: dataSource,
optionChange: $root.optionChangeHandler,
item: { template: 'app_nav_template' }
}"
aria-label="Choose only one navigation element">
</div>
</div>
</div> <!-- oj-row -->
</div> <!-- oj-col -->
</div> <!-- oj-row -->
</div> <!-- demo-appheader -->
<!-- template for rendering app nav data -->
<script type="text/html" id="app_nav_template">
<li>
<a href="#">
<!-- ko text: $data['name'] --> <!--/ko-->
</a>
</li>
</script>

This is the code of header.tmpl.html
In the ojNavigationList you can find the following code:

selection: $root.router.stateId()

This points to the router in the main.js.

For the “Table” page I used the example which you can find in the cookbook here.
I changed only one thing in table.tmpl.html. That is this:

selection: $root.router.stateId()

For the “Chart” page I also used an example from the cookbook. link.
This is the code (partly) in chart.js:

var viewModel = {
router: undefined,
initialize : function(data) {
if (this.router) {
return;
}
router = oj.Router.rootInstance;

oj.Router.sync();
},
selectHandler: function(event, ui) {
if ('chart-container' === event.target.id && event.originalEvent) {
viewModel.router.go(ui.key);
}
}
};
CreateChart();

return viewModel;

So this is the code for creating a application with a responsive layout and with multiple pages. With the modulair plan you can expand your JET-application very simple. Create an extra page, add the data (for example a REST-service), add the page to the menu and reload.
Also JET supports a responsive layout, it works very easy for different screen sizes. I wonder how Oracle places Oracle JET versus Oracle MAF for mobile devices.

Ratings:
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

{ 5 comments… read them below or add one }

Geertjan February 12, 2016 at 4:28 pm

Great — and, yes, like you said when we met, one approach is to use $root for intermodular communication (https://blogs.oracle.com/geertjan/entry/intermodular_communication_in_oracle_jet), while also note the other related comments by JB Brock on the Oracle JET forum.

Reply

Manu June 29, 2016 at 3:07 pm

That’s great.
Now, if I want simply to organize the views and viewModels in different sub folders, how can we do this?
The goal is just to help visualizing the files.

/views/section1
/views/section1/subsection1
/views/sections1/subsction1/viewA
/views/sections1/subsction2/viewB
/views/sections2/subsction1/viewC
etc.

The viewModels would have of course the same structure but I don’t know how to call them.

Reply

Herman Brunnekreef June 29, 2016 at 6:50 pm

Hi Manu,

Do you mean how to call the viewModel files?

You can check this site made by Geertjan: https://netbeans.org/kb/docs/webclient/ojet-gettingstarted.html.
At “Creating the first module” is described how to call a viewModel file.

Reply

Manu June 30, 2016 at 5:05 am

Calling a viewModel, that’s fine as long as the the file is in the root of the folder
but can we call a viewModel that is in a subfolder?
It’s bit like in this example
http://www.oracle.com/webfolder/technetwork/jet/uiComponents-router-viewsNavList.html?root=book&chapter=chapter1
But this is working if the files are in the root of /views and /viewModels
What about if I would like to have then group together in a subfolder. Again, this is just to help visualizing the files for the developers, it doesn’t change the user experience.
When I try to put in the router
‘test/testsubfolder’: {label: ‘Test subfolder’},
I get this message: Error when executing transition: Invalid path “/test/testsubfolder”. State id “test” does not exist on router “root”.

I’m just starting with Oracle JET and I like it. It’s less confusing as this regroup many framework together. But the community is still small so it makes it a bit difficult at beginning.

Reply

Herman Brunnekreef July 4, 2016 at 9:55 am

Hi Manu,

I understand what you mean.
For example chart/piechart.js and chart/barchart.js. I tried some possibilities but I couldn’t get it work.
Did you post a request at the Oracle-JET forum: https://community.oracle.com/community/development_tools/oracle-jet

Maybe somebody else can help you. I’m interested in the solution.

Reply

Leave a Comment

 

Previous post:

Next post:

About Whitehorses
Company profile
Services
Technology

Whitehorses website

Home page
Whitebooks
Jobs

Follow us
Blog post RSS
Comment RSS
Twitter