No results found

Your search did not match any results.

 

Developer | Java

Building Browser-Based UIs with Oracle JET

A look inside Oracle’s open source JavaScript toolkit

By John Brock


Oracle JavaScript Extension Toolkit, or Oracle JET as it’s more commonly called, is a modular toolkit based on a collection of open source libraries and open source code contributed by Oracle. It helps JavaScript developers build pure client-side user interfaces that consume and interact with web services such as REST and WebSocket. The toolkit is designed so you can use as little or as much as you need. It’s as non¬prescriptive in nature as possible.

Why should a Java developer even care about a JavaScript toolkit? With the increasing demand each year for developers to be versed in more aspects of the application stack, it’s becoming critical for Java developers to understand the client space as well as the traditional server space. Whether you are responsible for developing REST services that an application will integrate with or the full application, you will inevitably need to know something about how that JavaScript client is written. It could be only for testing purposes, but you will most likely need to know how things work in the browser at some point.

Oracle JET is designed to be a comfortable toolkit for the traditional JavaScript developer. Installation is provided through the Node.js npm and bower modules, while starter templates are provided by using a Yeoman generator. The steps that follow assume that you are familiar with JavaScript and with Node.js, and that you already have Node.js and Git installed on your system. (Note that Node.js is required only for the installation.)

To install and create your own Oracle JET application, open a terminal or command-prompt window and follow the steps below.

Using npm, install the following libraries:

npm install –g bower grunt-cli yo
npm install –g generator-oraclejet

Once you have the supporting libraries installed, you are ready to generate your first Oracle JET application by typing the following:

yo oraclejet <application name> --template=navdrawer

This command will create a subdirectory with the <applicationname> that you provided and then install and configure all the required files for the Oracle JET application, using one of many sample application shells as a template. In this case, it will use an application shell that works on both desktop and mobile web browsers. If everything goes correctly, you should see a prompt with wording similar to:

Oracle JET: Your app is ready! Change to your new app 
    directory [application name] and try grunt build 
    and serve…

Now that you have your application shell created, you can run the sample app and see how it looks in a browser. To do this from the terminal or command-prompt window, type the following commands in your application’s root directory:

grunt build
grunt serve 

The browser opens automatically (on localhost at port 8000). The application should show a mostly empty dashboard window when the browser opens.

If you resize the browser window or use the browser tools to render the content in mobile mode, you will see that the application shell is already configured as a responsive application and will change layout depending on the viewport size. Figure 1 shows this same dashboard in a simulated device environment (here, the “device toolbar” in the Developer Tools menu of Google Chrome).

Figure 1. The sample application in a simulated mobile environment

Figure 1. The sample application in a simulated mobile environment

Getting started is always the tricky part for anything new. With Oracle JET, you can use a helpful feature of the Oracle JET website called the Cookbook, which has recipes for all kinds of display components and widgets. Figure 2 shows some samples. The code in the Cookbook is live, so you can make changes to HTML, JavaScript, or CSS and see the changes with a simple click of the Apply button. This is a great way to learn about the API and various options for different UI components.

Figure 2. Cookbook samples

Figure 2. Cookbook samples

Once you are ready to add to your own code, you can simply copy and paste the HTML and JavaScript to your own application and continue your development.

For this example, I am going to add one text input field, a selection menu, a button, a radio button set, and a chart. The input field will take a city name; the selection menu will allow you to select a state; and the button will call a REST service to get all of the fueling stations offering alternative fuels in that city and state. The chart will display the returned data. Using radio buttons, you can select whether you want to see the results as a bar chart or a pie chart. You will also be able to click any of the items in the legend of the chart to show or hide that particular item. Figure 3 is what the final application looks like.

Figure 3. What the sample application will look like

Figure 3. What the sample application will look like

Note that out of the box, all Oracle JET UI components meet the Web Content Accessibility Guidelines (WCAG) 2.0 at the AA level. While this might not mean much to some developers, it should be a goal of all developers to write software that can be used by persons with or without disabilities. Beyond this just being the right thing to do, it’s also a requirement for many government and public sector customers, as well as many enterprises around the world.

Let’s take a look at the code behind the sample application. The architectural structure of an Oracle JET application follows the Model-View-View model (MVVM) pattern. MVVM is derived from the model-view-controller (MVC) pattern and is designed to separate development of the view layer (usually HTML) from the business logic and data layers (usually JavaScript and JSON, respectively). The toolkit is designed to be as modular as possible, thereby allowing developers to use as little or as much of it as they like. It provides a two-way data binding method based on the open source library Knockout.js. While Knockout is not required by Oracle JET, it is used heavily in samples and documentation as a default bind¬ing mechanism. UI components are wrapped as jQuery UI widgets, and a custom Knockout binding integrates those components into the larger MVVM pattern. jQuery UI was chosen because of the hundreds of third-party UI components available for it on the internet. These third-party components can be used with few issues in any Oracle JET–based application.

The inclusion of RequireJS with Oracle JET is to provide lazy loading of resources through the use of the Asynchronous Module Definition (AMD) API. With large enterprise-ready applications, which might have hundreds of JavaScript libraries, it is critical to performance to have the ability to manage the dependencies among those libraries as well as to load only specific libraries when they are needed.

The directory structure shown in Figure 4 is a common one with JavaScript and CSS in their respective /js and /css folders. Build scripts are kept separate in their own /scripts folder. All the main application code is placed under the /src folder so you can separate what would be included for source code management from what would be platform-specific.

Figure 4. The default directory structure

Figure 4. The default directory structure

Because Oracle JET is a pure client-side toolkit, the only way to consume and interact with remote data is via web services such as REST or WebSocket.

The starter templates provided by Oracle JET are set up to allow you to build for multiple platforms. You can build a web or mobile hybrid application from the same source code. Currently Android, iOS, and Windows are supported mobile platforms. At build time, native themes are added for the platform that you have selected, so the application’s form elements and other platform-specific theming automatically look like those of a native app. You can see a lot of this in action by changing the themes in the Cookbook on the Oracle JET website.

In addition to the accessibility features mentioned earlier (which also carry over to mobile apps), all Oracle JET UI components are touch- and gesture-enabled out of the box. If you have a touchscreen on your laptop, Oracle JET–based applications will work properly.

Looking at the code itself, you will notice that the index.html file provides the shell of the application, while the main content is actually loaded using a feature called ojModule. This design enables developers to think of their pages as separate modules that are loaded into the content area asynchronously when they are needed.

This approach allows for more-distributed work on an application, because different teams can work on different modules without stepping on each other’s code. An ojModule binding consists of its own HTML (view) and JavaScript (viewModel) file. As shown in Figure 4, there are separate directories for views and viewModels as part of the app structure. In this sample application, all code was added to the dashboard module (dashboard.html and dashboard.js files).

The dashboard view file is where you focus on writing your HTML code. Oracle JET is what is often referred to as an HTML forward toolkit. This means that you use the semantics of HTML5 itself to provide layout and structure to your application. This is in contrast to a JavaScript forward framework, where you would write JavaScript to generate your HTML. The business logic is handled in the dashboard viewModel file.

The following code excerpt is an example of what the view looks like:

<div class="oj-flex-item">
  <label id="groupLabel">Enter City and State</label>
  <div role="group" aria-labelledby="groupLabel" 
    class="oj-form-control-group">
    <input id="text-input" aria-label="city" 
      type="text"
      data-bind=
        "ojComponent: {component: 'ojInputText', 
                       value: cityVal}"/>
    <input id="text-input" aria-label="state" 
      type="text"
      data-bind=
        "ojComponent: {component: 'ojSelect', 
                       options: States,
                       value: selectVal}"/>
    <button data-bind=
      "ojComponent: {component: 'ojButton',
                     label:'Search'},
                     click:getData">
    </button>
  </div>
</div>

Notice that the getData method is bound to the click event for the Search button. The values for the input field and selection menu are also bound to values that are defined in the viewModel. This data binding functionality is provided by Knockout.

Looking at the viewModel, you can see that the Knockout observables are defined, along with their default values in the following code:

self.handleActivated = function (info) {
  self.cityVal = ko.observable('San Jose');
  self.chartType = ko.observable('pie');
  self.selectVal = ko.observableArray(['CA']);
  self.pieSeriesValue = ko.observableArray([]);
  self.groupsValue = ko.observableArray(['Fuel Types']);
  self.seriesValue = ko.observable();
  . . .

Knockout observables are special variables to which Knockout attaches listeners for the purpose of two-way data binding. You will recognize these variables because they are defined by ko.observable or ko.observableArray. If you change the value of one of these variables, anything bound to it on the view side of the application is automatically updated to the new value. The reverse is also true if you have bound the value of an editable component such as an input field. Once the user updates that field, the variable is updated and anything else bound to that same variable will be notified and updated as well. This is what two-way data binding is all about. You don’t need to worry about doing any kind of Document Object Model (DOM) manipulation in your JavaScript code to update the value of your UI components.

The getData() method that is called when the Search button is clicked is shown in the following code:

self.getData = function () {
  // using a Promise to allow the chart to 
  // render only once the data is available.
  self.seriesValue(new Promise(
   function (resolve, reject) {
     var url = 
      "https://api.data.gov/nrel/alt-fuel-stations" + 
      "/v1/nearest.json?location=" +
      + self.cityVal() + "+" + self.selectVal()+
      "&api_key=<your api key goes here>";
     $.getJSON(url).then(function (data) {
       var fuels = data.station_counts.fuels;
       var seriesData = [];
     for (var prop in fuels) {
       if (fuels[prop].total > 0) {
         seriesData.push({name: getFuelName(prop), 
           items: [fuels[prop].total] })
       }
     }
     resolve(seriesData);
    });
  }))
};

This code uses a JavaScript Promise to return the results of the call to the REST service after the data is actually ready. The Promise object is a new addition in the ECMAScript 2015 language specification (also known as ES6) that helps when you are working with asynchronous data such as REST calls.

Oracle has used Oracle JET as the foundation for more than 70 percent of its new cloud service offerings.

Because Oracle JET is a pure client-side toolkit, the only way to consume and interact with remote data is via web services such as REST or WebSocket. You can use any method you like for making the web service call. The most common way is to use jQuery Ajax methods or jQuery.getJSON, but you can use plain JavaScript XMLHttpRequest API calls as well. For more-complex data interactions—such as those used in applications that need to create, read, update, and delete (CRUD) data—Oracle JET provides a Common Model API that simplifies working with multiple types of data sources. You can read more about the Common Model API in the “Framework” section of the Oracle JET Cookbook.

If you would like to take a closer look at the sample application and run it in your own development environment, you can clone the project from GitHub. Installation and configuration steps are included in the README file for the project.

Conclusion

While Oracle JET has actually been around for more than three years, it has been available to the open source community for only about one year. Oracle has used Oracle JET as the foundation for more than 70 percent of its new cloud service offerings—so you know that it meets the needs of very large enterprise-scale applications.

Oracle JET is most powerful when you understand the concepts and ideas behind its creation. To get that understanding, you can read the developer’s guide or take the free online training course (login required). Both are great resources for beginners and developers. For announcements and interaction with others using Oracle JET, follow @oraclejet on Twitter or engage with other developers on the Oracle JET Community site.


John “JB” Brock has spoken at JavaOne, Oracle OpenWorld, and many Developer Days events over the last decade. He is a coauthor of Java EE and HTML5 Enterprise Application Development (McGraw-Hill, 2014), a two-time winner of the JavaOne Rock Star Award, and the senior product manager for Oracle JET.

This article originally was published in Java Magazine March/April 2017.