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:
This is the startscreen of the application:
When “Table” is selected, there is a submenu where a user can make another selection:
When a choice is made in the subselect, you see the results:
If “Chart” is selected you see a chart:
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.
After selecting “Table” and choose the “Department” option, you can see the results are located under the subselect menu
When the “Chart” is selected in the menu you see the chart. Oracle JET automatically resize the bar’s of the chart
The “Chart” menu option without the menu shown
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.
{ 5 comments… read them below or add one }
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.
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.
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.
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.
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.