Author Topic: Tree based multilevel screens  (Read 7652 times)

Benjamin Dasari

  • GuiXT Forum
  • Newbie
  • *
  • Posts: 96
    • View Profile
Tree based multilevel screens
« on: August 26, 2016, 04:21:24 PM »
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!
« Last Edit: August 29, 2016, 01:49:35 PM by Benjamin Dasari »