ojx
v1.1.0
Published
OJET custom components and utilities
Maintainers
Readme
ojx: OJET eXtension - Custom Elements and Utilities
ojx is an extension to OJET (Oracle JET) - MVVM
Installation:
npm i ojxor
yarn add ojxConfiguration:
Add the following block in project's src/js/path_mapping.json after "ojs" block.
"ojx": {
"cwd": "node_modules/ojx",
"debug": {
"src": ["dist/**"],
"path": "libs/ojx",
"pathSuffix": "/dist'"
},
"release": {
"src": ["dist/**"],
"path": "libs/ojx",
"pathSuffix": "/dist'"
}
},Usage:
import
Import ojx AMD modules in src/js/appController.js or src/js/root.js or any viewModel.js
define(['knockout', 'jquery',
..., ..., ..., ...,
'ojx/bundle', // load all modules
'ojx/elements', // for all ojx-elements: <ojx-bind-html>, <ojx-module>, ...
'ojx/bind-html', // for <ojx-bind-html> only
'ojx/module', // for <ojx-module> only
'ojx/utils', // for ojet util functions
'ojx/dom', // for DOM util functions
'ojx/object', // for object util functions
'ojx/type', // for type util functions
'ojx/data-time', // for date-time util functions
'ojx/storage', // for multi-user sessionStorage and localStorage
'ojx/file-system', // for file system util functions
'ojx/libs', // to export ko, jquery($) to global
], function (ko, $, ...) {
});ojx-elements - ojx/elements
NOTE: you need to import 'ojx/elements' or 'ojx/bind-html', 'ojx/module' in viewModel.js. Refer import guide in Usage section above.
In views/*.html
... ... ...
<!-- <ojx-bind-html> for <oj-bind-dom> -->
<ojx-bind-html value="<strong>HTML</strong> text"></ojx-bind-html>
<ojx-bind-html value="[[sectionTitle]]"></ojx-bind-html>
<!-- optionally use voidxss attribute to void XSS content in value -->
<ojx-bind-html value="[[sectionTitle]]" voidxss></ojx-bind-html>
... ... ...
<!-- <ojx-module> simplified wrapper for <oj-module> -->
<ojx-module
path="customers/view-customer"
data="[[customerRecord]]"
render="[[toggleModuleRender]]"></ojx-module>
... ... ...Utilities - ojx/utils
ojx.domConfig
// for view.html: <oj-bind-dom config="[[ titleConfig ]]"></oj-bind-dom>
// in viewModel.js
this.titleConfig = ojx.domConfig( '<strong>HTML</strong> Text' );
ojx.moduleConfig
// ... ... ... ... ... ... ... ... ... ... ...
// for view.html: <oj-module config="[[ editCustViewConfig ]]"></oj-module>
// in viewModel.js
let moduleName = 'customers/edit-view';
let params = {
user: {
firstName: 'Donal',
lastName: 'Duck',
email: '[email protected]'
}
};
this.editCustViewConfig = ojx.moduleConfig( moduleName, params );
ojx.arrayDataProvider
returns oj ArrayDataProvider (ojs/ojarraydataprovider) for a given source array
/**
* returns oj ArrayDataProvider (ojs/ojarraydataprovider) for a given source array
* @param {Array} srcArray - The source array
* @param {string} keyAttribute - The key attribute (e.g., 'id', 'userId', 'departmentId', 'lastUpdated')
* @param {string} sortOrder - for ascending : 'asc' | 'ascending'
* for descending: any value other than ['asc', 'ascending'] (ex., 'desc', 'descending')
* @param {string} sortBy - The key to sort by if ohter than keyAttribute (e.g., 'departmentId', 'StartDate')
* @param {string} isDateTime - is sortBy field of type Date/Time?
*/
let ojTableDataProvider1 = ojx.arrayDataProvider( srcArray, keyAttributes, sortOrder, sortBy, isDateTime );
// auto-detect key field in source array for unique-key
let ojTableDataProvider2 = ojx.arrayDataProvider( srcArray );
// use 'DepartmentId' field as key, and only indicate sort as desc - but does not sort the source array
let ojTableDataProvider3 = ojx.arrayDataProvider( srcArray, 'DepartmentId', 'desc' );
// use 'DepartmentId' field as unique key, and re-sort the source array by DepartmentId (descending)
let ojTableDataProvider4 = ojx.arrayDataProvider( srcArray, 'DepartmentId', 'desc*' );
// use 'id' field as unique key, and re-sort the source array by 'firstName' (ascending)
let ojTableDataProvider5 = ojx.arrayDataProvider( srcArray, 'id', 'asc', 'firstName' );
// use 'id' field as unique key, and re-sort the source array by 'lastUpdatedOn' (descending) + auto-detects date/time field by its fieldname
let ojTableDataProvider6 = ojx.arrayDataProvider( srcArray, 'id', 'desc', 'lastUpdatedOn' );
// use 'id' field as unique key, and re-sort the source array by 'lastUpdatedOn' (descending) and consider 'lastUpdatedOn' as date-time field.
let ojTableDataProvider7 = ojx.arrayDataProvider( srcArray, 'id', 'desc', 'lastUpdatedOn', true );
DOM utilities - ojx/dom
DOM selector
// instead of document.querySelector( '#pgHeader' );
let secHeaderA = _$( '#sectionHeader' );
// OR
let secHeaderB = ojx.$( '#pgHeader' );
// instead of document.querySelectorAll( '.menu-items' );
let menuItemsA = _$$( '.menu-items' );
// OR
let menuItemsB = ojx.$$( '.menu-items' );Sanitize XSS in HTML and JSON Object
sanitizeXSS( '<script>alert("Hi")</script>' ); // '<xss-script>alert("Hi")</xss-script>'
sanitizeXSS( '<button onclick="doSomething()">Click Me</button>' ); // '<button xss-onclick="doSomething()">Click Me</button>'
sanitizeXSS( { note: '<button onclick="doSomething()">Click Me</button>' } ); // { note: '<button xss-onclick="doSomething()">Click Me</button>' }
// OR
ojx.sanitizeXSS( '<script>alert("Hi")</script>' ); // '<xss-script>alert("Hi")</xss-script>'
Object - ojx/object
{ }.__keys( deep? )
To get keys
let testObjA = {
name: 'Javascript',
altName: 'ECMA Script',
active: true
};
console.log( testObjA.__keys() ); // ['name', 'altName', 'active']
// OR
console.log( ojx.keysOf(testObjA) ); // ['name', 'altName', 'active']
// ----------------------------------------------------------------
const testObjB = {
company: "TechCorp",
employees: [
{ name: "Tom", role: "Dev" },
{ name: "Jerry", role: "Design" }
]
};
testObjB.__keys( true ); // ["company", "employees", "employees[0].name", "employees[0].role"]
// OR
ojx.keysOf(testObjB, true ); // ["company", "employees", "employees[0].name", "employees[0].role"]
{ }.__merge( ObjX1, ObjX2, ...) | ojx.merge( targetObj, ObjX1, ObjX2, ... )
High-performance JSON-object merge.
const user = { profile: { name: 'JavaScript' } };
const update1 = { profile: { age: 30 }, settings: { dark: true } };
const update2 = { profile: { location: 'everywhere' } };
user.__merge(update1, update2);
// OR
ojx.merge(user, update1, update2)
// Result:
// user = {
// profile: { name: 'JavaScript', age: 30, location: 'everywhere' },
// settings: { dark: true }
// }
{ }.__ofClass()
To find the object's Class
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
// <h1 id="sectionTitle">Section Title</h1>
document.getElementById('sectionTitle').__ofClass(); // 'HTMLHeadingElement'
document.querySelector('h1').__ofClass(); // 'HTMLHeadingElement'
/* HTML
<ul>
<li class="menu-items">menu item 01</li>
<li class="menu-items">menu item 02</li>
<li class="menu-items">menu item 03</li>
<li class="menu-items">menu item 04</li>
<li class="menu-items">menu item 05</li>
</ul>
*/
document.getElementsByClassName('menu-item').__ofClass(); // 'HTMLCollection'
document.querySelectorAll('.menu-item').__ofClass(); // 'NodeList'
[ ].__sortBy | ojx.sortBy
Sorts an array of objects based on a specific field and order.
/**
* Sorts an array of objects based on a specific field and order.
* @param {Array} srcArray - The source array
* @param {string} sortByField - The keyField to sort by (e.g., 'id', 'userId', 'lastUpdated', 'address.shipping.zip')
* @param {string} orderBy - for ascending : 'asc' | 'ascending'
* for descending: any value other than ['asc', 'ascending'] (ex., 'desc', 'descending')
* @param {string} isDateTime - is sortByField of type Date/Time?
*/
ojx.sortBy(srcArray, sortByField, orderBy, isDateTime);
let sortedArray1 = ojx.sortBy( [...srcArray], sortByField, orderBy, isDateTime );
let sortedArray2 = ojx.sortBy( [...srcArray], 'lastUpdatedOn', 'desc', true );
let sortedArray3 = ojx.sortBy( [...srcArray], 'itemPrice', 'desc' );
let sortedArray4 = ojx.sortBy( [...srcArray], 'firstName' );
// also you can
let sortedArray5 = [ ...srcArray ];
sortedArray5.__sortBy('firstName');
console.log( sortedArray5 );
{ }.__valueOfPath | ojx.valueOfPath
Deeply retrieves a value from an object/array using a string path.
/**
* Deeply retrieves a value from an object/array using a string path.
* Supports: "address.city", "tags[0]", "orders.0.id"
*/
// ojx.valueOfPath(obj, path);
//-------------------------------------------------------------
const testDataX = {
name: 'Unknown',
age: 10,
address: {
billing: {
address: 'billing address line',
city: 'billing city',
state: 'billing state',
zip: '111111'
},
shipping: {
address: 'shipping address line',
city: 'shipping city',
state: 'shipping state',
zip: '222222'
}
}
};
ojx.valueOfPath(testDataX, 'address.shipping.zip'); // 222222
// OR
testDataX.__valueOfPath('address.shipping.zip'); // 222222
//-------------------------------------------------------------
const testDataY = [
{ id: 2, info: { name: "Beta", date: "2023-01-01" } },
{ id: 1, info: { name: "Alpha 10", date: "2021-01-01" } },
{ id: 3, info: { name: "Alpha 2", date: "2022-01-01" } },
{ id: 4, info: null }
];
ojx.valueOfPath(testDataY, '[0].id'); // 2
ojx.valueOfPath(testDataY, '1.info.name'); // "Alpha 10"
ojx.valueOfPath(testDataY, '[2].info.date'); // "2022-01-01"
ojx.valueOfPath(testDataY, 'info.name'); // undefined
ojx.valueOfPath(testDataY, '[3].info'); // null
//-------------------------------------------------------------
const testDataZ = [{ x: { y: [ { z: "found" } ] } }];
ojx.valueOfPath(testDataZ, "0.x.y[0].z"); // "found"
ojx.valueOfPath(testDataZ, "0.x.y.0.z"); // "found"
Type - ojx/type
Check type with ofType | ojx.ofType
// instead of typeof xyz === 'type'
// use ofType which returns / checks exact variable type; particularly for array and null.
let testNull = null;
let testArray = [];
let testString = '';
let testObject = {};
ofType( testNull ); // returns 'null'
ofType( testArray ); // returns 'array'
ofType( testArray, 'array' ); // returns true : alternate to Array.isArray(testArray)
ofType( document.getElementsByClassName('menu-item') ); // returns 'array-like'
function fx () {
console.log(typeof arguments, ofType(arguments), ofClass(arguments) ); // object array-like Arguments
};
Get Class with ofClass | ojx.ofClass
ofClass( document.querySelectorAll('h1') ); // 'NodeList'
ofClass( document.getElementsByTagName('h1') ); // 'HTMLCollection'
ofClass( document.querySelector('h1') ); // 'HTMLHeadingElement'Test Empty with isEmpty
let testArrayX = [];
let testStringX = '';
let testObjectX = {};
isEmpty( testArrayX ); //returns true
isEmpty( testStringX ); //returns true
isEmpty( testObjectX ); //returns trueDate/Time - ojx/data-time
dateYYYYMMDD | ojx.dateYYYYMMDD
now(); // returns current timestamp
dateYYYYMMDD(); // returns current date in YYYYMMDD - ex: 20031206
dateYYYYMMDD( '-' ); // returns current date in YYYY-MM-DD - ex: 2003-12-06
dateYYYYMMDD( '/' ); // returns current date in YYYY/MM/DD - ex: 2003/12/06
dateYYYYMMDD( '/', dateObj ); // returns given date in YYYY/MM/DD
timeHHMMSS | ojx.timeHHMMSS
timeHHMMSS(); // returns current time in HHMMSS - ex: 141030
timeHHMMSS( ':' ); // returns current time in HH:MM:SS - ex: 14:10:30
timeHHMMSS( ':', dateObj ); // returns given time in HH:MM:SSStorage - ojx/storage for sessionStorage and localStorage utils
let storage = sessionStorage; // or localStorage
storage.user(); // get current userStoreToken
storage.user( 'userID' ); // set current userStoreToken
storage.getUserItemStr( 'key' ); // get raw value as string
storage.getUserItem( 'key' ); // get parsed value
storage.setUserItemStr( 'key', value ); // store value as raw string
storage.setUserItem( 'key', value ); // store value as JSON String;
storage.removeUserItem( 'key' ); // remove user key-value
storage.entries(); // return all entries (value:string)
storage.entries( true ); // return all entries (parsed=true) as js object
storage.userEntries(); // return only current user entries (value:string)
storage.userEntries( true ); // return current user entries (parsed=true) as js objectFile system - ojx/file-system
fs.readFileContent | ojx.readFileContent
function callbackFnOnSuccess ( fileContent ) {
// ... ... ...
}
function callbackFnOnError ( error ) {
// ... ... ...
}
fs.readFileContent( callbackFnOnSuccess );
fs.readFileContent( callbackFnOnSuccess, callbackFnOnError );
fs.readFileContent( callbackFnOnSuccess, callbackFnOnError, fileTypes );
fs.readFileContent( callbackFnOnSuccess, fileTypes );
// fileTypes: any text file extensions - Ex: '.txt,.html,.css,.js,.json,.yaml,.yml,.csv'
fs.saveToDisk | ojx.saveToDisk
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
fs.saveToDisk(fileContent, fileName);Libs - ojx/libs
Export ko and jQuery($) to window, so you don't have to require in every modules with ['knockout', 'jquery'].
Write less, done fast 🚀
Happy coding until your company replaces you with AI Agents!
