Create a form to create data records in an Oracle JET web app
Introduction
This tutorial shows you how to use your Oracle JavaScript Extension Toolkit (Oracle JET) web app to create a data record and submit it to a REST service.
Objectives
In this tutorial, you will learn how to write data to a REST service.
Prerequisites
- A development environment set up to create Oracle JET web apps that includes an installation of Node.js
- Completion of the previous tutorial in this learning path, Fetch Data from the REST API in Oracle JET
Task 1: Create a Dialog Box in the View
Use the oj-dialog custom HTML element to collect form information that you then pass to an observable.
-
Navigate to the
JET_Web_Application/src/ts/viewsdirectory and open thedashboard.htmlfile in an editor. -
Find the
h3element whereid="itemsListHeader". Below it, add anoj-buttonelement and set theon-oj-actionattribute to"[[showCreateDialog]]".<h3 id="itemsListHeader">Activity Items</h3> <oj-button id="createButton" on-oj-action="[[showCreateDialog]]">Create</oj-button> -
Find the
oj-bind-if test="[[itemSelected()]]"element and, above it, add anoj-dialogelement. Set theidattribute to"createDialog"and the style to"display:none".. . . </oj-list-view> </div> <oj-dialog id="createDialog" style="display: none" dialog-title="Create New Item" cancel-behavior="icon"> </oj-dialog> <oj-bind-if test="[[itemSelected()]]"> <div id="itemDetailsContainer" class="oj-flex-item oj-md-6 oj-sm-12"> . . . - Inside the
oj-dialogelement you created, add two childdivelements with theslot="body"andslot="footer"attributes.<oj-dialog id="createDialog" style="display: none" dialog-title="Create New Item" cancel-behavior="icon" > <div slot="body"></div> <div slot="footer"></div> </oj-dialog> - Add an
oj-buttonelement inside thediv slot="footer"element you created, and set theon-oj-action="[[createItem]]"attribute.<div slot="footer"> <oj-button id="submitBtn" on-oj-action="[[createItem]]">Submit</oj-button> </div> -
Inside the
div slot="body"element you created, add anoj-labelelement and anoj-input-textelement each for theActivity IDandNamevalues.<div slot="body"> <oj-label class="oj-label oj-label-value" for="createActivityId">Activity ID</oj-label> <oj-input-text id="createActivityId" readonly value="[[activityKey]]"></oj-input-text> <oj-label class="oj-label" for="name">Name</oj-label> <oj-input-text id="name" value="{{itemName}}"></oj-input-text> </div>Note that you bind the
activityKeyvalue using square brackets, which indicates one-way binding, because the user should not edit the activity ID value. You bind theitemNamevalue using curly brackets, which indicates two-way binding and allows the user to overwrite the value. -
Similarly, below the
oj-input-text id="name"custom HTML element you created, addoj-input-textelements for the remaining values (price, short_desc, and so on).<div slot="body"> <oj-label class="oj-label oj-label-value" for="createActivityId">Activity ID</oj-label> <oj-input-text id="createActivityId" readonly value="[[activityKey]]"></oj-input-text> <oj-label class="oj-label" for="name">Name</oj-label> <oj-input-text id="name" value="{{itemName}}"></oj-input-text> <oj-label class="oj-label" for="price">Price</oj-label> <oj-input-text id="price" value="{{price}}"></oj-input-text> <oj-label class="oj-label" for="short_desc">Description</oj-label> <oj-input-text id="short_desc" value="{{short_desc}}"></oj-input-text> <oj-label class="oj-label" for="quantity_instock">Quantity: In-Stock</oj-label> <oj-input-text id="quantity_instock" value="{{quantity_instock}}"></oj-input-text> <oj-label class="oj-label" for="quantity_shipped">Quantity: Shipped</oj-label> <oj-input-text id="quantity_shipped" value="{{quantity_shipped}}"></oj-input-text> </div> -
Save the
dashboard.htmlfile.Your code should look similar to this final-create-dashboard-html.txt file.
Task 2: Handle Opening the Dialog in the ViewModel
Declare the new observables and functions you referenced in the view so that your Oracle JET web app successfully initializes when you serve it.
-
Navigate to the
JET_Web_Application/src/ts/viewModelsdirectory and open thedashboard.tsfile in an editor. -
At the top of the
dashboard.tsfile, import the Oracle JET modules for the Button, Dialog, and Input Text components.import * as AccUtils from "../accUtils"; . . . import { ojDialog } from "ojs/ojdialog"; import "ojs/ojdialog"; import "ojs/ojinputtext"; import { ojButtonEventMap } from "ojs/ojbutton"; . . . -
In the list of observables, declare and initialize observables for the fields in the create dialog.
class DashboardViewModel { . . . // Fields in Create dialog itemName: ko.Observable<string | null>; price: ko.Observable<number | null>; short_desc: ko.Observable<string | null>; quantity_instock: ko.Observable<number | null>; quantity_shipped: ko.Observable<number | null>; quantity: number; inputImageFile: string = "css/images/product_images/jet_logo_256.png"; . . . constructor() { . . . // Initialize fields in create dialog this.itemName = ko.observable(null); this.price = ko.observable<number>(null); this.short_desc = ko.observable<string>(null); this.quantity_instock = ko.observable<number>(null); this.quantity_shipped = ko.observable<number>(null); this.quantity = 0; // inputImageFile has already been initialized. } // Closing bracket for constructor method -
Below the
constructor()method, add a method namedshowCreateDialogfor opening the dialog.. . . constructor() { . . . } // Closing bracket for constructor method // Open dialog public showCreateDialog(event: ojButtonEventMap["ojAction"]) { (document.getElementById("createDialog") as ojDialog).open(); } -
Below the
showCreateDialogmethod you created, add a method calledcreateItemfor submitting the dialog data, and add a close command.// Create item and close dialog public createItem = async (event: ojButtonEventMap["ojAction"]) => { (document.getElementById("createDialog") as ojDialog).close(); } -
Save the
dashboard.tsfile.Your code should look similar to this create-dashboard-ts.txt file.
-
In the terminal window, run and test your web app.
npx ojet serveThe Activity Items panel now contains a Create button. When you click it, a dialog opens.

-
Leave the terminal window and the browser window that displays your web app open.
Task 3: Handle Submitting the Dialog Input in the ViewModel
Retrieve the data from the dialog in your viewModel, send it to your REST service using the Fetch API and the HTTP POST method, and finally use the mutate method of the RESTDataProvider class to update your RESTDataProvider instance.
-
In the open
dashboard.tsfile, in thecreateItemmethod above theclose()call, declare variables to hold the input values from the Create New Item dialog. Also, calculate the value ofquantitybased on the input values forquantity_instockandquantity_shipped.// Create item and close dialog public createItem = async (event: ojButtonEventMap["ojAction"]) => { this.quantity = (Number(this.quantity_instock()) + Number(this.quantity_shipped())); const row = { name: this.itemName(), short_desc: this.short_desc(), price: this.price(), quantity_instock: this.quantity_instock(), quantity_shipped: this.quantity_shipped(), quantity: this.quantity, activity_id: this.activityKey, image: this.inputImageFile, }; (document.getElementById("createDialog") as ojDialog).close(); } -
Below the
rowvariable declaration, create a request to send the data to the REST service.. . . const row = { . . . image: this.inputImageFile, }; // Create and send request to REST service to add row const request = new Request(this.restServerURLItems, { headers: new Headers({ "Content-type": "application/json; charset=UTF-8", }), body: JSON.stringify(row), method: "POST", }); const response = await fetch(request); const addedRow = await response.json(); . . . -
Below the
addedRowvariable, create anaddmutate event and call theRESTDataProviderclass’smutatemethod to notify yourRESTDataProviderinstance that a new row has been added. You also call theRESTDataProviderclass’srefresh()method to refresh the display.. . . const addedRow = await response.json(); // Create add mutate event and call mutate method // to notify dataprovider that a row has been // added const addedRowKey = addedRow[this.keyAttributes]; const addedRowMetaData = { key: addedRowKey }; this.itemsDataProvider.mutate({ add: { data: [addedRow], keys: new Set([addedRowKey]), metadata: [addedRowMetaData], }, }); this.itemsDataProvider.refresh(); // Close dialog (document.getElementById("createDialog") as ojDialog).close(); } -
Save the
dashboard.tsfile.Your code should look similar to this final-create-dashboard-ts.txt file.
Task 4: Test the Code and Create a Record
- In the browser, view the dynamic changes in your web app.
- In the web app, click on the Baseball activity.
-
Click Create.
The Create New Item dialog opens.
-
Fill in details for a new item.
- Name:
SureFire Ball (Set of 4) - Price:
20.5 - Description:
Canvas balls for practice - Quantity: In-Stock:
35 - Quantity: Shipped:
61
- Name:
-
Click Submit.
The section refreshes and the item is part of the list of Baseball activity items.
-
Click the SureFire Ball (Set of 4) item in the list and view its details.

-
Close the browser window or tab that displays your running web app.
- In the terminal window, press Ctrl+C, and if prompted, enter
yto exit the Oracle JET tooling batch job.
Next Step
Proceed to the next tutorial in this module.
This tutorial is part of the module CRUD Operations Using a REST Service.
- Fetch Data from a REST API in an Oracle JET Web App
- Create a Form to Create Data Records in an Oracle JET Web App
- Update Data Records in an Oracle JET Web App
- Delete Data Records in an Oracle JET Web App
You can return to the learning path’s main page to access all the modules on building web apps.
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.
Create a form to create data records in an Oracle JET web app
F11594-08