Add components to an Oracle JET virtual DOM app
Introduction
This tutorial shows you how to add Oracle JavaScript Extension Toolkit (Oracle JET) components to the Content
component in the basic
starter template of your Oracle JET virtual DOM app.
Oracle JET is a development toolkit that you use to build client-side virtual DOM apps. To use Oracle JET components in your virtual DOM app, use the Oracle JET Cookbook to locate the component samples that illustrate the specific functionality you want to add to your app. Although not optimized for JSX (the tag syntax used by virtual DOM apps), the Cookbook shows you the Oracle JET components and TypeScript code that you can use to infer the JSX equivalent in your Oracle JET virtual DOM app by, for example, showing the import statement that you need to use to include the component in your virtual DOM app.
Objectives
In this tutorial, you will learn how to use the Oracle JET Cookbook to add Oracle JET Select Single and Chart components to the Content
component of your virtual DOM app. You will also learn how to connect these two components to add interactivity between them.
Prerequisites
- A development environment set up to create Oracle JET virtual DOM apps that includes an installation of Node.js
- Completion of the previous tutorial in this learning path, Create an Oracle JET Virtual DOM App by Using a Starter Template
- Access to the Oracle JET Cookbook
Task 1: Add Style Classes
It is good practice to place styles that you want to apply to components in a separate CSS file rather than use the inline style
attribute demonstrated in the following example:
<oj-select-single
id="basicSelect"
style="max-width:20em"
data="{chartTypesDP}"
></oj-select-single>
Before we add the Select Single and Chart components to our page, we’ll create style classes in our app’s CSS file that the components can then reference.
-
Navigate to the
JET-Virtual-DOM-app/src/styles
directory and open theapp.css
file in an editor. -
At the end of the
app.css
file, add the following style classes that will determine style properties for the Select Single and Chart components..selectSingleStyle { max-width: 20em; } .chartStyle { max-width: 500px; width: 100%; height: 350px; }
Later in this tutorial, the Select Single and Chart components reference these styles using the component’s
class
attribute:<oj-select-single id="basicSelect" . . . class="selectSingleStyle" >. . . <oj-chart id="barChart" . . . class="chartStyle" >. . .</oj-chart ></oj-select-single >
Task 2: Add a Select Single Component
-
Navigate to the
JET-Virtual-DOM-app/src/components/content
directory and open theindex.tsx
file in an editor. -
At the top of the
index.tsx
file, import the Oracle JET modules for the MutableArrayDataProvider, the Label and Select Single components, plus the type definition for the Select Single component.import { h } from "preact"; import "ojs/ojlabel"; import "ojs/ojselectsingle"; import { ojSelectSingle } from "ojs/ojselectsingle"; import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider");
-
Within the HTML
div
element of theContent()
function, add an HTMLh1
element to display the header Product Information.. . . import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider"); export function Content() { return ( <div class="oj-web-applayout-max-width oj-web-applayout-content"> <h1>Product Information</h1> </div> ); }
-
Within the HTML
div
element of theContent()
function, add anotherdiv
element and, within this newerdiv
element, add anoj-label
element and anoj-select-single
element. Also add anid
attribute with a value ofitemDetailsContainer
to the newdiv
element.. . . <div class="oj-web-applayout-max-width oj-web-applayout-content"> <h1>Product Information</h1> <div id="itemDetailsContainer"> <oj-label for="basicSelect">Select Chart:</oj-label> <oj-select-single id="basicSelect" value="pie" class="selectSingleStyle" data={chartTypesDP} ></oj-select-single> </div> </div>
-
Before the
Content()
function, add a type alias for the chart types (ChartType
) and a chart type data array (chartTypesData
). Also before theContent()
function, add an instance of theMutableArrayDataProvider
class (chartTypesDP
) to allow binding of the chart type data by the Select Single component.. . . import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider"); type ChartType = { id: number; value: string; label: string; }; const chartTypeData = [ { value: "bar", label: "Bar" }, { value: "pie", label: "Pie" } ]; const chartTypesDP: MutableArrayDataProvider<ChartType["value"], ChartType> = new MutableArrayDataProvider(chartTypeData, { keyAttributes: "value" }); export function Content() { . . .
-
Save the
index.tsx
file.Your
index.tsx
code should look similar to add-select-single-index-tsx.txt. -
Open a terminal window, change to the
JET-Virtual-DOM-app
directory, and run the app.npx ojet serve
The browser displays the
basic
starter template with the Select Single component visible in your virtual DOM app. -
Leave the terminal window and the browser that displays your virtual DOM app open.
The Oracle JET command-line interface’s
serve
command lets you make changes to the code in theJET-Virtual-DOM-app/src
directory that are immediately reflected in the browser. One exception is that if you add or delete a file, you need to runnpx @oracle/ojet-cli serve
again to see the change reflected in the browser. Theserve
command builds and serves the content of theJET-Virtual-DOM-app/src
directory to theJET-Virtual-DOM-app/web
directory. Do not make changes to the code in theJET-Virtual-DOM-app/web
directory because you will overwrite these changes the next time that you run thenpx @oracle/ojet-cli serve
command.
Task 3: Add a Chart Component
-
In the open
index.tsx
file from theJET-Virtual-DOM-app/src/components/content
directory, import the module and the type definitions for the Oracle JET Chart component.import { h } from "preact"; import "ojs/ojlabel"; import "ojs/ojselectsingle"; import { ojSelectSingle } from "ojs/ojselectsingle"; import MutableArrayDataProvider = require("ojs/ojmutablearraydataprovider"); import "ojs/ojchart"; import { ojChart } from "ojs/ojchart"; . . .
-
Before the
Content()
function, add a type alias for the chart data (ChartItem
), a chart data array (chartData
), and an instance of theMutableArrayDataProvider
class (chartDataProvider
) to reference the data that the Chart component renders.. . . type ChartItem = { id: number; series: string; group: string; value: number; }; const chartData = [ { "id": 0, "series": "Baseball", "group": "Group A", "value": 42 }, { "id": 1, "series": "Baseball", "group": "Group B", "value": 34 }, { "id": 2, "series": "Bicycling", "group": "Group A", "value": 55 }, { "id": 3, "series": "Bicycling", "group": "Group B", "value": 30 }, { "id": 4, "series": "Skiing", "group": "Group A", "value": 36 }, { "id": 5, "series": "Skiing", "group": "Group B", "value": 50 }, { "id": 6, "series": "Soccer", "group": "Group A", "value": 22 }, { "id": 7, "series": "Soccer", "group": "Group B", "value": 46 } ] const chartDataProvider: MutableArrayDataProvider<ChartItem["id"], ChartItem> = new MutableArrayDataProvider(chartData, { keyAttributes: "id" }); export function Content() { . . .
-
Within the HTML
div
element of theContent()
function that has anid
attribute value ofitemDetailsContainer
, add theoj-chart
custom HTML element below theoj-select-single
custom HTML element such that the two elements appear inside theitemDetailsContainer
HTMLdiv
element.. . . <div class="oj-web-applayout-max-width oj-web-applayout-content"> <h1>Product Information</h1> <div id="itemDetailsContainer"> <oj-label for="basicSelect">Select Chart:</oj-label> <oj-select-single . . .></oj-select-single> <oj-chart id="barChart" type="bar" data={chartDataProvider} animationOnDisplay="auto" animationOnDataChange="auto" hoverBehavior="dim" class="chartStyle"></oj-chart> </div> </div>
-
Within the
oj-chart
custom HTML element, add an HTMLtemplate
element with aslot
attribute to render each item in the chart.. . . <div class="oj-web-applayout-max-width oj-web-applayout-content"> <h1>Product Information</h1> <div id="itemDetailsContainer"> <oj-label for="basicSelect">Select Chart:</oj-label> <oj-select-single . . .></oj-select-single> <oj-chart . . .> <template slot="itemTemplate" render={chartItem}></template> </oj-chart> </div> </div>
-
Before the
return
statement in theContent()
function, add the following code to render the chart item data.. . . export function Content() { const chartItem = ( item: ojChart.ItemTemplateContext<ChartItem["id"], ChartItem> ) => { return ( <oj-chart-item value={item.data.value} groupId={[item.data.group]} seriesId={item.data.series}></oj-chart-item> ); }; return (
-
Save the
index.tsx
file.Your
index.tsx
file should look similar to final-chart-index-tsx.txt. -
Return to the browser to view the changes in your virtual DOM app.
The browser displays the
basic
starter template with the Chart component rendering a bar chart in your virtual DOM app.Notice that the virtual DOM app displays only the bar chart format for each Select Chart dropdown list option. You must add a dependency between the two components so that the Chart component responds to the selection event in the Select Single component.
-
Leave the terminal window and the browser that displays your virtual DOM app open.
Task 4: Connect the Two Components
-
In the open
index.tsx
file from theJET-Virtual-DOM-app/src/components/content
directory, import theuseState
anduseCallback
hooks andComponentProps
from Preact.import { h, ComponentProps } from "preact"; import { useState, useCallback } from "preact/hooks"; . . .
-
Before the
Content()
function, add a type alias for the chart properties (ChartProps
).type ChartProps = ComponentProps<"oj-chart">; export function Content() { . . .
-
Within the
Content()
function, add code to set an initial value ofbar
for the Select Single component using Preact’suseState
hook and include Preact’suseCallback
hook to pass newly-selected chart types back to theuseState
hook.export function Content() { const [val, setVal] = useState("pie" as ChartProps["type"]); const valChangeHandler = useCallback( (event: ojSelectSingle.valueChanged<ChartType["value"], ChartType>) => { setVal(event.detail.value as ChartProps["type"]); }, [val, setVal] ); . . .
-
Within the
itemDetailsContainer
HTMLdiv
element of theContent()
function, update theoj-select-single
andoj-chart
custom attribute values to reference the current selected value (val
) and an event handler (valChangeHandler
) that is called when a user selects a new chart type.<div id="itemDetailsContainer"> . . . <oj-select-single id="basicSelect" . . . value={val} onvalueChanged={valChangeHandler} ></oj-select-single> <oj-chart id="barChart" type={val} . . .>
-
Save the
index.tsx
file.Your
index.tsx
file should look similar to final-connect-index-tsx.txt. -
Return to the browser to view the changes in your virtual DOM app.
The browser now displays the
basic
starter template with the Select Single and Pie Chart components visible in your virtual DOM app. -
To see the different chart formats, choose between the options in the Select Chart dropdown list.
-
Close the browser window or tab that displays your running virtual DOM app.
-
In the terminal window, press Ctrl+C, and, if prompted, enter
y
to terminate the Oracle JET tooling batch job. -
Leave the terminal window open for your next tutorial.
Next Step
To proceed to the next tutorial in this learning path, click here.
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Add components to an Oracle JET virtual DOM app
F61017-03
February 2025
Copyright ©2024,2025, Oracle and/or its affiliates.