Purpose:
Create dynamically multiple levels of hierarchy based on data and pass values along the way to be used in the last level.
Liquid UI Code:
// SAPLSMTR_NAVIGATION.E0100.sjs
// Delete AxtiveX Container on SAP Easy Access screen
del('X[IMAGE_CONTAINER]');
// Function to trim blank spaces at the end of the string
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');}
// Function to check if the string value is blank
function isBlank(jvar){
if(typeof jvar == 'string') {
jvar = jvar.trim();
}
if(typeof jvar == 'undefined') {
jvar = '';
}
return(jvar == 'undefined' || jvar == undefined || jvar == null || jvar == "" || jvar == void 0);
}
// Function to transform the JSON data into Tree Hierarchical structure
function generateHierarchyData(arrName) {
var roots = [], children = {};
// Find the top level nodes and hash the children based on parent
for (var i = 0, len = arrName.length; i < len; ++i) {
var item = arrName[ i];
p = item.Parent;
target = !p ? roots : (children[p] || (children[p] = [])); // If isBlank 'p' then target = roots, else target = (children[p] || (children[p] = []))
target.push({ value: item });
}
// Function to recursively build the tree
var findChildren = function(parent) {
if (children[parent.value.Id]) {
parent.children = children[parent.value.Id];
for (var i = 0, len = parent.children.length; i < len; ++i) {
findChildren(parent.children[ i]);
}
}
};
// Enumerate through to handle the case where there are multiple roots
for (var i = 0, len = roots.length; i < len; ++i) {
findChildren(roots[ i]);
}
return roots;
}
// Function to create the UI based on parameters passed
function generateHierarchyUI(param) {
nodeId = param.currentNodeId;
nodeVal = param.currentNodeVal;
arrName = param.arrNm;
children = [];
for(var i=0; i<arrName.length; i++){ // For display for Children and Title
var item = arrName[ i];
if(item.Id == nodeId){ // To Display Title
if(isBlank(txcode)){
txcode = item.Txcode;
}
titleName = item.Name;
title(titleName); // Push button that is clicked is displayed as the title
}
if(item.Parent == nodeId){ // Create children array
children.push({value: item});
}
}
onscreen 'SAPLSMTR_NAVIGATION.0100'
pushScreens = false;
enter('?');
}
// Function to perform some action on the last level
// Navigates to the transaction code and uses the value passed
function navigateNode(param) {
var tcode = param.l_tcode;
first_time = '';
enter('/n'+tcode);
onscreen '*'
title(_title);
if(tcode == 'MM02'){ // Rest of the navigation logic based on Transaction code
set('F[Material]',param.nodevalue);
}
enter('?');
}
// Function to display the previous screen when Back button is clicked
function generateHierarchyUIBack(){
backClicked = 'X';
screenArr.pop();
titles.pop();
children = screenArr[screenArr.length -1].slice(0);
}
// Retrieve Data in the below format
// These data may come from-
// a. Fixed File
// b. RFC Call
var testData = [
{"Id": "1", "Name": "1000", "Value": "", "Parent": "", "Txcode": "MM02"},
{"Id": "2", "Name": "Uni Coiler A", "Value": "K1-A", "Parent": "1"},
{"Id": "3", "Name": "Uni Coiler B", "Value": "K1-B", "Parent": "1"},
{"Id": "4", "Name": "Uni Coiler C", "Value": "K1-C", "Parent": "1"},
{"Id": "5", "Name": "Uni Coiler A South East", "Value": "K1-E-SE", "Parent": "2"},
{"Id": "6", "Name": "Uni Coiler A North East", "Value": "K1-E-NE", "Parent": "2"},
{"Id": "7", "Name": "Uni Coiler A South East 1", "Value": "K1-E-SE-1", "Parent": "5"},
{"Id": "8", "Name": "2000", "Value": "", "Parent": "", "Txcode": "VA02"},
{"Id": "9", "Name": "Uni Coiler A South East 1A", "Value": "K1-E-SE-1A", "Parent": "7"},
{"Id": "10", "Name": "Uni Coiler A South East 1B", "Value": "K1-E-SE-1B", "Parent": "7"}
];
// Initial Entry - SAP Easy access
if(isBlank(first_time)){ // UI for Initial entry on Log on
first_time = "X";
txcode = "";
counter = 0;
root_val = [];
root_val = generateHierarchyData(testData); // Pass the Data Array as parameter to the function
firstTitle = 'Root';
title(firstTitle); // Initial Title to be displayed
for(i=0;i<root_val.length;i++){
pushbutton([(i+1)*2,10], ""+root_val[ i].value.Name+"", {"size":[2,30], "process":generateHierarchyUI, "using":{"currentNodeId":root_val[ i].value.Id, "currentNodeVal":root_val[ i].value.Value, "arrNm":testData}});
}
screenArr = [];
titles = [];
screenArr.push(root_val);
titles.push(firstTitle);
} else{ // UI for Second level onwards
if(isBlank(children)){ // If user refreshes the screen OR On reaching the last level
if(!isBlank(txcode)){
enter({"process":navigateNode, "using":{"l_tcode":txcode, "nodevalue":nodeVal}});
} else{
enter('/0');
first_time = '';
}
goto SCRIPT_END;
} else { // For display Multiple levels
if(children.length != 0){
for(i=0;i<children.length;i++){
pushbutton([(i+1)*2,10], ""+children[ i].value.Name+"", {"size":[2,30], "process":generateHierarchyUI, "using":{"currentNodeId":children[ i].value.Id, "currentNodeVal":children[ i].value.Value, "arrNm":testData}});
}
// Code for BACK button below
if(backClicked == 'X'){
titleName = titles[titles.length -1];
backClicked = '';
}
title(titleName);
if(titleName != firstTitle){
pushbutton([TOOLBAR], "@9S@BACK", '?', {"process":generateHierarchyUIBack});
}
if(!pushScreens){
screenArr.push(children);
titles.push(titleName);
pushScreens = true;
}
}
}
}
SCRIPT_END:;
See attachments for code samples!