Understand Oracle JET User Interface Basics

Oracle JET User Interface (UI) components extend the htmlElement prototype to implement the World Wide Web Consortium (W3C) web component specification for custom elements. Custom elements provide a more declarative way of working with Oracle JET components and allow you to access properties and methods directly on the DOM layer.

About the Oracle JET User Interface

Oracle JET includes components, patterns, and utilities to use in your app. The toolkit also includes an API specification (if applicable) and one or more code examples in the Oracle JET Cookbook.

Identify Oracle JET UI Components, Patterns, and Utilities

The Oracle JET Cookbook lists all the components, design patterns, and utilities available for your use. By default, the cookbook is organized into functional sections, but you can also click Sort to arrange the contents alphabetically.

The Cookbook contains samples that you can edit online and see the effects of your changes immediately. You’ll also find links to the API documentation, if applicable.

About Common Functionality in Oracle JET Components

All Oracle JET components are implemented as custom HTML elements, and programmatic access to these components is similar to interacting with any HTML element.

Custom Element Structure

Oracle JET custom element names start with oj-, or oj-c- for the newer Core Pack components, and you can add them to your page the same way you would add any other HTML element. In the following example, the oj-label and oj-input-date-time custom elements are added as child elements to a standard HTML div element.

<div id="div1">
  <oj-label for="dateTime">Default</oj-label>
  <oj-input-date-time id="dateTime" value='{​{value}​}'>
  </oj-input-date-time>
</div>

Each custom element can contain one or more of the following:

A custom element will be recognized only after its module is loaded by the app. Once the element is recognized, Oracle JET will register a busy state for the element and will begin the process of upgrading the element from a normal element to a custom element. The element will not be ready for interaction until the upgrade process is complete. The app should listen to either the page-level or element-scoped BusyContext before attempting to interact with any JET custom elements. However, property setting (but not property getting) is allowed before the BusyContext is initialized. See the BusyContext API documentation on how BusyContexts can be scoped.

The upgrade of custom elements relies on a binding provider which manages the data binding. The binding provider is responsible for setting and updating attribute expressions. Any custom elements within its managed subtree will not finish upgrading until the provider applies bindings on that subtree. By default, there is a single binding provider for a page, but subtree specific binding providers can be added by using the data-oj-binding-provider attribute with values of none and knockout. The default binding provider is knockout, but if a page or DOM subtree does not use any expression syntax or knockout, the app can set data-oj-binding-provider=”none" on that element so that its dependent JET custom elements do not wait for bindings to be applied to finish upgrading.

Other Common Functionality

Oracle JET custom elements also have the following functionality in common:

Add the deferred content to the app's view and ViewModel, content.html and content.js, as specified in the oj-module definition. For the complete code example, see Collapsibles - Deferred Rendering.

For a list of custom elements that support oj-defer, see oj-defer.

Custom Element Examples and References

The Oracle JET Cookbook and API Reference for Oracle® JavaScript Extension Toolkit (Oracle JET) provide examples that illustrate how to work with custom elements. In addition, the Cookbook provides demos with editing capability that allow you to modify the sample code directly and view the results without having to download the sample.

To learn more about the World Wide Web Consortium (W3C) web component specification for custom elements, see Custom Elements.

About Oracle JET Reserved Namespaces and Prefixes

Oracle JET reserves the oj namespace and prefixes for the original set of UI components that predate the introduction of the Oracle JET Core Pack components in release 14.0.0. This includes, but is not limited to component names, namespaces, pseudo-selectors, public event prefixes, CSS styles, Knockout binding keys, and so on. Oracle JET also reserves the oj-c namespace for the newer Core Pack components.

About Binding and Control Flow

Oracle JET includes components and expressions to easily bind dynamic elements to a page in your app using Knockout.

Use oj-bind-text to Bind Text Nodes

Oracle JET supports binding text nodes to variables using the oj-bind-text element and by importing the ojknockout module.

The oj-bind-text element is removed from the DOM after binding is applied. For example, the following code sample shows an oj-input-text and an oj-button with a text node that are both bound to the buttonLabel variable. When the input text is updated, the button text is automatically updated as well.

<div id='button-container'>
   <oj-button id='button1'>
      <span><oj-bind-text value="[[buttonLabel]]"></oj-bind-text></span>
   </oj-button>
   <br><oj-label for="text-input">Update Button Label:</oj-label>
   <oj-input-text id="text-input" value="{​{buttonLabel}​}"></oj-input-text>
</div>

The script to create the viewModel for this example is shown below.

The figure below shows the output for the code sample.

A web page interface showing two buttons with labels "My Button" and "Click Me!" and an arrow pointing to the second button, with instructions to update the button label.

Description of the illustration binding-text-rw.png

The Oracle JET Cookbook contains the complete example used in this section. See Text Binding.

Bind HTML Attributes

Oracle JET supports one-way attribute data binding for attributes on any HTML element by prefixing ":" to the attribute name and by importing the ojknockout module.

To use an HTML attribute in an HTML or JET element, prefix a colon to it. JET component–specific attributes do not need the prefix.

The following code sample shows two JET elements and two HTML elements that use both the prefixed and non-prefixed syntax. Since the label and input elements are native HTML elements, all their data bound attributes should use the colon prefixing. The oj-label and oj-input-text elements use the prefix only for native HTML element attributes and the non-prefixed syntax for component-specific attributes.

    <div id="demo-container">
      <oj-label for="[[inputId1]]">oj-input-text element</oj-label>
      <oj-input-text :id="[[inputId1]]" value="{​{value}​}"></oj-input-text>
      <br><label :for="[[inputId2]]">HTML input element</label>
      <br><input :id="[[inputId2]]" :value="[[value]]" style="width:100%;max-width:18em"/>
    </div>

The script to create the viewModel for this example is shown below.

The figure below shows the output for the code sample.

A comparison of two text input elements, showing the difference between an OJ input text element and an HTML input element, with both displaying the text "This text value is bound."

Description of the illustration binding-attribute-rw.png

The Oracle JET Cookbook contains the complete example used in this section. See Attribute Binding.

Use oj-bind-if to Process Conditionals

Oracle JET supports conditional rendering of elements by using the oj-bind-if element and importing the ojknockout module.

The oj-bind-if element is removed from the DOM after binding is applied, and must be wrapped in another element such as a div if it is used for slotting. The slot attribute has to be applied to the wrapper since oj-bind-if does not support it. For example, the following code sample shows an image that is conditionally rendered based on the option chosen in an oj-buttonset.

<div id="demo-container">
<oj-buttonset-one class="oj-buttonset-width-auto" value="{​{buttonValue}​}">
  <oj-option id="onOption" value="on">On</oj-option>
  <oj-option id="offOption" value="off">Off</oj-option>
</oj-buttonset-one>
<br><div>Image will be rendered if the button is on:</div>
<oj-bind-if test="[[buttonValue() === 'on']]">
  <oj-avatar role="img" aria-label="Avatar of Amy Bartlet" size="md" initials="AB"
	src="../css/images/avatar-image.jpg" class="oj-avatar-image"></oj-avatar>
</oj-bind-if>
</div>

In the above example, the oj-avatar element is an icon which can display a custom or placeholder image. See oj-avatar.

The script to create the view model for this example is shown below.

The figure below shows the output for the code sample. When the oj-buttonset is set to 'on', the oj-avatar element is rendered and displayed.

Toggle button in the "On" position with an arrow pointing to a second toggle button in the "Off" position, followed by a profile picture of a smiling woman.

Description of the illustration binding-if.png

The Oracle JET Cookbook contains the complete example used in this section. See If Binding.

Use oj-bind-for-each to Process Loop Instructions

Oracle JET supports processing loop instructions, such as binding items from an array by using the oj-bind-for-each element and by importing the ojknockout module.

The oj-bind-for-each element only accepts a single template element as its direct child. Any markup to be duplicated, such as li tags, must be placed inside the template tag. For example, the following code sample shows an unordered list nested inside another unordered list. The list items are created using an oj-bind-text tag inside nested oj-bind-for-each elements.

<div id="form-container">
  <ul>
    <oj-bind-for-each data="[[categories]]">
      <template data-oj-as="category">
        <li>
          <ul>
            <oj-bind-for-each data="[[category.data.items]]">
              <template data-oj-as="item">
                <li>
                  <oj-bind-text value="[[category.data.name 
                           + ' : ' + item.data]]"></oj-bind-text>
                </li>
              </template>
            </oj-bind-for-each>
          </ul>
        </li>
      </template>
    </oj-bind-for-each>
  </ul>
</div>

In the above example, the data-oj-as attribute provides an alias for the bound data. These aliases (category and item) are referenced in the nested oj-bind-for-each and oj-bind-text elements. If you do not use the data-oj-as attribute to provide an alias, you must use $current instead. In that case, your code becomes:

. . . 
<oj-bind-for-each data="[[categories]]">
 <template>
  <li>
   <ul>
    <oj-bind-for-each data="[[$current.data.items]]">
. . .

The script to create the viewModel for this example is shown below.

The figure below shows the output for the code sample.

List of fruits and vegetables including Apple, Orange, Banana, Celery, Corn, and Spinach.

Description of the illustration binding-foreach-rw.png

The Oracle JET Cookbook contains the complete example used in this section. See Foreach Binding.

Bind Style Properties

The Oracle JET attribute binding syntax also supports style attributes, which can be passed as an object or set using dot notation. The ojknockout module must be imported.

The style attribute binding syntax accepts an object in which style properties should be referenced by their JavaScript names. Apps can also set style sub-properties using dot notation, which uses the CSS names for the properties. The code sample below shows two block elements with style attributes. The first element binds a style object, while the second binds properties directly to the defined style attributes.

<div id="demo-container">
  <div :style="[[style]]">Data bound style attribute</div>
  <br><div :style.color="[[fontColor]]" :style.font-style="[[fontStyle]]">Data bound style using dot notation</div>
</div>

The script to create the viewModel for this example is shown below. The style object referenced above is highlighted below.

The figure below shows the output for the code sample.

Here is the alt text for the image:

**Alt text:** 
A heading in red text reads "Data bound style attribute" followed by a subheading in blue text stating "Data bound style using dot notation".

This alt text is concise, factual, and useful for accessibility, as it accurately describes the content of the image without being overly verbose.

Description of the illustration binding-style-rw.png

The Oracle JET Cookbook contains the complete example used in this section. See Style Binding.

Bind Event Listeners to JET and HTML Elements

Oracle JET provides one-way attribute data binding for event listeners on JET and HTML elements using the on-[eventname] syntax and by importing the ojknockout module.

Oracle JET event attributes provide two key advantages over native HTML event listeners. First, they provide three parameters to the listener:

Second, they have access to the model state and can access functions defined in the viewModel using the data and bindingContext parameters.

The this context is not directly available in the event listeners. This is the same behavior as native HTML event listeners.

For example, the following code sample shows an oj-c-button element that uses the on-oj-action event attribute and an HTML button element that uses the on-click event attribute to access custom functions defined in the viewModel shown below.

<div id="demo-container">
  <oj-label for="button1">oj-c-button element</oj-label>
  <oj-c-button id="button1" label="Click me!" on-oj-action="[[clickListener1]]"></oj-c-button>
  <br><label for="button2">HTML button element</label>
  <br><button id="button2" on-click="[[clickListener2]]">Click me!</button>
  <br><div style="font-weight:bold;color:#ea5b3f;">
    <oj-bind-text value="[[message]]"></oj-bind-text>
  </div></div>

HTML events use the prefix “on”, such as onclick and onload. JET events use the prefix “on-”, such as on-click and on-load.

The script to create the viewModel for this example is shown below. Note the usage of the data attribute to access the message parameter.

The figure below shows the output for the code sample.

Image showing a comparison of button elements in OJ-C and HTML. The top section displays two buttons labeled "Click me!" with the OJ-C button on the left and the HTML button on the right. Two arrows point downward from the top section to two separate sections below. The left section shows the OJ-C button in a clicked state with a gray background and the text "oj-c-button is clicked" in red. The right section shows the HTML button in a clicked state with a gray background and the text "HTML button is clicked" in red.

Description of the illustration binding-event.png

The Oracle JET Cookbook contains the complete example used in this section. See Event Binding.

Bind Classes

The Oracle JET attribute binding syntax has enhanced support for the class attribute, which can be used to set classes on components. The attribute accepts a string, an object, or an array. The ojknockout module must be imported.

The :class attribute binding supports expressions that resolve to a space-delimited string, an array of classes, or an object whose keys are individual style classes and whose values are booleans or expressions used for adding and removing the classes in the DOM. Only object values can be used to toggle classes on and off, whereas array and string values are used only to set classes.

For example, the following code sample shows an oj-input-text and an HTML input that both use the :class attribute.

<oj-label for="input1">oj-input-text element</oj-label>
<oj-input-text
  id="input1"
  :class="[[{'oj-form-control-text-align-right': alignRight}]]"
  value="Text Content"></oj-input-text>
<br />
<br />
<oj-c-button
  id="button2"
  label="Toggle Alignment"
  on-oj-action="[[clickListener2]]">
</oj-c-button>
<br />
<br />
<br />
<label for="input2">HTML input element</label>
<br />
<input
  id="input2"
  :class="[[classArrayObs]]"
  value="Text Content"
  class="demo-width"/>
<br />
<br />
<oj-c-button
  id="button1"
  label="Add Class"
  on-oj-action="[[clickListener1]]">
</oj-c-button>

The script to create the viewModel for this example is shown below.

The figure below shows the first of the two outputs for the code sample. The button acts as a toggle to switch on and off the oj-form-control-text-align-right class property and so change the alignment of the text.

Toggle button for alignment class on oj-input-text element

Description of the illustration binding-class-2-rw.png

The figure below shows the second of the two outputs for the code sample. The button calls a function to take a predefined array of classes and add them to the input element. Each class has CSS modifications that come into effect when the class is added.

Here is the alt text for the documentation image:

A diagram illustrating how to add a new class to an HTML input element using the "Add Class" button. The image shows three HTML input elements with text content, connected by arrows, demonstrating the process of updating the class attribute with additional CSS classes.

Description of the illustration binding-class-1-rw.png

The Oracle JET Cookbook contains the complete example used in this section. See Class Binding.

Add an Oracle JET Component to Your Page

Use the Oracle JET Cookbook recipes and API documentation to locate examples that illustrate the specific element and functionality you want to add to your page.

If you have not already, create the app that you will use for this exercise.

Use the following procedure to add an Oracle JET custom element to your page:

  1. In the Oracle JET Cookbook, find the JET element that you want to add to your app. For this example, we will add the oj-input-date-time element using the Date and Time Pickers Cookbook demo.

  2. Follow the Cookbook recipe for your element and add the markup to your HTML page. Modify the attributes as needed.

    <div id="div1">
      <oj-label for="dateTime">oj-input-date-time</oj-label>
      <oj-input-date-time id="dateTime" value='{​{value}​}'>
      </oj-input-date-time>
          
      <br/><br/>
          
      <span class="oj-label">Current component ISO string value is:</span>
      <span><oj-bind-text value="[[value]]"></oj-bind-text></span>        
    </div>

    In this example, the oj-input-date-time element is declared with its value attribute using the {​{...}​} expression syntax, which indicates that changes to the value will update the corresponding value in the viewModel. Each Oracle JET custom element includes additional attributes that are defined in the custom element's API documentation.

  3. In your page's viewModel file, import the element and add any required scripts. Reference the Cookbook for example scripts and correct syntax. Each Cookbook component demo includes a tabbed interface where you can access both the JavaScript and TypeScript versions of the viewModel code.

    Add the JavaScript or TypeScript code appropriate for your app to your viewModel file.

  4. Once you are satisfied with the state of your code, run your app to test the added component. If you have problems adding the component, refer to both the Cookbook and the API documentation for your component. You can directly access each JET component's API documentation through its Cookbook demo page.

Add Animation Effects

You can use the oj-module component’s animation property in conjunction with the ModuleAnimations namespace to configure animation effects when the user transitions between or drills into views. If you’re not using oj-module, you can use the AnimationUtils namespace instead to add animation to Oracle JET components or HTML elements.

Adding Animation Effects Using the oj-module Component

The ModuleAnimations namespace includes pre-configured implementations that you can use to configure the following animation effects:

For examples that illustrate how to add animation with the oj-module component, see Animation Effects with Module Component.

Adding Animation Effects Using AnimationUtils

The AnimationUtils namespace includes methods that you can use to configure the following animation effects on HTML elements and Oracle JET components:

Depending on the method’s options, you can configure properties like delay, duration, and direction. For examples that illustrate how to configure animation using the AnimationUtils namespace, see Animation Effects.

Manage the Visibility of Added Component

Follow the recommended best practice when you programmatically manage the display of Oracle JET components in the DOM.

If you manage the display of collection components and other complex component by using the CSS display property values of none or block, you may also need to use Components.subtreeHidden(node) when you hide a component and Components.subtreeShown(node) when you display the component. The node parameter refers to the root of the subtree in the DOM for the component that you are hiding or displaying. You need to notify Oracle JET if you change the display status of these types of component to ensure that the component instance continues to work correctly in the app.

Not all components where you programmatically manage the display require you to notify Oracle JET when you change their display state. Components such as oj-collapsible, oj-dialog, and oj-popup are examples of components where you do not need to call Components.subtreeHidden(node) or Components.subtreeShown(node). These components manage rendering when visibility is changed and also manage any components that they contain. Similarly, you do not need to use these methods in conjunction with the oj-bind-if component because Oracle JET rewrites the appropriate part of the DOM in response to the evaluation of the oj-bind-if component’s test condition.

Failure to use the subtreeHidden and subtreeShown methods to notify Oracle JET when you hide or show a component can result in unexpected behavior for the component, such as failure to render data or failure to honor other component attribute settings. For more information about the subtreeHidden and subtreeShown methods, see API Reference for Oracle® JavaScript Extension Toolkit (Oracle JET).