Purpose:
Create UI dynamically on the same screen based on data passed as an array by converting to hierarchical tree structure.
Liquid UI Code:
[SAPLSMTR_NAVIGATION.E0100.sjs]
load('commonFunctions.sjs'); // Loads the functions file
// This data may come from -
// a. Fixed File
// b. RFC Call
// The data from File or RFC needs to be built into an array similar to below
// "Parent,Child,Value,Tcode"
testData = [];
testData[0] = "Root,1000,K1,";
testData[1] = "1000,Uni Coiler A,K1-A,";
testData[2] = "1000,Uni Coiler B,K1-B,";
testData[3] = "1000,Uni Coiler C,K1-C,";
testData[4] = "Uni Coiler A,Uni Coiler A South East,K1-E-SE,";
testData[5] = "Uni Coiler A,Uni Coiler A North East,K1-E-NE,";
testData[6] = "Uni Coiler A South East,Uni Coiler A South East 1,K1-E-SE-1,";
testData[7] = "Uni Coiler A South East 1,Uni Coiler A South East 1A,K1-E-SE-1A,MM02";
testData[8] = "Uni Coiler A South East 1,Uni Coiler A South East 1B,10030388,IW22";
testData[9] = "Root,2000,100,";
testData[10] = ",Root,,"; // ROOT - Not displayed on screen
testData[11] = "2000,TEST_CASING,100-100,MM03";
// User Interface
clearscreen();
if(isBlank(first_time)){
first_time = "X";
createTree(testData,","); // Pass seperator to the function and use that (Eg: '^','-','^^')
}
drawUI();
[commonFunctions.sjs]
// 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 paint the User Interface
function drawUI(){
if(!isBlank(current.getChildren())){
title(current.name);
for(x=0; x<current.getChildren().length; x++){
pushbutton([(x+1)*2,10], current.children[ x].name, "?", {"size":[2,30], "process":changeCurrent, "using":{"new_current":current.children[ x]}});
}
// If the option to go back is possible
if(current.getParentNode() != null){
pushbutton([TOOLBAR],"@9S@BACK","?", {"process":changeCurrent, "using":{"new_current":current.getParentNode()}});
}
} else{
tcode = current.txcode;
value = current.val;
if(!isBlank(tcode)){
enter({"process":navigateToTransaction, "using":{"l_tcode":tcode, "l_val":value}});
} else{
message('E: No transaction specified');
first_time = '';
enter('?');
}
}
}
// Function to perform some action on the last level
// Navigates to the transaction code and uses the value passed
function navigateToTransaction(param) {
var tcode = param.l_tcode;
first_time = '';
enter('/n'+tcode);
onscreen '*' // Rest of the navigation logic based on Transaction code
title(_title);
if(tcode == 'MM02'){
set('F[Material]',param.l_val);
} else if(tcode == 'MM03'){
set('F[Material]',param.l_val);
goto MM03_PROCESS;
} else if(tcode == 'IW22'){
set('F[Notification]',param.l_val);
goto IW22_PROCESS;
}
enter('?');
goto SCRIPT_END;
onscreen 'SAPLMGMM.0600'
MM03_PROCESS:;
enter();
goto SCRIPT_END;
onscreen 'SAPLIQS0.0100'
IW22_PROCESS:;
enter();
SCRIPT_END:;
}
// Function to initialize the Node containing name, value and transaction code
function Node(name,val,txcode){
this.name = name;
this.val = val;
this.txcode = txcode;
this.children = [];
this.parent = null;
this.setParentNode = function(node){
this.parent = node;
}
this.getParentNode = function(){
return this.parent;
}
this.addChild = function(node){
node.setParentNode(this);
this.children[this.children.length] = node;
}
this.getChildren = function(){
return this.children;
}
}
// Function to refresh and paint the new screen based on button click
function changeCurrent(param){
current = param.new_current;
enter("?");
}
// Function which creates the tree structure from an array and the data seperator passed to it
function createTree(arr,seperator){
// Create the root
for(i=0; i<arr.length; i++){
arrTemp = arr[ i].split(seperator);
if(isBlank(arrTemp[0])){
rootNode = new Node(arrTemp[1],arrTemp[2],arrTemp[3]);
arr.splice(i,1); // Delete the element in the array
break;
}
}
index = 0;
while(arr.length > 0){ // While elements are in the array
if(isBlank(arr[index])) // Reached the end of the data array, break out of while loop
break;
arrTemp = arr[index].split(seperator);
result = inTree(rootNode,arrTemp[0]); // Check whether the Parent is in the Tree
if(!isBlank(result)){
result.addChild(new Node(arrTemp[1],arrTemp[2],arrTemp[3])); // Add the child
arr.splice(index,1); // Delete the element in the array
index = 0;
} else{
index++;
}
}
current = rootNode;
}
// Function which checks to see if the Parent Node exists in current tree
function inTree(rtnode,parent){
var nodeStack = [];
nodeStack.push(rtnode);
while(nodeStack.length > 0){ // Always 1 as 'nodeStack' contains the ROOT node
processNode = nodeStack.pop(); // 'processNode' points to the beginning of the node
if (processNode.name == parent) {
return processNode; // Returns once the node is found and adds to the tree
break;
} else if (processNode.children.length>0) {
for (ii = 0; ii < processNode.children.length; ii++) {
nodeStack.push(processNode.children[ii]);
}
}
}
return ''; // Return an empty string if parent not found in the tree
}
See attachments for code samples!