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/views
directory and open thedashboard.html
file in an editor. -
Find the
h3
element whereid="itemsListHeader"
. Below it, add anoj-button
element and set theon-oj-action
attribute 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-dialog
element. Set theid
attribute 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-dialog
element you created, add two childdiv
elements 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-button
element 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-label
element and anoj-input-text
element each for theActivity ID
andName
values.<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
activityKey
value using square brackets, which indicates one-way binding, because the user should not edit the activity ID value. You bind theitemName
value 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-text
elements 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.html
file.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/viewModels
directory and open thedashboard.ts
file in an editor. -
At the top of the
dashboard.ts
file, 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 namedshowCreateDialog
for opening the dialog.. . . constructor() { . . . } // Closing bracket for constructor method // Open dialog public showCreateDialog(event: ojButtonEventMap["ojAction"]) { (document.getElementById("createDialog") as ojDialog).open(); }
-
Below the
showCreateDialog
method you created, add a method calledcreateItem
for 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.ts
file.Your code should look similar to this create-dashboard-ts.txt file.
-
In the terminal window, run and test your web app.
npx ojet serve
The 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.ts
file, in thecreateItem
method above theclose()
call, declare variables to hold the input values from the Create New Item dialog. Also, calculate the value ofquantity
based on the input values forquantity_instock
andquantity_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
row
variable 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
addedRow
variable, create anadd
mutate event and call theRESTDataProvider
class’smutate
method to notify yourRESTDataProvider
instance that a new row has been added. You also call theRESTDataProvider
class’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.ts
file.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
y
to exit the Oracle JET tooling batch job.
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.
Create a form to create data records in an Oracle JET web app
F11594-07
September 2024