OJET Student Guide
OJET Student Guide
OJET-JS
Content
Description Page
1) Introduction to Oracle JavaScript Extension Toolkit (JET)--------4
1.1 Overview of Oracle JET and its features----------------------4
1.2 Benefits of using Oracle JET for web application development----5
1.3 Introduction to the Oracle JET architecture------------------5
1.4 Exploring the key components of Oracle JET-----------------6
2) Getting started with Oracle JET------------------------------------------7
2.1 Setting up the development environment---------------------------------7
2.2 Running and Previewing--------------------------------------------------------8
3) Responsive UI----------------------------------------------------------------9
3.1 Importance of responsive design----------------------------------9
3.2 Responsive Layout Components ---------------------------------10
3.3 implementing Responsive UI--------------------------------------11
3.4 Testing and debugging----------------------------------------------12
4) Single Page Applications-------------------------------------------------13
4.1 characteristic----------------------------------------------------------14
4.2 role of routing---------------------------------------------------------15
5) Understanding Oracle JET User Interface basics-------------------16
5.1 introduction------------------------------------------------------------16
5.2 UI Components-------------------------------------------------------17
5.3 Theming and styling ------------------------------------------------18
5.4 Internationalization and accessibility --------------------------20
5.5 Modular Architecture-----------------------------------------------20
6) Oracle JET - Common Model and Collection API------------------23
6.1 Introduction-----------------------------------------------------------23
6.2 Importance and Benefits-------------------------------------------24
6.3 model API---------------------------------------------------------------25
6.4 methods and properties--------------------------------------------26
6.5 Collection API----------------------------------------------------------28
6.6 methods and properties -------------------------------------------29
1
6.7 data binding and synchronization --------------------------------
30
7) Validating and converting inputs-------------------------------------31
7.1 importance and benefits------------------------------------------31
7.2 different types of inputs ------------------------------------------32
7.3 validating and converting-----------------------------------------33
7.4 input validation using features of OJET-------------------------33
8) Theming Applications----------------------------------------------------34
8.1 Introduction -----------------------------------------------------------34
8.2 importance ------------------------------------------------------------35
8.3 Theming concepts----------------------------------------------------36
8.4 customizing colours and themes----------------------------------37
8.5 applying custom fronts and colours------------------------------38
8.6 creating responsive themes----------------------------------------40
9) Securing Applications-----------------------------------------------------40
9.1 importance of security----------------------------------------------41
9.2 common threats -----------------------------------------------------42
9.3 authentication and authorization--------------------------------43
9.4 input validation and sanitization---------------------------------45
10) Testing and debugging--------------------------------------------46
10.1 importance of testing---------------------------------------------46
10.2 testing technique---------------------------------------------------48
10.3 automation-----------------------------------------------------------49
10.4 debugging-------------------------------------------------------------
53
2
Introduction to Oracle JavaScript Extension
Toolkit (JET):
Oracle JavaScript Extension Toolkit (JET) is a powerful open-source JavaScript
framework developed by Oracle for building modern, responsive, and feature-
rich web applications. It provides a collection of UI components, tools, and
libraries that enable developers to create enterprise-grade applications with
ease.
1. Overview of Oracle JET and its features:
Oracle JET offers a wide range of features that make it a popular choice for
web application development.
Features
3
- Modular Architecture: Oracle JET follows a modular architecture, allowing
developers to organize their code into reusable modules. This promotes code
maintainability, scalability, and reusability.
- Localization and Internationalization: Oracle JET supports localization and
internationalization, making it easy to create applications that can be localized
for different regions and languages.
- Extensibility: Developers can extend Oracle JET's functionality by creating
custom components, modules, and plugins. This flexibility allows for the
incorporation of existing libraries or the development of specialized features.
2. Benefits of using Oracle JET for web application development:
4
- Charts: Oracle JET offers a variety of chart types, including bar charts, line
charts, pie charts, and more. These components enable the visual
representation of data in a meaningful and interactive way.
- Tables: The table component allows the display of tabular data with
features such as sorting, filtering, and pagination. It provides a rich set of
options for customization and data manipulation.
- Forms: Oracle JET includes form components like input fields, checkboxes,
radio buttons, and dropdowns. These components simplify data input and
validation in web forms.
- Menus: The menu component provides a flexible and customizable menu
system for creating navigation menus, context menus, and dropdown menus in
the application.
- Data Binding: Oracle JET's data binding capabilities enable automatic
synchronization between the UI and underlying data models. It supports both
one-way and two-way data binding, making it easy to keep the UI up-to-date
with changes in the data.
- Routing: Oracle JET includes a powerful routing mechanism that enables the
creation of single-page applications with multiple views. It allows for
navigation between different sections of the application without page reloads.
5
Creating a new Oracle JET project:
```
my-ojet-project/
|- src/
|- css/
|- app.css
|- js/
|- appController.js
|- app.js
|- main.js
|- index.html
|- node_modules/
|- ojmetadata.json
|- package.json
|- README.md
```
- `src/`: This directory contains the source code for your Oracle JET application.
- `src/css/`: The CSS directory holds the application-specific CSS files.
- `src/js/`: The JS directory contains JavaScript files.
- `src/index.html`: The main HTML file for your application.
6
- `node_modules/`: This directory contains the dependencies installed via npm.
- `ojmetadata.json`: The configuration file that defines the metadata for your
Oracle JET application.
- `package.json`: The package.json file specifies the project's dependencies and
scripts.
- `README.md`: A readme file that provides information about the project.
7
src/js/views: Contains JavaScript files for defining Oracle JET
modules representing different views or pages of your application.
src/js/viewModels: Contains JavaScript files for defining Oracle
JET view models. View models encapsulate the data and behavior
of a specific view or component.
src/js/services: Contains JavaScript files for defining services or
utility functions used by your application.
src/js/libs: Contains third-party libraries or custom JavaScript
modules that are not part of the Oracle JET framework.
2. web Directory: This directory contains the compiled output of your
application. When you build your Oracle JET application, the source files
from the src directory are compiled and bundled into the web directory.
The web directory typically includes subdirectories like web/js, web/css,
and web/html with the compiled JavaScript, CSS, and HTML files
respectively.
3. config Directory: This directory contains configuration files for your
Oracle JET application. It may include files like config.js for application
configuration, navigation.json for defining navigation structure, and
platform.json for platform-specific configuration.
4. node_modules Directory: This directory contains the dependencies
installed for your project using npm. It's typically generated
automatically when you run npm install to install project dependencies.
5. src/main.js: This is the entry point of your Oracle JET application. It's
where the application initialization and configuration take place.
6. index.html: This is the main HTML file of your application. It's where you
include the necessary scripts and stylesheets and define the layout of
your application.
7. package.json: This file contains metadata about your Oracle JET
application and its dependencies. It includes information such as the
project name, version, and list of dependencies.
By exploring and understanding the project structure, you gain insights into
how different parts of your Oracle JET application are organized and how they
interact with each other.
8
Introduction to Oracle JET CLI (Command Line Interface) for project
management:
Oracle JET CLI provides a set of commands that help manage and build Oracle
JET projects. Some commonly used commands include:
- `ojet create`: Generates a new Oracle JET project based on selected options
and templates.
- `ojet serve`: Starts the development server and serves the application locally
for testing and previewing.
- `ojet build`: Builds a production-ready version of the Oracle JET application
for deployment.
- `ojet add`: Adds new components, pages, or modules to the Oracle JET
application.
- `ojet remove`: Removes components, pages, or modules from the Oracle JET
application.
- `ojet restore`: Restores dependencies from the package.json file and installs
them.
- `ojet update`: Updates the Oracle JET framework and its dependencies to the
latest versions.
The Oracle JET CLI simplifies project setup, development, and deployment
tasks by providing a convenient command-line interface.
9
1. Model-View-ViewModel (MVVM) Pattern:
Oracle JET is built around the Model-View-ViewModel (MVVM)
pattern, which separates the application's data (Model),
presentation logic (View), and application behavior (ViewModel).
The Model represents the data and business logic of the
application.
The View represents the presentation layer, typically defined
using HTML and CSS.
The ViewModel acts as a mediator between the Model and View,
handling user interactions, data binding, and application logic.
2. Modular Structure:
Oracle JET applications are organized into modules, each
encapsulating a specific functionality or feature of the application.
Modules in Oracle JET are typically defined using RequireJS, a
module loader for JavaScript.
Modularization helps improve code maintainability, reusability,
and scalability.
3. Component-Based Architecture:
10
Oracle JET provides a rich set of UI components that are designed
to be reusable and customizable.
Components encapsulate both the UI presentation and behavior,
making it easy to create complex user interfaces.
Components can be composed together to build larger views or
layouts.
4. Data Binding:
Oracle JET includes powerful data binding capabilities that allow
developers to establish relationships between the ViewModel and
the View.
Data binding ensures that changes to the ViewModel are
automatically reflected in the View, and vice versa, without
manual manipulation of the DOM.
5. Routing:
Oracle JET includes a built-in router that enables navigation
between different views or pages within the application.
Routing is typically defined using a JSON configuration file
(navigation.json) where developers can specify the URL patterns
and corresponding views.
6. Localization and Internationalization (I18n):
Oracle JET provides support for localization and
internationalization, allowing developers to create applications
that support multiple languages and locales.
Localization resources are typically stored in JSON files within the
src/locales directory.
7. Accessibility:
Oracle JET emphasizes accessibility and includes features to
ensure that applications built with the framework are accessible
to users with disabilities.
UI components in Oracle JET are designed to adhere to
accessibility standards, such as WCAG and Section 508.
8. Data Visualization:
Oracle JET includes a rich set of data visualization components,
such as charts, graphs, and gauges, for visualizing data in
meaningful ways.
These components are highly customizable and can be integrated
seamlessly into Oracle JET applications.
11
a. Model-View-ViewModel (MVVM) design pattern
12
1. Model:
The Model represents the data and business logic of the
application.
It encapsulates the application's data structures, database
operations, and business rules.
In Oracle JET, the Model can be a JavaScript object representing
application data or may interact with a backend server to fetch
and manipulate data.
2. View:
The View represents the user interface (UI) of the application.
It defines the structure, layout, and visual elements of the
application, typically using HTML, CSS, and UI components.
In Oracle JET, Views are HTML templates that render UI elements
and are bound to ViewModel properties using data binding.
3. ViewModel:
The ViewModel acts as an intermediary between the Model and
View.
It exposes data and behavior to the View, handles user
interactions, and updates the Model as necessary.
The ViewModel contains presentation logic, such as data
formatting, validation, and event handling.
In Oracle JET, ViewModels are JavaScript classes or objects that
encapsulate the application's state and behavior. They are
responsible for managing the data displayed in the View and
responding to user actions.
13
Key characteristics and benefits of the MVVM pattern include:
Separation of Concerns: The MVVM pattern separates the concerns of
data management, UI presentation, and application logic, making the
codebase more modular and easier to maintain.
Testability: Each component in the MVVM pattern can be tested
independently, facilitating unit testing and ensuring code reliability.
Reusability: Components like ViewModels and UI elements can be
reused across different views or applications, promoting code reuse and
reducing development effort.
Data Binding: MVVM frameworks often provide data binding
mechanisms that enable automatic synchronization between the
ViewModel and View, reducing boilerplate code and enhancing
developer productivity.
Scalability: The MVVM pattern supports the development of scalable
applications by promoting modularization and decoupling between
components.
Data binding and observables are core concepts in Oracle JET (JavaScript
Extension Toolkit) that enable the automatic synchronization of data between
the ViewModel and the View. Here's an overview of data binding and
observables in Oracle JET:
1. Data Binding:
Data binding is a technique used to establish a connection
between the data in the ViewModel and the UI elements in the
View.
When data changes in the ViewModel, the corresponding UI
elements in the View are automatically updated, and vice versa.
Data binding eliminates the need for manual DOM manipulation,
making the code more concise and easier to maintain.
Oracle JET supports two-way data binding, where changes in the
UI elements are reflected back to the ViewModel, and changes in
the ViewModel are reflected in the UI elements.
2. Observables:
Observables are special JavaScript objects provided by Oracle JET
that enable automatic notification when their values change.
In Oracle JET, observables are used to represent properties in the
ViewModel that need to be observed for changes.
14
When the value of an observable changes, any UI elements bound
to that observable are automatically updated to reflect the new
value.
Observables in Oracle JET come in various types, such as
ko.observable, ko.observableArray, and ko.computed.
ko.observable: Represents a single value that can be observed for
changes.
ko.observableArray: Represents an array that can be observed for
changes to its elements.
ko.computed: Represents a computed value derived from one or
more observables. It automatically updates whenever its
dependencies change.
Here's an example of how data binding and observables are used in Oracle JET:
// ViewModel definition
function AppViewModel() { var self = this;
// Define observables for data properties self.name = ko.observable('John');
self.age = ko.observable(30);
// Define a computed observable self.info = ko.computed(function() { return
self.name() + ' is ' + self.age() + ' years old.'; }); }
// Apply bindings ko.applyBindings(new AppViewModel());
In this example:
The ViewModel (AppViewModel) defines two observables (name and
age) to represent the name and age properties.
It also defines a computed observable (info) that derives its value from
the name and age observables.
In the View (HTML), the data-bind attribute is used to establish bindings
between the observables in the ViewModel and the UI elements.
Changes to the values of name and age observables in the ViewModel
are automatically reflected in the corresponding UI elements, and
changes in the UI elements are reflected back to the ViewModel.
15
c. Components and modules in OJet-JS
1. Self-contained functionality:
Each component in Oracle JET encapsulates a specific piece of UI
functionality, such as buttons, inputs, lists, charts, dialogs, and more.
2. Encapsulation:
Components encapsulate both the visual presentation (HTML/CSS) and
the behavior (JavaScript) associated with a particular UI element or
feature. This encapsulation promotes code modularity and separation of
concerns.
3. Customization:
Oracle JET components are highly customizable and configurable.
Developers can adjust various attributes, properties, and styles of a
component to meet specific design and functional requirements.
4. Reusability:
Components are designed to be reusable across different views or
applications. Once defined, a component can be easily reused multiple
times throughout the application, promoting code reuse and reducing
development effort.
5. Integration:
Components in Oracle JET seamlessly integrate with other parts of the
framework, such as data binding, observables, routing, and
internationalization. This integration allows developers to build complex
and interactive user interfaces efficiently.
6. Rich set of built-in components:
Oracle JET provides a rich set of built-in components covering a wide
range of UI elements and features commonly used in web and mobile
applications. These components are designed to adhere to modern
design principles and accessibility standards.
16
Basic Input Components:
Input Text:
Allows users to enter single-line text input.
Input Number:
Accepts numeric input, including integer and floating-point numbers.
Input Date:
Enables users to select a date from a calendar.
Input Password:
Similar to input text but hides the entered characters for password fields.
Input Color:
Lets users select a color from a color picker.
Form Components:
Checkbox:
Allows users to select one or more options from a set of choices.
Radio Button:
Presents a set of mutually exclusive options, where only one option can be
selected.
Select (Dropdown):
Provides a dropdown list of options for users to select from.
Switch:
Offers a toggle switch for users to turn options on or off.
Textarea:
Allows users to enter multiline text input.
Display Components:
Button:
Triggers an action when clicked by the user.
Icon:
Represents graphical symbols or icons that convey meaning or provide
visual cues.
Progress Bar:
Visualizes the progress of a task or operation.
Badge:
Displays a small notification or status indicator.
Label:
Provides textual information or context for other UI elements.
Data Visualization Components:
17
Chart:
Presents data in graphical formats such as line charts, bar charts, pie
charts, and more.
Gauge:
Displays values within a range, often used to represent progress or status.
Map:
Renders geographical data and provides interactive mapping features.
Timeline:
Visualizes chronological data in a timeline format.
Navigation Components:
Menu:
Presents a list of options or commands for navigation or selection.
Tabs:
Organizes content into separate sections or tabs.
Accordion:
Collapses and expands sections of content to conserve space.
Dialog and Overlay Components:
Dialog:
Displays modal or non-modal dialogs for user interaction or confirmation.
Popup:
Presents additional content or actions in a floating overlay.
Layout Components:
Layout Grid:
Defines a responsive grid layout for organizing content.
Flexbox:
Offers flexible box layout capabilities for arranging elements in a container.
Flex Container and Items: Enable flexbox layout for a container and its child
items.
18
Modules:
1. Definition:
Modules are individual JavaScript files that encapsulate a specific
piece of functionality or feature within an application.
They follow the CommonJS module format or the AMD
(Asynchronous Module Definition) format, which allows them to
define dependencies and export functionality.
2. Types:
ViewModel Modules:
ViewModel modules contain the logic and behavior of a
specific view or component within the application.
They typically define observables, computed observables,
and functions that handle user interactions and data
manipulation.
ViewModel modules are responsible for managing the state
of the UI and communicating with the Model and View
layers.
Service Modules:
Service modules encapsulate reusable functionality that is
shared across multiple parts of the application.
They often provide data access methods, API wrappers,
utility functions, or other services needed by ViewModel
modules.
Service modules help promote code reuse and
maintainability by centralizing common functionality.
Utility Modules:
Utility modules contain helper functions, constants, or
other utilities that are used throughout the application.
They provide reusable functionality for tasks such as data
formatting, validation, string manipulation, and more.
Utility modules help streamline development and ensure
consistent behavior across the application.
Component Modules:
Component modules encapsulate the functionality and
behavior of reusable UI components.
They define custom elements, templates, and logic specific
to a particular UI component.
Component modules promote code reuse and
maintainability by encapsulating complex UI elements into
reusable units.
19
Routing Modules:
Routing modules define the navigation logic and routes for
the application.
They specify URL patterns and corresponding views or
components to render when a particular route is matched.
Routing modules enable single-page application (SPA)
behavior and help manage application navigation.
Benefits:
Modularity: Modules help break down the application into smaller,
more manageable pieces, making it easier to understand, develop, and
maintain.
Reusability: By encapsulating functionality into modules, developers can
reuse code across different parts of the application, reducing duplication
and promoting consistency.
Encapsulation: Modules encapsulate functionality and data, preventing
unintended interference and promoting a clear separation of concerns.
Dependency Management: Oracle JET provides tools for managing
module dependencies, ensuring that modules are loaded in the correct
order and minimizing dependencies between modules.
20
4. Working with OJet-JS Components
21
OJet-JS offers two types of components: built-in components provided by the
framework and custom components created by developers. Built-in
components include a wide range of UI elements such as buttons, inputs,
tables, charts, and layouts, which are ready to use out of the box. Custom
components, on the other hand, allow developers to create specialized UI
elements tailored to the specific requirements of their application.
22
8. CSS Styling: CSS styles define the visual appearance of components,
including layout, colors, fonts, and animations. OJet-JS provides
guidelines and best practices for styling components to ensure
consistency and maintainability.
1. Component Integration:
Oracle JET provides a rich set of components like buttons, inputs,
lists, charts, dialogs, and more, allowing developers to build
sophisticated user interfaces.
Integration involves including the necessary HTML markup for
each component in your application's views. For example, <oj-
button>, <oj-input-text>, <oj-list-view>, etc.
Components can be customized and configured using various
attributes and properties to match specific design and functional
requirements. This includes attributes like disabled, readonly,
value, label, options, etc.
2. Data Binding:
Data binding is a core feature of Oracle JET that allows you to
establish a connection between ViewModel observables and
component properties.
By using the data-bind attribute in HTML, you can bind ViewModel
properties to component attributes or properties. For example,
data-bind="value: name" binds the name observable to the value
of an input field.
When ViewModel properties change, the corresponding UI
elements are automatically updated, and vice versa, ensuring that
the UI remains synchronized with the underlying data.
3. Event Handling:
Oracle JET components can respond to various user interactions
such as clicks, key presses, mouse movements, etc.
Event handling involves defining event handlers in your
ViewModel to handle these interactions and trigger corresponding
actions.
Use data binding to bind event handlers to component events. For
example, data-bind="click: handleClick" binds the handleClick
method in the ViewModel to the click event of a button.
4. Custom Components:
23
Custom components allow developers to encapsulate reusable UI
elements or complex functionality into a single, self-contained
unit.
To create a custom component, define a new HTML element with
associated JavaScript and CSS to define its behavior and
appearance.
Component composition can be used to combine multiple existing
components into a new custom component, providing flexibility
and reusability.
5. Component Lifecycle:
Components in Oracle JET have a lifecycle that includes various
phases such as initialization, rendering, updating, and destruction.
Lifecycle hooks such as connectedCallback, disconnectedCallback,
attributeChangedCallback, etc., allow you to perform initialization
and cleanup tasks at different stages of the component lifecycle.
6. Accessibility:
Oracle JET components are designed to be accessible, ensuring
that they can be used by people with disabilities.
Accessibility features include using semantic HTML elements, ARIA
attributes, and keyboard navigation support to enhance usability
for all users, including those using assistive technologies.
7. Responsive Design:
Oracle JET components are responsive by default, meaning they
adapt to different screen sizes and devices.
Developers can use responsive design principles and media
queries to ensure that components render correctly on various
devices and screen resolutions, providing a consistent user
experience across different platforms.
8. Testing and Debugging:
Thorough testing is essential to ensure that components behave
as expected and handle different scenarios correctly.
Use browser developer tools, unit tests, and debugging
techniques to identify and fix issues, ensuring optimal
performance and reliability of your components.
Example -
<!DOCTYPE html>
<html lang="en">
<head>
24
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Oracle JET Button Example</title>
<!-- Include Oracle JET CSS -->
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/oraclejet@11.0.0/dist/css/alta/oj-alta-
min.css" type="text/css">
</head>
<body>
<!-- Oracle JET Button Component -->
<oj-button id="my-button">Click Me</oj-button>
This code displays a single Oracle JET button component with the text "Click
Me". When clicked, it doesn't perform any action, but it demonstrates how to
include and display a basic component in an HTML page.
25
b. Using built-in OJet-JS components
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Oracle JET Button Example</title>
<!-- Include Oracle JET CSS -->
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/oraclejet@11.0.0/dist/css/alta/oj-alta-
min.css" type="text/css">
</head>
<body>
<!-- Oracle JET Button Component -->
<oj-button id="my-button">Click Me</oj-button>
<!-- Include Oracle JET and Knockout.js libraries -->
26
<script src="https://cdn.jsdelivr.net/npm/oraclejet@11.0.0/dist/js/libs/oj-esm-
runtime.js"></script>
<script src="https://cdn.jsdelivr.net/npm/oraclejet@11.0.0/dist/js/libs/oj-esm-
es5-adapter.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/knockout@3.5.1/build/output/knockout-
latest.js">
</script>
<!-- Include Oracle JET Custom Elements -->
<script type="module"
src="https://cdn.jsdelivr.net/npm/oraclejet@11.0.0/dist/js/custom-
elements/custom-elements-esm.js"></script>
</body>
</html>
2. JavaScript (Optional): No JavaScript code is needed for this simple
example. The button will work even without any additional JavaScript.
In this example:
We include the Oracle JET button component <oj-button> in the HTML.
The button displays the text "Click Me".
Oracle JET CSS is included to style the button.
Oracle JET and Knockout.js libraries are included for component
functionality and data binding (though not strictly necessary for this
example).
Oracle JET custom elements script is included to enable custom element
functionality.
This example demonstrates how to use a built-in Oracle JET component
(button) in an HTML page without any additional configuration or JavaScript
code.
27
This may include handling user interactions, updating component
state, and interacting with external data or services.
3. Style the Component with CSS:
Apply styles to the custom component using CSS to control its
appearance and layout.
Use CSS classes or inline styles to define the visual presentation of
the component.
4. (Optional) Handle Data Binding:
If your custom component needs to interact with a ViewModel or
other data source, you can implement data binding using
Knockout.js or another data binding library.
Define observable properties in your ViewModel and bind them to
the custom component's attributes or properties.
5. Use the Custom Component:
Once the custom component is defined, you can use it like any
other HTML element in your application.
Include the custom element in your HTML markup and provide
any necessary attributes or content.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Button Example</title>
</head>
<body>
<!-- Use the custom component -->
<my-button text="Click Me"></my-button>
28
// custom-button.js
class MyButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.text = this.getAttribute('text') || 'Click Me';
this.shadowRoot.innerHTML = `
<style>
/* Include custom-button.css styles */
@import "custom-button.css";
</style>
<button class="my-button">${this.text}</button>
`;
this.shadowRoot.querySelector('.my-button').addEventListener('click', () => {
alert('Button clicked!');
});
}
}
29
handles navigation events and updates the UI based on route
changes.
Navigation: Navigation refers to the process of moving between
different views/pages within the application. Navigation can be
triggered by user actions (e.g., clicking links, buttons) or
programmatically in response to application logic.
URL Parameters: URL parameters allow you to pass data or
customize the behavior of views/pages. Parameters can be
specified as part of the URL path or query string and are extracted
by the router for use in the application.
Navigation Guards: Navigation guards are hooks that allow you to
intercept and control navigation events. Guards can be used to
enforce access control, perform data validation, or prompt the
user for confirmation before navigating to a new page.
Define Routes:
Define the routes for your application by specifying URL patterns and their
associated modules or HTML files.
Routes are typically defined in a separate configuration file or module using a
JSON object.
Each route consists of a path representing the URL pattern and a module or
view specifying the associated view module or HTML file.
Example route configuration:
{
"path": "/home",
"module": "home-view"
},
{
"path": "/about",
"module": "about-view"
}
Initialize Router:
30
Initialize the router in your main application module to enable routing
functionality.
Configure the router with the defined routes and specify the root module or
HTML file where routing will occur.
Example router initialization:
Handle Navigation:
31
Extract URL parameters from the route and use them in your application logic
as needed.
Example URL parameter handling:
// Extract parameter from URL
const userId = router.getParam('id');
Setting up routing in Oracle JET allows you to create SPAs with multiple
views/pages and enables seamless navigation between them based on URL
changes and user interactions.
You can simply import and use the oj.Router module in your Oracle JET
application without the need for any external dependencies. The router
module allows you to define routes, handle navigation events, and manage the
application's navigation flow seamlessly.
Here's an example of how you can initialize the router in your Oracle JET
application:
By using the built-in router module provided by Oracle JET, you can easily set
up routing in your application and create dynamic, single-page experiences for
your users.
32
b. Defining routes and handling navigation
2. Initialize Router:
Initialize the router in your main application module to enable
routing functionality.
Use the oj.Router module provided by Oracle JET to initialize the
router and configure it with the defined routes.
Example router initialization:
33
Load the appropriate view module or HTML file and render it in
the application's main content area.
Example route change event listener:
router.on('route:change',
(route) => { console.log('Route changed:', route); // Load and render the view
module or HTML file associated with the route renderView(route.module); });
34
Example menu item selection handler:
document.getElementById('navigationMenu').
addEventListener('ojAction', (event) => { const path =
event.detail.originalEvent.target.dataset.path; router.go(path); });
4. Displaying Links:
Display navigation links within your application's views/pages to
provide additional navigation options.
Use Oracle JET components such as oj-button or standard HTML a
elements to create links.
Example navigation link:
35
6. Data Management with OJet-JS
36
Validate user input and data retrieved from external sources to
prevent errors and inconsistencies.
Use validation techniques such as regular expressions, custom
validators, and built-in validation rules provided by Oracle JET.
Data binding in Oracle JET allows you to establish a connection between the UI
components of your application and the underlying data model. It ensures that
changes to the data model are automatically reflected in the UI, and vice versa,
without requiring manual synchronization.
Oracle JET supports two-way data binding, which means changes to the UI
update the underlying data model, and changes to the data model update the
UI. This bidirectional binding simplifies development and keeps the UI in sync
with the data.
2. Syntax:
Data binding in Oracle JET is typically done using special attributes in HTML
markup and expressions in JavaScript.
a. HTML Markup:
Use the data-bind attribute to bind UI components to ViewModel
properties or expressions.
The data-bind attribute accepts one or more binding directives
separated by commas.
Example:
In this example, the value binding directive binds the input field's value to the
userName property in the ViewModel, while the attr binding directive
dynamically sets the placeholder attribute.
b. JavaScript Expressions:
Use JavaScript expressions within binding directives to dynamically
generate values or perform computations.
Expressions can access properties and functions defined in the
ViewModel.
37
Example:
Here, the text binding directive dynamically generates the text content using
the userName property from the ViewModel.
3. Observable Properties:
4. Binding Context:
The binding context provides access to ViewModel properties and functions
within the HTML markup. You can reference ViewModel properties directly or
use $data to refer to the current binding context.
Syntax:
In Oracle JET, data models and collections are used to represent and manage
structured data within your application. Data models encapsulate individual
data items, while collections organize multiple data items into a structured
format. Here's how you can work with data models and collections in Oracle
JET:
1. Data Models:
Definition: Data models represent individual data items or entities
within your application.
38
Usage: Data models are typically used to represent a single record or
entity fetched from an external data source.
Types of Data Models:
Observable Objects:
These are JavaScript objects that support two-way data binding, allowing
changes made to the object to automatically reflect in the UI and vice
versa.
Collection Models:
OJet data models can seamlessly integrate with backend services, such
as RESTful APIs or WebSocket endpoints, to fetch, update, or delete data
from external data sources.
Extensibility:
39
OJet provides flexibility for extending and customizing data models to
meet specific application requirements. Developers can create custom
data models or extend existing ones to incorporate additional
functionality or business logic.
2. Collections:
40
Once you have defined data models and collections, you can perform
various operations such as creating, reading, updating, and deleting
(CRUD) data items.
Use methods provided by JavaScript arrays or Oracle JET collections to
manipulate data items within the collection.
// JavaScript Array
users.push
({ id: 4, name: 'Bob Johnson', email: 'bob@example.com' });
CRUD operations (Create, Read, Update, Delete) are fundamental for managing
data in any application. In Oracle JET, you can handle CRUD operations
efficiently using various techniques and APIs. Below is a detailed explanation of
how to handle CRUD operations in Oracle JET:
1. Create Operation:
Definition: The create operation involves adding new data items to your
application's data model or collection.
Syntax (JavaScript):
For adding a new item to a JavaScript array:
collection.create(newItem);
2. Read Operation:
Definition: The read operation involves fetching existing data items from
your application's data model or collection.
Syntax (JavaScript):
41
For accessing data from a JavaScript array:
collection.at(index);
3. Update Operation:
Definition: The update operation involves modifying existing data items
in your application's data model or collection.
Syntax (JavaScript):
For updating an item in a JavaScript array:
data.splice(index, 1);
For deleting an item from an Oracle JET collection:
42
7. OJet-JS and RESTful APIs
Oracle JET applications often rely on RESTful APIs to interact with external data
sources. RESTful APIs provide a standardized way to access and manipulate
resources over the web using HTTP methods. Oracle JET leverages these APIs
to fetch, update, create, and delete data from remote servers.
43
Oracle JET applications may require authentication and
authorization to access protected resources.
Authentication mechanisms such as OAuth, JWT, or session-based
authentication can be implemented to secure API endpoints and
ensure that only authorized users can access certain data or
perform specific actions.
4. Error Handling:
Error handling is essential when working with RESTful APIs to
handle unexpected responses or network errors.
Oracle JET applications should implement robust error handling
logic to gracefully handle errors returned by API endpoints and
provide meaningful feedback to users.
Theory Example:
Suppose you have an Oracle JET application that manages a list of products
using a RESTful API. Here's how you might interact with the API:
1. Fetching Data:
Use the Fetch API to send a GET request to the API endpoint
/api/products to retrieve the list of products.
2. Creating a New Product:
When a user adds a new product in the application, send a POST
request to the API endpoint /api/products with the product data
in the request body to create a new product.
3. Updating a Product:
If a user edits an existing product, send a PUT request to the API
endpoint /api/products/{productId} with the updated product
data to update the product on the server.
4. Deleting a Product:
When a user deletes a product, send a DELETE request to the API
endpoint /api/products/{productId} to remove the product from
the server.
5. Error Handling:
Implement error handling logic to handle cases where the API
request fails due to network issues or server errors. Display
appropriate error messages to the user to notify them of the
issue.
44
handling responses, and updating the UI based on the retrieved data. Below is
a detailed explanation of how to consume RESTful APIs in Oracle JET:
1. Fetching Data from APIs:
Oracle JET uses modern web APIs like Fetch API or XMLHttpRequest to
send HTTP requests to RESTful API endpoints.
The fetch() function is commonly used to fetch data asynchronously
from a server.
Example using Fetch API:
fetch('https://api.example.com/data') .
then(response => response.json()) // Parse response as
JSON .then(data => console.log(data)) // Process retrieved
data .catch(error => console.error('Error:', error)); // Handle errors
2. Sending Data to APIs:
Oracle JET applications can send data to APIs using various HTTP
methods such as POST, PUT, or DELETE.
When sending data, you typically include it in the request body as JSON
or form data.
Example of sending data with POST request:
fetch('https://api.example.com/data',
{ method: 'POST', headers: { 'Content-Type': 'application/json' // Specify
content type as JSON },
body: JSON.stringify({ name: 'John Doe', email: 'john@example.com' }) //
Convert data to JSON string })
.then(response => response.json())
.then(data => console.log('Created:', data)) .catch(error =>
console.error('Error:', error));
3. Handling Responses:
After sending a request, Oracle JET applications handle the response
asynchronously.
Responses are typically parsed (e.g., as JSON) to extract the data and
then processed accordingly.
Example of handling JSON response:
45
Error handling is crucial when consuming RESTful APIs to handle network
errors, server errors, or other issues.
Oracle JET applications use .catch() to catch and handle errors gracefully.
Example of error handling:
fetch('https://api.example.com/data')
.then(response => { if (!response.ok) { throw new Error('Network response was
not ok'); } return response.json(); })
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Overview:
1. What is AJAX?
AJAX is a combination of technologies including JavaScript, XML
(although JSON is more commonly used nowadays), HTML, CSS, and
XMLHttpRequest.
It allows web pages to send and receive data from a server
asynchronously, meaning that it can update parts of a web page without
requiring a full page reload.
AJAX enables developers to create more interactive and responsive web
applications by fetching data in the background and updating the UI
accordingly.
46
2. Making AJAX Requests with Oracle JET:
Oracle JET provides built-in support for making AJAX requests using the
Fetch API or XMLHttpRequest.
Developers can use these methods to send HTTP requests to server
endpoints and handle responses asynchronously.
3. Fetch API:
The Fetch API provides a modern interface for fetching resources
asynchronously across the network.
It offers a more powerful and flexible way to make AJAX requests
compared to XMLHttpRequest.
Example using Fetch API:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
4. XMLHttpRequest:
XMLHttpRequest (XHR) is an older method for making AJAX requests,
supported by all major browsers.
It provides a lower-level interface compared to Fetch API but is still
widely used in many applications.
Example using XMLHttpRequest:
5. Handling Responses:
After sending an AJAX request, Oracle JET applications handle the
response asynchronously.
Responses are typically processed, parsed (e.g., as JSON), and then used
to update the UI or perform other actions.
6. Error Handling:
Error handling is essential when making AJAX requests to handle
network errors, server errors, or other issues.
47
Oracle JET applications use error handling techniques such as .catch() to
catch and handle errors gracefully.
When working with RESTful APIs in Oracle JET applications, it's essential to
handle API responses effectively and implement robust error handling
mechanisms. This ensures that the application behaves gracefully in various
scenarios, such as successful responses, errors from the server, or network
issues. Let's delve into the details of handling API responses and error handling
in Oracle JET:
1. Handling API Responses:
After sending a request to a RESTful API, Oracle JET applications receive
responses asynchronously.
Responses may contain the requested data, metadata, status codes, and
headers, which need to be processed appropriately.
Oracle JET provides methods for parsing and processing API responses,
typically as JSON objects.
Example of handling a JSON response using Fetch API:
fetch('https://api.example.com/data')
.then(response => { if (!response.ok) { throw new Error('Network response was
not ok'); } return response.json(); })
.then(data => { // Process the retrieved data console.log(data); })
.catch(error => { // Handle errors gracefully console.error('Error:', error); });
2. Error Handling:
Error handling is crucial to gracefully handle errors that may occur
during API requests, such as network errors, server errors, or invalid
responses.
Oracle JET applications use error handling techniques such as .catch() to
catch and handle errors gracefully.
Example of error handling using Fetch API:
fetch('https://api.example.com/data')
.then(response => { if (!response.ok)
{ throw new Error('Network response was not ok'); }
return response.json(); })
.then(data => { // Process the retrieved data console.log(data); })
.catch(error => { // Handle errors gracefully console.error('Error:', error); });
48
3. Error Status Codes:
HTTP status codes are used to indicate the success or failure of an API
request.
Common HTTP status codes for error responses include 4xx (Client Error)
and 5xx (Server Error) status codes.
Oracle JET applications can inspect the status code of the response to
determine the type of error and handle it accordingly.
4. Displaying Error Messages:
When an error occurs during an API request, it's essential to provide
meaningful error messages to the user to explain what went wrong.
Oracle JET applications can display error messages in the UI, log them to
the console, or take other appropriate actions based on the context.
5. Retrying Failed Requests:
In some cases, it may be appropriate to retry failed API requests
automatically.
Oracle JET applications can implement retry logic with exponential
backoff strategies to retry failed requests with increasing delays.
49
8. Advanced OJet-JS Concepts
1. Main Folder Structure: Organize your modules within the main project
folder.
2. Module Folder: Each module should have its own folder within the
project structure.
3. Subfolders: Within the module folder, include subfolders for different
aspects like views, models, controllers, services, etc.
4. View Templates: Store HTML files for views in the 'views' subfolder.
5. JavaScript Logic: Place JavaScript files, including controllers and
modules, in the appropriate subfolders like 'viewModels' or 'controllers'.
6. Styling: CSS files can be stored in a 'css' subfolder.
7. Resource Files: Any other resources like images, fonts, or third-party
libraries can be organized accordingly.
8. Configuration Files: Include configuration files like 'ojET.json' for
module-specific settings.
50
9. Accessibility: Ensure that the module structure adheres to accessibility
standards for ease of navigation and maintenance.
10.Documentation: Document the module structure and any dependencies
for future reference.
The structure of an Oracle JET module follows a specific pattern that organizes
code into distinct components, promoting modularity, maintainability, and
scalability. Let's break down the structure of an Oracle JET module:
1. Model:
The model component represents the data layer of the
application.
It encapsulates data structures, business logic, and interactions
with external data sources.
Models can be implemented using JavaScript classes, functions, or
objects.
Example:
2. View:
The view component defines the user interface (UI) of the
application.
It consists of HTML templates, CSS stylesheets, and any other
assets required for rendering.
Views define the layout, structure, and visual presentation of UI
elements.
Example:
51
The viewModel component acts as the bridge between the model
and the view.
It contains presentation logic, event handling, and data binding
setup.
ViewModels are implemented using JavaScript functions or
classes.
Example:
TodoViewModel { constructor()
{ this.todoModel = new TodoModel();
this.todos = ko.observableArray(this.todoModel.todos); } }
4. Custom Components:
Modules may include custom components, which encapsulate
reusable UI elements or complex functionality.
Custom components consist of their own model, view, and
viewModel components.
They promote code reuse and encapsulation.
Example:
Dependency management
52
The define function specifies the name of the module, an array of
dependencies, and a factory function that defines the module's
behavior.
Example:
define(['knockout', 'ojs/ojmodule'],
function(ko, Module) { // Module code here });
53
4. Circular Dependencies:
Circular dependencies occur when two or more modules depend
on each other directly or indirectly.
While circular dependencies should generally be avoided,
RequireJS handles them gracefully by allowing modules to be
partially initialized until all dependencies are resolved.
Developers should strive to refactor code to eliminate circular
dependencies whenever possible to improve code clarity and
maintainability.
Example
// ModuleA.js
define(['ModuleB'], function(ModuleB) {
// ModuleA logic here
return {
// ModuleA exports
};
});
// ModuleB.js
define(['ModuleA'], function(ModuleA) {
// ModuleB logic here
return {
// ModuleB exports
};
});
54
c. Localization and internationalization
55
Resource Bundles: Oracle JET supports resource bundles, which
are JSON files containing key-value pairs for localized text strings
and formats.
Message Format: Oracle JET includes support for message
formatting, allowing developers to dynamically insert variables
and placeholders into localized text strings.
Date and Time Formatting: Oracle JET provides built-in functions
for formatting dates, times, and numbers according to the user's
locale preferences.
Translation Tools: Oracle JET integrates with translation
management tools and platforms, making it easier for developers
to collaborate with translators and manage translations for their
applications.
Language and Locale Detection: Oracle JET can automatically
detect the user's language and locale settings, enabling
applications to display content in the appropriate language and
format.
{
"greeting": "Hello",
"farewell": "Goodbye"
}
es.json:
{
"greeting": "Hola",
"farewell": "Adiós"
}
Accessing Localized Text Strings:To access localized text strings from
resource bundles in Oracle JET, you can use the
oj.Translations.getTranslatedString(key) method. Here's how you can
use it:
56
// Assuming the current locale is set to 'en'
var greeting = oj.Translations.getTranslatedString('greeting');
// greeting will be "Hello"
Message Formatting:Oracle JET supports message formatting, allowing
you to insert variables and placeholders into localized text strings. Here's
an example:
// Resource bundle:
// {
// "welcome_message": "Welcome, {name}!"
// }
57
d. Handling application state and events
function ViewModel()
{ this.handleClick = function()
{ console.log('Button clicked'); }; }
58
Event Delegation: Event delegation allows you to handle events
on parent elements instead of individual child elements,
improving performance and simplifying event management.
function ViewModel()
{ this.handleItemClick = function(data, event)
{ console.log('Item clicked:', data); }; }
3. Lifecycle Hooks:
Attached Callback: The attached callback is invoked when a view
is attached to the DOM. It's commonly used for initializing third-
party libraries or performing DOM manipulations.
59
9. OJet-JS Theming and Styling
Theming plays a significant role in the design and visual appeal of software
applications. It involves customizing the appearance of an application by
modifying its colors, fonts, spacing, and other visual elements. Theming allows
developers to create unique and branded user interfaces that align with the
application's design requirements and aesthetics.
60
2. CSS Variables: OJet-JS makes extensive use of CSS variables (also known
as CSS custom properties) for theming purposes. These variables allow
you to define reusable values for properties like colors, fonts, spacing,
etc., which can be easily modified to change the overall theme of your
application.
3. Themes: You can create multiple themes for your OJet-JS application by
defining sets of CSS variables for each theme. Switching between themes
can be done dynamically by changing the values of these variables at
runtime, allowing users to choose their preferred theme or enabling
theme switching based on application logic.
4. Sass/Less Support: OJet-JS supports Sass and Less preprocessors, which
provide additional features like variables, mixins, and nesting to make
styling more efficient and maintainable. You can leverage these
preprocessors to organize your stylesheets and streamline the theming
process.
5. Component Styling: OJet-JS components are designed to be highly
customizable, allowing you to apply custom styles to individual
components as needed. You can use inline styles, CSS classes, or
component-specific styling options to tailor the appearance of each
component to fit your application's design requirements.
6. Global vs. Local Styles: OJet-JS provides options for applying styles
globally across your application or locally to specific components or
pages. This gives you flexibility in managing the scope of your styles and
ensures consistent styling where needed while allowing for component-
specific customization.
7. Responsive Design: OJet-JS supports responsive design principles,
allowing you to create styles that adapt to different screen sizes and
devices. You can use media queries and responsive layout techniques to
ensure that your application looks good and functions well across a
variety of devices and viewport sizes.
Theming in OJet-JS enables developers to tailor the visual aspects of web and
mobile applications to their specific design preferences. It encompasses
several key elements, starting with the customization of default CSS styles to
align with desired aesthetics. Central to OJet-JS theming is the utilization of CSS
variables, offering a flexible and efficient approach to adjusting colors, fonts,
and other style properties across the application.
61
Moreover, developers can create multiple themes by defining sets of variables,
allowing for easy switching between different visual styles or dynamic theme
changes based on user preferences or application context. This approach
facilitates enhanced customization and maintains consistency throughout the
application.
Additionally, theming in OJet-JS prioritizes responsive design principles,
ensuring that applications adapt seamlessly to various screen sizes and
devices. This involves employing responsive layout techniques and media
queries to optimize the user experience across different platforms.
By leveraging these features, developers can craft visually appealing and highly
customizable applications that meet their design requirements while
maintaining responsiveness and consistency across diverse environments.
Theming plays a vital role in Oracle JET applications for several reasons:
62
elements to create a personalized experience that resonates with the target
audience.
1. Skins: Skins in Oracle JET are predefined collections of styles that define the
visual appearance of components. Oracle JET offers a set of built-in skins that
developers can choose from to quickly apply a consistent look and feel to their
applications. These skins include different color schemes, typography settings,
and other design elements. Skins provide a convenient starting point for
theming and can be easily applied to the entire application or specific
components.
63
creating custom styles, developers have full control over the visual appearance
of their application, allowing for extensive customization and branding.
4. CSS Variables: Oracle JET utilizes CSS variables to enable flexible theming.
CSS variables are reusable values that can be defined and assigned to various
CSS properties. By leveraging CSS variables, developers can define and update
global theme-related values, such as colors or font sizes, in a central location.
This makes it easier to maintain consistent theming across the application and
allows for quick adjustments and updates to the visual appearance.
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--font-family: 'Arial', sans-serif;
/* Add more variables as needed */ }
The : root selector sets the scope for global CSS variables.
--primary-color and --secondary-color represent the main color
scheme of the theme.
--font-family specifies the font to be used across the application.
.button {
background-color: var(
--primary-color);
64
color: white; /* Additional styles */ }
.header {
background-color: var(--primary-color);
color: white; /* Additional styles */ }
Styling Components:
1. HTML Structure:
.oj-flex {
display: flex; align-items: center;
justify-content: center;
}
.oj-text-color-primary {
color: #007bff; }
.oj-button {
padding: 8px 16px;
border-radius: 4px;
border: none;
cursor: pointer;
}
.oj-button-primary
{ background-color: #007bff;
color: white;
}
.oj-flex class defines a flex container to center its children
horizontally and vertically.
.oj-text-color-primary class sets the text color to a primary color.
.oj-button class styles a basic button with padding, border-radius,
and cursor properties.
.oj-button-primary class styles a button with a primary color
background and white text.
Styling Layouts:
1. HTML Structure:
66
</div>
2. CSS Styling:
.oj-grid
{ display: grid;
grid-template-rows: auto 1fr auto;
grid-template-columns: 1fr;
min-height: 100vh;
}.
oj-padding {
padding: 16px;
}
.oj-cell {
padding: 16px;
border: 1px solid #ccc;
}
.oj-grid class defines a grid container with three rows (header,
content, footer) and one column, with the content area taking up
most of the available space.
.oj-padding class adds padding to the layout container.
.oj-cell class styles each cell within the layout grid with padding
and a border.
By styling OJet-JS components and layouts using CSS, you can customize their
appearance to match your design requirements. This approach allows for
flexibility and consistency in styling across different parts of your application.
Overview
67
1. Unit Testing:
Testing individual units or components of the application in isolation to
ensure they work as intended.
2. Integration Testing:
Verifying that different modules or components of the application work
together correctly.
3. End-to-End Testing:
Testing the entire application flow from start to finish to ensure all parts
work together seamlessly.
4. Regression Testing:
Repeating tests to ensure that new changes or updates haven't
introduced bugs or regressions.
5. Performance Testing:
Evaluating the application's responsiveness, scalability, and resource
usage under various conditions.
Importance of Testing
The importance of testing in software development cannot be overstated.
Testing plays a crucial role in ensuring the quality, reliability, and success of
software applications. Here are some key reasons why testing is important:
1. Detecting and Preventing Bugs: Testing helps to identify and fix bugs or
issues in the software. By thoroughly testing the application, developers can
catch and resolve any programming errors or defects before the application is
deployed to production. This helps in delivering a stable and reliable software
product.
68
4. Enhancing User Experience: Testing plays a vital role in ensuring a positive
user experience. By conducting usability testing and user acceptance testing,
developers can gather feedback from users and make necessary improvements
to the application's interface, functionality, and overall usability. This helps in
delivering an application that meets user expectations and requirements.
6. Cost and Time Savings: While testing requires an investment of time and
resources, it ultimately helps in saving costs and time in the long run. By
identifying and fixing issues early in the development process, testing helps to
avoid costly rework and delays that may arise if defects are discovered in the
production environment.
Testing Technique
Testing Techniques refer to the methods and approaches used to assess the
quality, functionality, and performance of software applications. These
techniques help identify defects, validate functionality, and ensure that the
software meets the specified requirements. Here are some common testing
techniques used in software development:
2. White Box Testing: White Box Testing is the opposite of Black Box Testing. It
examines the internal structure and code of the application to validate its logic
and execution. Testers have access to the application's code and use
69
techniques like code coverage analysis to ensure that all code paths are tested
and that potential issues are identified.
70
These are just a few examples of testing techniques used in software
development. Depending on the specific requirements and nature of the
application, additional testing techniques may be employed to ensure
comprehensive testing coverage and high-quality software delivery.
Test Automation
Test Automation refers to the process of using software tools and scripts to
automate the execution of tests, the comparison of actual results with
expected results, and the generation of test reports. It is an essential practice
in software development and testing that brings efficiency, reliability, and
repeatability to the testing process. Here are some key points about Test
Automation:
1. Efficiency and Time Savings: Test Automation significantly reduces the time
and effort required to execute tests. Automated tests can be run repeatedly,
consistently, and at a much faster pace compared to manual testing. This
allows testers to focus on more critical tasks and accelerates the overall testing
process, leading to faster software delivery.
2. Increased Test Coverage: With Test Automation, a larger number of test
cases can be executed, covering a broader range of scenarios. This ensures
comprehensive testing coverage and helps identify defects and issues that
might be missed in manual testing. Automated tests can handle repetitive
tasks, data-driven tests, and extensive regression testing more effectively.
4. Reusability and Maintainability: Test Automation allows for the reuse of test
scripts and test suites across different projects, releases, and iterations. Once
automated tests are developed, they can be easily maintained and updated to
accommodate changes in the software under test. This reusability and
maintainability save time and effort in the long run.
71
6. Scalability: Test Automation supports scaling up the testing efforts, allowing
for the execution of a large number of tests across multiple configurations,
platforms, and environments. Automated tests can be run in parallel on
different machines or virtual environments, speeding up the testing process
and handling diverse testing requirements.
Debugging, on the other hand, is the process of identifying and fixing issues or
defects in the code. It involves:
1. Identifying Bugs:
Analyzing error messages, unexpected behavior, or crashes to identify
the root cause of the issue.
2. Reproducing Issues:
Attempting to replicate the problem in a controlled environment to
understand its triggers and conditions.
3. Isolating Problems:
Narrowing down the scope of the issue to identify the specific code or
functionality causing the problem.
72
4. Fixing Bugs:
Modifying the code to address the identified issues, whether they're
logical errors, syntax errors, or other issues impacting the application's
behavior.
Testing frameworks play a critical role in ensuring the quality, reliability, and
maintainability of OJet-JS applications by providing developers with tools and
utilities for writing and executing tests. These frameworks offer various
features to support different types of testing, including unit testing, integration
testing, and end-to-end testing. Let's delve deeper into some popular testing
frameworks for OJet-JS:
1. Jasmine:
Overview: Jasmine is a behavior-driven testing framework for
JavaScript that focuses on simplicity and readability. It provides a
clean and expressive syntax for defining test suites, test cases, and
expectations, making it easy to write and understand tests.
Features: Jasmine offers a rich set of features, including a built-in
assertion library, support for asynchronous testing with async and
await, and customizable test runners for browser and Node.js
environments.
Usage: Developers write tests using Jasmine's describe, it, and
expect functions to define test suites, individual test cases, and
expectations, respectively.
2. Mocha:
Overview: Mocha is a flexible testing framework that supports
various testing styles and environments. It provides a robust set of
features for organizing and executing tests, including support for
different assertion libraries, test reporters, and asynchronous
testing patterns.
Features: Mocha allows developers to choose their preferred
assertion library (such as Chai or Should.js) and test runner (such
as Karma or Node.js) for maximum flexibility. It also supports
features like test skipping, test filtering, and parallel test
execution.
Usage: Developers use Mocha's describe, it, and assert functions
to define test suites, test cases, and assertions, respectively.
73
Mocha provides hooks like before, after, beforeEach, and
afterEach for setting up and tearing down test environments.
3. Karma:
Overview: Karma is a test runner that facilitates the execution of
tests in multiple browsers and environments. It integrates with
popular testing frameworks like Jasmine and Mocha, allowing
developers to write tests using their preferred framework and run
them across different browsers and devices.
Features: Karma provides features for automated testing,
including continuous integration with tools like Travis CI and
Jenkins, live reloading of tests, and test result reporting. It also
supports features like code coverage analysis and browser
debugging.
Usage: Developers configure Karma to load and run tests in
specified browsers using configuration files (karma.conf.js). They
can specify test frameworks, reporters, plugins, and other settings
to customize the testing environment.
4. QUnit:
Overview: QUnit is a lightweight testing framework developed by
the jQuery team. It is well-suited for unit testing JavaScript code
and provides a simple and easy-to-use API for defining and
running tests.
Features: QUnit offers a minimalistic approach to testing with
features like test grouping, assertions, and asynchronous test
support. It is designed to be simple to set up and use, making it a
popular choice for testing jQuery plugins and other JavaScript
libraries.
Usage: Developers write tests using QUnit's test function to define
individual test cases and assertions. QUnit provides hooks like
setup and teardown for setting up and tearing down test
environments.
5. Selenium WebDriver:
Overview: Selenium WebDriver is a powerful tool for automating
web browser interactions, making it ideal for end-to-end testing of
OJet-JS applications. It allows developers to simulate user
interactions and verify the behavior of their applications across
different browsers and platforms.
Features: Selenium WebDriver provides a comprehensive set of
features for web browser automation, including navigation, form
submission, element interaction, and JavaScript execution. It
74
supports multiple programming languages (such as JavaScript,
Java, Python, and C#) and integrates with testing frameworks like
Jasmine and Mocha.
Usage: Developers write test scripts using Selenium WebDriver's
API to interact with web elements, perform actions, and assert
expected outcomes. They can use WebDriver bindings for
JavaScript (such as webdriverio or selenium-webdriver) to write
tests in JavaScript.
1. Setup Jasmine:
2. Initialize Jasmine:
<!DOCTYPE html>
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="stylesheet" href="../node_modules/jasmine-core/lib/jasmine-
core/jasmine.css">
<script src="../node_modules/jasmine-core/lib/jasmine-
core/jasmine.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine-
html.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/boot.js">
75
</script>
</head>
<body> <!-- Include your spec files here -->
<script src="mySpec.js"></script> </body> </html>
describe('MyComponent', function() {
it('should return true', function() {
expect(true).toBe(true); });
6. Run Tests:
Open the spec-runner.html file in a web browser to run your
Jasmine tests.
Jasmine will execute your test cases and display the results in the
browser.
7. Refine and Repeat:
Refine your test cases as needed to cover different scenarios and
edge cases.
Repeat the testing process regularly as you make changes to your
application code.
By following these steps meticulously, you can effectively write and execute
unit tests for your OJet-JS applications using Jasmine.
76
Debugging techniques and tools are essential for identifying and resolving
issues in OJet-JS applications.
Here are some tools -
1. Console Logging:
Overview: Console logging is a ubiquitous debugging technique
that allows developers to output messages, variable values, and
other information to the browser console during runtime. It's
useful for tracking the flow of execution, diagnosing unexpected
behavior, and monitoring the values of variables.
Usage: Besides logging variable values, developers can use
console.log() to log function calls, object properties, array
contents, and even custom messages. It's also possible to use
string interpolation with template literals (${}) to format log
messages dynamically.
Best Practices: While console logging is helpful for debugging, it's
essential to remove or comment out debug logs before deploying
the application to production to avoid unnecessary overhead and
potential security risks.
2. Debugger Statement:
Overview: The debugger statement is a JavaScript keyword that
triggers a breakpoint in the code when encountered. When the
browser's debugger encounters the debugger statement, it
pauses execution and opens the debugger tool, allowing
developers to inspect the call stack, variables, and code execution
context.
Usage: Developers insert debugger; statements at specific
locations in the code where they suspect issues or want to
examine the program state. Once execution reaches the debugger
statement, developers can step through the code, evaluate
expressions, and diagnose problems interactively using the
debugger tool.
Best Practices: It's essential to remove or comment out debugger
statements before deploying the application to production, as
they can halt execution and impact performance if left in the
code.
3. Browser DevTools:
Overview: Browser Developer Tools, such as Chrome DevTools
and Firefox Developer Tools, provide a comprehensive set of
77
features for debugging web applications. These tools include
panels for inspecting and editing HTML, CSS, and JavaScript,
monitoring network activity, analyzing performance, and
debugging JavaScript code.
Usage: Developers access browser DevTools by pressing F12 or
right-clicking on the page and selecting "Inspect." They can then
navigate through different panels, such as "Console" for logging
messages, "Sources" for debugging JavaScript code, "Network" for
monitoring network requests, and "Performance" for analyzing
page performance.
Best Practices: Familiarize yourself with the various features and
shortcuts offered by browser DevTools to streamline the
debugging process. Experiment with different panels and tools to
gain insights into your application's behavior and performance.
4. Breakpoints:
Overview: Breakpoints are markers set in the code that pause
JavaScript execution when reached. Developers use breakpoints
to inspect the state of the application at specific points in the
code, including variable values, function calls, and control flow.
Usage: To set a breakpoint, developers click on the line number in
the browser's debugger interface where they want execution to
pause. When the code reaches the breakpoint during runtime,
execution halts, allowing developers to examine the call stack,
step through the code, and interactively debug issues.
Best Practices: Use breakpoints strategically to focus debugging
efforts on specific areas of the codebase. Avoid setting too many
breakpoints, as it can clutter the debugger interface and make
debugging more challenging.
5. Console Methods:
Overview: In addition to console.log(), browser consoles provide
several other logging methods for different purposes:
console.error(): Logs error messages with a red icon,
indicating critical issues.
console.warn(): Logs warning messages with a yellow icon,
indicating potential problems.
console.info(): Logs informational messages with a blue
icon, providing supplementary details.
console.assert(): Logs an error message if a specified
condition evaluates to false.
78
Usage: Developers use these console methods to categorize and
differentiate log messages based on their severity and purpose.
For example, console.error() is suitable for logging critical errors,
while console.info() can be used for informational messages.
Best Practices: Choose the appropriate console method based on
the nature and severity of the message being logged. Use
console.assert() to validate assumptions and detect unexpected
conditions during runtime.
6. Remote Debugging:
Overview: Remote debugging enables developers to debug OJet-
JS applications running on remote devices or servers from their
development machines. This technique is invaluable for
troubleshooting issues that only occur in specific environments,
such as mobile devices or production servers.
Usage: To enable remote debugging, developers typically start a
remote debugging session in the browser's developer tools and
connect to the remote device or server using a provided URL or
connection protocol (e.g., WebSocket). Once connected,
developers can inspect and debug the application remotely using
the same debugging features available locally.
Best Practices: Ensure that remote debugging is enabled and
configured securely to protect sensitive data and prevent
unauthorized access. Follow the documentation and guidelines
provided by the browser vendor for setting up and using remote
debugging effectively.
11. Deploying OJet-JS Applications
Overall, it's about making your application accessible to users on the web or
mobile devices while ensuring reliability, security, and scalability.
79
1. Optimize Code:
Explanation: Optimizing code involves reducing file sizes, removing
unnecessary code, and optimizing assets to improve the performance of
the application. This process helps in minimizing load times and
enhancing the overall user experience.
Example:
Suppose you have an OJet-JS application with large JavaScript and CSS files. By
minimizing these files using tools like UglifyJS and cssnano, you can remove
whitespace, comments, and redundant code, resulting in smaller file sizes.
Additionally, optimizing images using tools like ImageOptim or TinyPNG
reduces their size without compromising quality.
Benefits:
2. Bundle Assets:
Explanation: Bundling assets involves combining multiple files, such as
JavaScript, CSS, HTML, and images, into bundles to optimize
performance by reducing the number of HTTP requests required to load
the application. This process is essential for improving load times,
especially in large-scale applications where numerous assets are
involved.
Example:
Let's say you have an OJet-JS application with multiple JavaScript files
representing different modules or components of the application. Without
bundling, each JavaScript file would require a separate HTTP request when the
application loads in the browser. This can lead to increased latency and slower
page load times, especially on networks with high latency or low bandwidth.
80
By bundling the JavaScript files together using a module bundler like Webpack,
you can create a single bundle file containing all the JavaScript code required
for the application. This bundle file can then be loaded with a single HTTP
request, reducing overhead and improving performance.
Similarly, CSS files, HTML templates, and image assets can also be bundled
together to minimize the number of requests and optimize load times.
Webpack and Oracle JET's CLI offer configuration options and plugins for
bundling assets efficiently, allowing developers to customize bundling
strategies based on the application's requirements and performance goals.
Here's a simplified example of bundling JavaScript files using Webpack's
configuration:
// webpack.config.js
const path = require('path');
module.exports = { entry: './src/index.js', // Entry point of the application
output: { filename: 'bundle.js', // Output bundle file path:
path.resolve(__dirname, 'dist'), // Output directory },
module: {
rules: [ { test: /\.js$/, // Apply bundling to JavaScript files exclude:
/node_modules/,
81
necessary code is included in each bundle, avoiding unnecessary
bloat and optimizing load times further.
2. Asset Size: Be mindful of the size of bundled assets, especially
JavaScript bundles, as large bundle sizes can impact initial load
times and user experience. Implement techniques like tree
shaking and code minification to reduce bundle size where
possible.
Benefits:
1. Streamlined Deployment: Generating static files simplifies the
deployment process by providing a single, optimized package that
contains all necessary assets.
2. Performance Optimization: Compiled static files are optimized for
performance, reducing load times and enhancing the overall user
experience.
Considerations:
1. Build Configuration: Customize the build process to meet the
specific requirements of the application, such as enabling code
minification, enabling source maps, or configuring asset hashing
for cache busting.
2. Dependency Management: Ensure that all dependencies are
included in the build process and properly resolved to prevent
runtime errors.
82
4. Configure Environment Variables:
Explanation: Configuring environment variables involves setting
environment-specific configuration settings, such as API endpoints or
database credentials, to ensure consistent behavior across different
deployment environments (e.g., development, staging, production).
Example:
Developers can define environment-specific configuration settings using
environment variables or configuration files. For example, setting an
environment variable named API_URL to different values for development,
staging, and production environments allows the application to dynamically
adapt to each environment's API endpoint.
Benefits:
1. Environment Flexibility: Environment variables provide a flexible
way to configure application settings based on the deployment
environment without modifying the codebase.
2. Security: Separating sensitive information, such as API keys or
database credentials, from the codebase enhances security and
minimizes the risk of exposing sensitive data.
83
1. Semantic Versioning: Follow semantic versioning principles
(MAJOR.MINOR.PATCH) to convey the significance of changes
accurately.
2. Release Notes: Document changes and enhancements in release
notes associated with each version to inform users about updates
and improvements.
7. Documentation:
84
Documentation can be created using Markdown, HTML, or other markup
languages and stored in a version-controlled repository alongside the
codebase. It should cover deployment instructions, including prerequisites,
setup steps, and configuration details, as well as information on dependencies,
build processes, and troubleshooting tips.
Benefits:
1. Knowledge Sharing: Documentation enables knowledge sharing
among team members by providing clear instructions and
guidelines for deploying and maintaining the application.
2. Onboarding: Well-documented deployment procedures help
onboard new team members quickly and efficiently, reducing
ramp-up time and ensuring consistency in deployment practices.
Considerations:
1. Accessibility: Make documentation easily accessible to all team
members by storing it in a central location and providing clear
navigation and search functionality.
2. Maintenance: Regularly update and maintain documentation to
reflect changes in the codebase, dependencies, and deployment
processes.
85
1. Size Limitations: Be mindful of the size of the packaged archive,
especially when deploying to environments with limited storage
or bandwidth constraints.
2. Dependency Management: Ensure that all dependencies are
included in the package and properly resolved to prevent runtime
errors during deployment.
10. Backup:
Explanation: Creating backups of the packaged application and relevant
data is essential for facilitating restoration in case of deployment issues
or unexpected problems. Backups ensure data integrity and reliability,
providing a safety net for recovering from unforeseen incidents.
Example:
Developers can use backup tools or scripts to automate the creation of
backups of the packaged application and relevant data. This may involve
86
storing backups in a secure location, such as a cloud storage service or
dedicated backup server, with regular intervals and versioning to ensure data
integrity and availability.
Benefits:
1. Disaster Recovery: Backups provide a safety net for recovering
from deployment failures, data loss, or other unforeseen
incidents, minimizing downtime and business impact.
2. Data Integrity: By regularly backing up the packaged application
and relevant data, developers can ensure data integrity and
reliability, preserving the state of the application and associated
resources.
Considerations:
1. Backup Frequency: Determine the frequency of backups based on
the criticality of the application and the frequency of changes or
updates.
2. Storage Security: Ensure that backups are stored securely to
prevent unauthorized access or data breaches, implementing
encryption and access controls as needed.
87
Ease of Setup: Traditional web hosting providers often offer
simple setup processes for deploying static files, making
them suitable for straightforward deployments.
Limited Scalability: Scaling traditional web hosting
environments may require manual intervention and could
be limited in terms of scalability compared to cloud-based
solutions.
Cost: Costs associated with traditional web hosting typically
depend on factors such as storage space, bandwidth usage,
and additional features.
Example Providers: Bluehost, HostGator, DreamHost.
2. Cloud Hosting Platforms:
Description: Cloud hosting platforms offer scalable infrastructure
for deploying and hosting OJet-JS applications. Providers offer
services for deploying static files, serverless functions, or
containerized applications.
Considerations:
Scalability: Cloud hosting platforms provide scalable
infrastructure that can automatically adjust to handle
varying levels of traffic, ensuring high availability and
performance.
Managed Services: Some cloud hosting platforms offer
managed services for deploying and managing OJet-JS
applications, reducing the operational overhead for
developers.
Cost and Pricing Models: Costs associated with cloud
hosting depend on factors such as usage, resource
consumption, and pricing models (e.g., pay-as-you-go,
reserved instances).
Example Providers: Amazon Web Services (AWS), Microsoft
Azure, Google Cloud Platform (GCP).
3. Serverless Computing:
Description: Serverless computing platforms abstract away
infrastructure management, allowing developers to deploy OJet-JS
applications as serverless functions (e.g., AWS Lambda, Azure
Functions).
Considerations:
Cost Efficiency: Serverless computing platforms often offer
cost-efficient pricing models based on usage, with no
charges for idle resources.
88
Scalability: Serverless architectures can automatically scale
to handle incoming requests, providing high availability and
scalability without manual intervention.
Cold Start Latency: Cold start latency, the delay in spinning
up new instances, may impact the responsiveness of
serverless functions for infrequently accessed applications.
Example Providers: AWS Lambda, Azure Functions, Google Cloud
Functions.
4. Containerization and Orchestration:
Description: Containerization platforms like Docker enable
packaging OJet-JS applications into containers for consistent
deployment across environments. Container orchestration tools
like Kubernetes provide management and scaling capabilities for
containerized applications.
Considerations:
Portability: Containerized OJet-JS applications are highly
portable and can be deployed across different
environments with consistent behavior.
Scalability and Resilience: Container orchestration
platforms offer features for scaling applications
horizontally, ensuring high availability and resilience against
failures.
Complexity: Containerization and orchestration introduce
additional complexity compared to traditional deployment
methods, requiring expertise in container technologies and
orchestration tools.
Example Tools: Docker, Kubernetes, Amazon Elastic Kubernetes
Service (EKS), Google Kubernetes Engine (GKE), Azure Kubernetes
Service (AKS).
5. Static Site Generators (SSGs):
Description: Static site generators like Hugo or Jekyll allow
developers to build OJet-JS applications as static sites, which can
be deployed to various hosting platforms.
Considerations:
Performance: Static sites offer fast load times and improved
performance due to pre-rendered content and reduced
server-side processing.
Simplicity: Static site generators simplify deployment by
generating static HTML files that can be hosted on any web
server or content delivery network (CDN).
89
Dynamic Content Limitations: Static sites are suitable for
content-centric applications but may have limitations for
dynamic content or complex interactions.
Example Tools: Hugo, Jekyll, Gatsb
90
Deployment Automation: Utilize deployment scripts or
configuration management tools to automate the
deployment of packaged applications to hosting
environments.
Rollback Mechanisms: Implement rollback mechanisms to
revert to previous versions in case of deployment failures or
issues, ensuring minimal disruption to users.
Tools: AWS CodePipeline, Azure DevOps, GitHub Actions, GitLab
CI/CD.
3. Feature Branch Workflow:
Description: In the feature branch workflow, developers work on
new features or bug fixes in separate branches, which are then
merged into the main branch (e.g., master) via pull requests.
CI Integration: Set up CI pipelines to trigger builds and tests
automatically for each pull request, providing feedback to
developers on the quality and correctness of their changes before
merging.
CD Integration: Upon merging changes into the main branch,
trigger CD pipelines to automatically deploy the updated
application to staging or production environments, depending on
the workflow.
Code Review: Conduct code reviews as part of the pull request
process to ensure code quality, maintainability, and adherence to
coding standards.
4. Infrastructure as Code (IaC):
Description: IaC involves defining infrastructure configurations
and provisioning resources using code, allowing for consistent and
reproducible deployment environments.
CI/CD Integration: Incorporate infrastructure provisioning and
configuration into CI/CD pipelines, automating the setup and
teardown of deployment environments.
Version Control: Store infrastructure configurations alongside
application code in version control systems, enabling versioning,
collaboration, and auditability.
Immutable Infrastructure: Adopt immutable infrastructure
patterns to treat infrastructure as disposable and recreate
deployment environments from scratch with each deployment.
5. Blue-Green Deployment:
91
Description: Blue-Green Deployment involves maintaining two
identical production environments (blue and green), with only one
environment actively serving user traffic at a time.
CI/CD Integration: Automate the provisioning and deployment of
blue and green environments using CI/CD pipelines, ensuring
consistency and reliability.
Traffic Routing: Use load balancers or DNS configurations to
control traffic routing between blue and green environments,
enabling zero-downtime deployments and easy rollback.
Validation and Rollback: Validate the newly deployed
environment before routing traffic to it, and rollback to the
previous environment in case of issues or failures during
validation.
92