// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= Strategies for Intermodular Communication in Oracle JET
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Strategies for Intermodular Communication in Oracle JET - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Strategies for Intermodular Communication in Oracle JET

This document provides a step-by-step set of instructions guiding you through the different approaches for communicating between modules defined by the link:http://oraclejet.org[+Oracle JavaScript Extension Toolkit (JET)+]. JET empowers web and mobile developers by providing a modular toolkit based on modern JavaScript, CSS3, and HTML5 design and development principles.


== Setting Up an Oracle JET Application

In this exercise you set up an Oracle JET application.

1. Follow the steps described in link:ojet-settingup.html[+Setting Up an Oracle JET Application+].


[start=2]
. Open the project into an editor or IDE of your choice, such as NetBeans IDE, which displays the application as follows:

image::images/navdrawer.png[]

Spend some time browsing through the application structure before continuing.


== Global Variables

In this exercise, you learn about where and how to set global variables in an Oracle JET application.

1. Knockout.js has the concept of a "binding context", which are global objects that can be referenced throughout your application. Spend some time learning about link:http://knockoutjs.com/documentation/binding-context.html[+the binding context here+].


[start=2]
. In any of your Oracle JET module's views, i.e., any of the HTML files that define the view of the Oracle JET modules, add the following:


[source,html]
----

<p>User Login Name: <input data-bind="textInput: *$root.userLogin*"></input></p>
----

Take note of the  ``$root``  binding context in the above.


[start=3]
. In the browser, notice there is already content in the input field. Make a change in the input field and notice that something in the menubar changes!


[start=4]
. Open the  ``appController.js``  file in the  ``src/js``  file. In that file, notice the following property has been defined:


[source,java]
----

self.userLogin = ko.observable("john.hancock@oracle.com");
----

[start=5]
. 
Create a new global variable, as follows:


[source,java]
----

self.stepArray = 
        ko.observableArray(
                [{label:'Step 1', id:'dashboard'},
                 {label:'Step 2', id:'customers'},
                 {label:'Step 3', id:'incidents'},
                 {label:'Step 4', id:'about'}]);
----

In the  ``index.html``  file, replace  ``ojNavigationList``  with  ``ojTrain`` , as follows:


[source,html]
----

<div id="train" 
       class="oj-train-stretch" 
       style="max-width:1500px;margin-left:auto;margin-right:auto;"
       data-bind="ojComponent:{
         component: 'ojTrain', 
         selectedStep: router.stateId, 
         steps: stepArray}">
</div>
----

Make sure to include  ``ojs/ojtrain``  in the  ``require``  block in  ``main.js`` .

In the browser, notice that you have now replaced the navigation list with a train-based step component:

image::images/ojtrain.png[]


[start=6]
. Create your own global variable and refer to it in your Oracle JET application.

The  ``src/js/appController.js``  file is the central location in an Oracle JET application where global variables are defined and from which they can be accessed throughout the application.


== Unobtrusive Event Handling

If you need to get at a value that is being used in a different JavaScript file (not in the HTML file, as shown in the previous scenario above), you can take a look at the Knockout  ``dataFor``  and  ``contextFor``  methods.

1. Knockout.js has the concept of a "binding context", which are global objects that can be referenced throughout your application. Spend some time learning about link:http://knockoutjs.com/documentation/binding-context.html[+the binding context here+].


[source,java]
----

var rootViewModel = ko.dataFor(document.getElementById('globalBody'));
self.userLogin = rootViewModel.userLogin;
----

If you're wondering where the element ID  ``globalBody``  comes from, take a look in your  ``index.html``  file.


[start=2]
. Now, instead of needing to refer to the  ``$root``  binding context, you have a normal Knockout.js observable property that you can reference instead:


[source,html]
----

<p>Name: <span data-bind="text: *userLogin*"></span></p>
----

[start=3]
. 
Similarly, you can now get hold of the router and use it as follows:


[source,java]
----

var rootViewModel = ko.dataFor(document.getElementById('globalBody'));
rootViewModel.router.go('dashboard');
----

A different approach is to load the  ``appController.js``  via the  ``define``  block and use it after referencing it in the callback function.

Make the above changes in your application and check that everything still works.


== Publish/Subscribe with Knockout Postbox

In this exercise, you integrate and use link:https://github.com/rniemeyer/knockout-postbox[+knockout-postbox+] in your Oracle JET application.

1. In your  ``package.json``  file, include  ``knockout-postbox`` :

[source,java]
----

"knockout-postbox": "0.6.0"
----

[start=2]
. In your  ``scripts/grunt/config/oraclejet-build.js``  file, include  ``knockout-postbox``  in the  ``ojet build``  process:

[source,java]
----

copyCustomLibsToStaging: {
  fileList: [
   {
     cwd:'node_modules/knockout-postbox/build',
     src: ['*'],
     dest: 'web/js/libs/knockout-postbox'
   }
  ]
 },
----

[start=3]
. 
When you run  ``ojet-build`` , you should see  ``knockout-postbox``  in  ``web/js/libs`` .


[start=4]
. Include the library in  ``main.js`` , in the  ``requirejs.config section`` :


[source,java]
----

'knockout-postbox': 'libs/knockout-postbox/knockout-postbox'
----

[start=5]
. 
In the JavaScript files of the Oracle JET modules where you want to use it, include  ``'knockout-postbox'``  in the  ``define``  block. Or maybe consider whether it should be loaded in the  ``require``  block in the  ``main.js``  file.


[start=6]
. Now you can use  ``knockout-postbox`` , as described on its home page: link:https://github.com/rniemeyer/knockout-postbox[+https://github.com/rniemeyer/knockout-postbox+]. For example:
* *Publish.* In one of your Oracle JET modules, publish like this, in the  ``handleDetached``  lifecycle method:

[source,java]
----

self.name = ko.observable("John");

self.handleDetached = function(info) {
    ko.postbox.publish("currentUser", 
    {   
        'name': self.name()
    });
};
----

You could have an Oracle JET component, such as the following, for changing the value in the module:


[source,java]
----

Name: <input id="text-input" 
             type="text"
             data-bind="ojComponent: {component: 'ojInputText', value: name}"/>
----
* *Subscribe.* In one of your other Oracle JET modules, subscribe to the "currentUser" message published above, as follows:

[source,javascript]
----

self.name = ko.observable();

ko.postbox.subscribe("currentUser", function (newValue) {
    self.name(newValue.name);
});
----

Finally, render changes to the message as follows in the module where you subscription code is found:


[source,xml]
----

Name: <span data-bind="text: name"></span>
----

Congratulations! You have now learned different approaches for setting up communication between Oracle JET modules.

link:/about/contact_form.html?to=3&subject=Feedback:%20Getting%20Started%20with%20Oracle%20JET%20Applications[+Send Feedback on This Tutorial+]




[[seealso]]
== See Also

For more information about support for Oracle JET and a variety of HTML5 applications in the IDE on link:https://netbeans.org/[+netbeans.org+], see the following resources:

* link:http://www.oracle.com/webfolder/technetwork/jet/globalExamples.html[+"Learn" section on the Oracle JET site+]. A set of official Oracle JET learning resources.
* link:html5-editing-css.html[+Working with CSS Style Sheets in HTML5 Applications+]. A document that continues with the application that you created in this tutorial that demonstrates how to use some of the CSS wizards and windows in the IDE and how to use the Inspect mode in the Chrome browser to visually locate elements in your project sources.
* link:html5-js-support.html[+Debugging and Testing JavaScript in HTML5 Applications+]. A document that demonstrates how the IDE provides tools that can help you debug and test JavaScript files in the IDE.
