iSeries EGL

All things EGL for the iSeries / i5 / Power System

A Multi-page RichUI Web Architecture Using EGL

with one comment

Introduction

This post presents a simple multi-page web architecture using EGL and RichUI components. The architecture provides the means to manage navigation between pages while also providing a simple method of allowing the pages to share data using a central storage mechanism.

Be aware that these pages were developed using the open source version of EGL as opposed to using the Community Edition or RDi’s RBD plug in. Therefore, when importing the source into RDi the imports will have to be updated to reflect the libraries provided by the RBD product.

The following EGL handlers and widgets are presented and are described below.

  • HomePage.egl (RUIhandler)
  • This is the home page of the web application . The final html file generated from this EGL part and which is deployed onto the web application server will be the page referenced in the URL (i.e. http://server:port/applicationName/HomePage.html) that was supplied to the browser.

    While it is referenced as the home page for the application it has nothing within to display as would be expected by a normal RUIHander part. It is simply an empty container which holds the current page as requested by the user. It handles user requests for a new page by swapping the current page with the requested page.

  • Page01.egl (RUIWidget)
  • This represents the first page of the web application. Using menu items provided it may navigate to page 2 and page 3.

  • Page02.egl (RUIWidget)
  • This represents the second page of the web application. Using menu items provided it may navigate to page 1 and page 3.

  • Page03.egl (RUIWidget)
  • This represents the third page of the web application. Using menu items provided it may navigate to page 2 and page 1.

 

The files presented above are designed to work together. In the IDE’s project space, they will appear as shown below.

The EGL source files as seen in the EGL project.


You may have noticed a few extra files i.e. Splash.egl and Test.egl. While the first represents a simple screen that presents the name of the application, it can be omitted from your project as it is not an integral part of the architecture. The second file is simply a development artifact and should be ignored.

 

Operation and Behavior

When running the applicatin the first screen to be presented is of course, page 1. To navigate to any other page in the series the user may select the menu option “Go to” from which the appropriate page can be selected. The navigation manager then presents the page selected by the user.

For demonstration purposes, a text message is presented to indicate the page from which navigation occured which was passed by the logic of that page so that it could be presented on the new page. The more important aspect of this message is that it serves to demonstrate how information can be passed from one page to the next during the navigation process.

EGL’s InfoBus is used to pass data from one page to the next as needed. The InfoBus is also used by each web page to communicate to the page navigation manager the page to which the user wishes to navigate. Prior to page navigation each page places data into an EGL Library part which acts as the session data object seen in normal web page development using languages such as Java.

Persisting Session Variables

The SessionLibrary part is presented here. It is used to persist session values so they may be made available to the new page presented by the navigation manager. Just before leaving the page, the logic within that page uses the provided functions to persist the values required for each page.
 

package com.mig.testnav.libraries;

// basic library
library SessionLibrary
	
	// Use Declarations
	//use usePartReference;
	
	// Variable Declarations

        //This is the runtimeEnvironment ("localhost", "TEST" or "PROD")
	private runtimeEnvironment string;	

        //These contain the current screen being displayed and the screen 
        //that will be displayed.  
	private screenName string;
	private toScreenName string;	
	

	function setRuntimeEnvironment(value string in)
		this.runtimeEnvironment = value;
	end
	
	function getRuntimeEnvironment() returns(string)
		return(this.runtimeEnvironment );
	end
	

	function setFromScreen(value string in)
		this.screenName = value;
	end
	
	function getFromScreen() returns(string)
		return(this.screenName);
	end

	
	function setToScreen(value string in)
		this.toScreenName = value;
	end
	
	function getToScreen() returns(string)
		return(this.toScreenName);
	end
	
end

Source code for the SessionLibrary part

 

When using the SessionLibrary in a real project, you can omit the variables for screenName and toScreenName in addition to their functions. They are present simply to demonstrate how variable values can be shared by every screen within the application thereby simulating session variables used by Java servlets.

Storing Constants for a Project

Constants are stored in a separate EGL Library part. Libraries provide a way to make values and functions available across the application.

The ProjectLibrary part that contains constants (which follow standard naming conventions) is presented here.

package com.mig.testnav.libraries;

// basic library
library ProjectLibrary
	
  	// Constant Declarations
	const CONST_APPLICATION_NAME string = "Test Page Navigation";

	const CONST_NAVIGATION_DATA_CALLBACK string = "navigationDataCallBack";	

	const CONST_SESSION_DATA string = "sessionData";

	
	// Variable Declarations
	variableName string;
	
end

Source code for the ProjectLibrary which contains constants

Note how the constant fields are in all uppercase with each word separated by an underscore, which follows the standard for constants. With the fact that each is prefixed with “CONST_” (CONSTant), it ensures that the code completion feature of the IDE will sort the constants together in the list, making it easier to visually isolate a constant from the entries presented.
 
 

The Page Navigation Manager

As previously described this EGL part manages page navigation. It contains an array of widgets ( Widgets[] ) that will hold the pages of the web application.

The EGL program is almost ready to use and has plenty of comments explaining where to make changes before it is ready to be used in your application. There are only 2 places that require modification. The first is the size of the array that holds each page or widget. The second is the function performLazyLoad() which must be modified as indicated in its comment section preceding the function.

package com.mig.testnav.client;

// RUI Handler

//************************************************
//*  Imports for Open Source Version of EGL
//************************************************
import org.eclipse.edt.rui.infobus.infobus;
import org.eclipse.edt.rui.widgets.Box;
import org.eclipse.edt.rui.widgets.Div;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.HTML;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;


//************************************************
//*  Imports for EGL / RBD for RDi
//************************************************
import com.ibm.egl.rui.infobus.infobus;
import com.ibm.egl.rui.widgets.Div;
import com.mig.testnav.libraries.ProjectLibrary;
import egl.javascript.job;
import egl.ui.rui.widget;


//************************************************************
// This is the Navigation Manager (NavMan) for the EGL web site.
// The only responsibility of the developer is to add a new instance
// to the array Widget[].  
//
// No other modifications to the NavMan should be made so that it
// remains as agnostic as possible about the application.
//  

handler HomePage type RUIhandler{initialUI =[ui
            ], onConstructionFunction = start, cssFile = "css/TestNavProject.css", title = "HomePage"}

    ui Div{position = "relative", x = 10, y = 10, width = "1410", height = "2000", borderColor = "LightGray", borderWidth = 1, borderStyle = "solid", children =[splash
            ]};

    //    ui Box{ padding=8,columns = 1,  
    //     	padding=8, columns = 1, 
    //    	x = 10,
    //    	y = 10,   	
    //    	borderColor = "LightGray",
    //    	borderWidth = 1,
    //    	borderStyle = "solid",  
    //    	children = [ splash ] };
    
    splash Div{children =[ new Splash{}
            ], borderWidth = 1, borderColor = "Black"};

    //**********************************************************************
    //*TO DEVELOPER : Change the size of Widget to match the number of pages
    //              : in the application.  Make no other modifications to 
    //              : this section
    //**********************************************************************
    pages Widget[3];
 	
 	
    pageStack int[100];

    fromPage string;

	

    //**********************************************************************
    //* TO DEVELOPER : DO NOT MODIFY THIS FUNCTION *
    //
    function start()

        Infobus.subscribe(ProjectLibrary.CONST_NAVIGATION_DATA_CALLBACK, navigationInfoBusCallBack);
        new Job{runFunction = start2}.schedule(3000);
		
    end

    function start2()
        addPage(1);
    end

    //**********************************************************************
    // This function is called from any of the web application screens.
    // The call is executed via the following construct:
    //	"InfoBus.publish(ProjectLibrary.CONST_APPLICATION_NAME, newPage);"
    //
    // *TO DEVELOPER : DO NOT MODIFY THIS FUNCTION *
    function navigationInfoBusCallBack(event string in, data any in)

        newPage int = data as int;
        if(newPage == -1)
            if(pageStack.getSize() > 1)
                ;
                pageStack.removeElement(pageStack.getSize());
            end
            showPage(pageStack[pageStack.getSize()]);
        else
            addPage(newPage);
        end
    end

	
    //**********************************************************************
    // Performs a lazy load of the web page being requested.   It does this
    // by interrogating the pages array for entries.  The scheme rests upon
    // the idea that each entry of the array corresponds to a page within
    // the navigation sequence. When the page requested is not found one
    // is instantiated and added to the array, thus the lazy load.
    //
    // *TO DEVELOPER : MODIFY THIS FUNCTION TO PERFORM THE FOLLOWING -
    //	    o INCLUDE THE SAME NUMBER OF BOOLEANS AS THERE ARE PAGES
    //      o INCLUDE THE SAME NUMBER OF if (pages[idx] isa Page01) 
    //      o INCLUDE THE SAME NUMBER OF if (newPage == 1 && !page01Found)
    //      Of course, for the last 2 above, modify Page01 and page01Found
    //      to properly reflect the page ID required.
    //
    function performLazyLoad( newPage int )
		
	page01Found boolean   = false;
	page02Found boolean   = false;
	page03Found boolean   = false;

	//Iterate through the array of web pages to determine if the
	//page being requested has already been loaded				
	for (idx int from 1 to pages.getSize())
			
	    //If page is already in the page array then exit
            if (pages[idx] isa Page01) 
		page01Found = true;
	    end
	    //If page is already in the page array then exit
	    if (pages[idx] isa Page02) 
		page02Found = true;
	    end
	    //If page is already in the page array then exit
	    if (pages[idx] isa Page03) 
		page03Found = true;
	    end			
        end

        //If the page requested is not found in the pages[] array 
        //add a new instance of the page.
        if (newPage == 1 && !page01Found)
	    pages[newPage] = new Page01;
        end
        if (newPage == 2 && !page02Found)
	    pages[newPage] =new Page02;
        end
        if (newPage == 3 && !page03Found)
 	    pages[newPage] = new Page03;
        end

        //Now when navigation proceedes it will find the page in 
        //the array.
		 		
    end
	
	
    //**********************************************************************
    // Add the new page to the page stack and show it.
    // *TO DEVELOPER : DO NOT MODIFY THIS FUNCTION *
    function addPage(newPage int in)
    	
    	performLazyLoad(newPage);
    	
        pageStack ::= newPage;
        showPage(newPage);
    end


    //**********************************************************************
    // Show the page requested.
    // *TO DEVELOPER : DO NOT MODIFY THIS FUNCTION *
    function showPage(newPage int in)
        ui.children =[pages[newPage]];

        //This was added to communicate to the destination page information 
        //about page navigation which can be obtained from the Session Library
        //which was placed there by the screen making the navigation request.
        InfoBus.publish(ProjectLibrary.CONST_SESSION_DATA, "GetDataFromSessionLibrary");
        //End of Modification.
        
    end

end

This version of the page navigation manager is for RDi with RBD plug-in

 

How It Performs Navigation

The page navigation manager uses an important feature in EGL, the InfoBus, which is used to communicate information from one RichUI Handler to another. The use of the InfoBus can be seen with these lines;

  • Infobus.subscribe([subscribed name], [function-to-be-called]);
  • function [function-to-be-called](event string in, data any in).

These entries are placed into the RichUI Handler that desires to expose a function (the second entry) through the InfoBus so that other RichUI handlers or widgets may call that function. For those handlers or widgets wishing to call the function, the following is placed inside each.
InfoBus.publish([subscribed name], [value required for the function]);

I’m going to digress a bit. Personally, I wish the designers had instead named the InfoBus functions subscribe and publish as register and evoke so that it better reflects what is actually happening. We’ll see the use of the publish function shortly. Ok, digression over.

Below is a diagram that illustrates how all this works together. The subscribe function has two parameters. (See Item 1 at the bottom of the diagram.) The first provides the name or handle being assigned to the function name provided by the second parameter. The navigationInfoBusCallBack function which was supplied by the subscribe function is registered with the InfoBus. The second argument – the function name to be called – is then made available, i.e. publicized, and can therefore be called by any other program by way of the InfoBus. This is illustrated by the line of code indicated by Item 3 which resides in each of the Rich UI Widget programs represented by Page 1 and Page 2. Item 2 represents the function being called which resides in the navigation manager which receives the page identifier as a parameter value passed by the caller (Item 3).

The InfoBus allows the project’s pages to communicate with the Page Navigation Manager which presents the desired page as requested.

How Screens Pass Data

In a similar manner, each screen of the application also register functions to be evoked, however, they are doing it for a different reason which is to pass data from the current screen to the destination screen. Each screen’s start() function registers the SessionDataInfoBusCallBack function using the InfoBus’s subscribe function as shown;
Infobus.subscribe(ProjectLibrary.CONST_SESSION_DATA, SessionDataInfoBusCallBack);
Remember, the first parameter is simply the name being assigned to the function name supplied by the second parameter. It will be up to the page navigation handler to evoke it.

 

Pages 1, 2 and 3

This section presents screen shots for each page and the source code for each.

 

Page 1

Presented below is a screen shot for page 1. The source code for this page follows.

Page 1


 

Depending upon the version of the IDE you are using, (the open source version of EGL using Eclipse or IBM’s RDi with RDB) you will need to delete the appropriate set of imports. Both sets have been provided for convenience. You just need to decide which set needs to be deleted. No other modifications are required.

package com.mig.testnav.client;

// RUI Widget

//************************************************
//*  Imports for Open Source Verion of EGL
//************************************************
import org.eclipse.edt.rui.infobus.infobus;
import org.eclipse.edt.rui.widgets.Box;
import org.eclipse.edt.rui.widgets.Div;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.GridLayoutData;
import org.eclipse.edt.rui.widgets.GridLayoutLib;
import org.eclipse.edt.rui.widgets.Image;
import org.eclipse.edt.rui.widgets.Menu;
import org.eclipse.edt.rui.widgets.MenuItem;
import org.eclipse.edt.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;


//************************************************
//*  Imports for RBD plug-in for RDi 
//************************************************
import com.ibm.egl.rui.infobus.infobus;
import com.ibm.egl.rui.widgets.Div;
import com.ibm.egl.rui.widgets.GridLayout;
import com.ibm.egl.rui.widgets.GridLayoutData;
import com.ibm.egl.rui.widgets.GridLayoutLib;
import com.ibm.egl.rui.widgets.Image;
import com.ibm.egl.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;

//
//

handler Page01 type RUIWidget{targetWidget = ui, onConstructionFunction = start, cssFile = "css/TestNavProject.css", @VEWidget{category = "Custom"}}



    ui GridLayout{columns = 2, rows = 5, cellPadding = 4, children = [ BodyPane, ControlPane, MenuBar, GridLayout],
    	width = "1400",
    	position = "relative",
    	x = 20,
    	y = 10,
    	borderColor = "Black",
    	borderWidth = 0,
    	borderStyle = "solid"};
    GridLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 1, columns = 2,
    	children = [ Image, GridLayout1],
    	borderColor = "LightGrey",
    	borderStyle = "solid",
    	borderWidth = 1,
    	width = "1350" };
    MigDepartmentName TextLabel{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "Department Name",
    	fontSize = "26",
    	fontWeight = "bold",
    	color = "SteelBlue" };
    MigApplicationName TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 1 }, text = "The Application Name",
    	fontSize = "18",
    	color = "SteelBlue" };
    GridLayout1 GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 2, columns = 3,
    	children = [ MigApplicationName, MigDepartmentName] };
    Image Image{ layoutData = new GridLayoutData{ row = 1, column = 2,
    	horizontalAlignment = GridLayoutLib.ALIGN_RIGHT },
    	src = "MigLogo03.png"};
    MenuBar GridLayout{ layoutData = new GridLayoutData{ row = 2, column = 1,
    	cellPadding = 0 }, cellPadding = 4, rows = 1, columns = 3,
    	backgroundColor = "RGB(245,245,245)",
    	width = "1350",
    	children = [ InnerMenuLayout ],
    	padding = 0,
    	margin = 0,
    	height = "40" 
    	  };
    HelpMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 4 }, text = "Help", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    FileMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "File", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    EditMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 2 }, text = "Edit", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    InnerMenuLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1,
    	verticalAlignment = GridLayoutLib.VALIGN_MIDDLE,
    	horizontalAlignment = GridLayoutLib.ALIGN_LEFT }, cellPadding = 4, rows = 1, columns = 5,
    	children = [ gotoMenu, HelpMenu, EditMenu, FileMenu],
    	height = "32" };
    ControlPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 3, column = 1 }, title = "Control Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ ControlPaneGridLayout ]
    } ] };
    ControlPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3,
    	children = [ TextLabel ] };
    BodyPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 4, column = 1 }, title = "Main Data Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ BodyPaneGridLayout ]
    } ] };
    BodyPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3 };
    gotoMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 3 }, text = "Go to", children = [
 
		new DojoMenuItem {
			text = "Page2", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage2
		},
		new DojoMenuItem {
			text = "Page3", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage3
		},		
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	]};
    TextLabel TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 1 }, text="TextLabel" };
 


    function start()
    	
    	//Register a callback function to process communication requests made through the InfoBus.
        Infobus.subscribe(ProjectLibrary.CONST_SESSION_DATA, SessionDataInfoBusCallBack);   	
        
        //Set Page Titles as required
    	MigDepartmentName.text = "Information Technology";
       	MigApplicationName.text = "Application Name - Page 01";
       	ControlPane.title = "Control Pane Title";
       	BodyPane.title = "Body Pane Title";
       	
       	//Startup Processing to get Runtime Environment and to read properties from XML file.
       	
       	//Get the screen name from which we came.
       	this.TextLabel.text = SessionLibrary.getFromScreen();
      	    
      	       	
    end
 
	function SessionDataInfoBusCallBack(event string in, data any in)
		this.TextLabel.text = "Navigation occurred from " + SessionLibrary.getFromScreen();
	end    
    
    function onPage2(e Event in)
     	toPage(2); 
    end
    
    function onPage3(e Event in)
    	toPage(3); 
    end
    
	//**********************************************************************
	// This function navigates to the requested screen. If the page's design
	// requires certain data elements to be passed to the destination page
	// place the elements into the Session Library established for this purpose 
	// before publishing the navigation request.
	//
    function toPage(newPage int in)
    	;
    	//Set this page as the page from which and to which we are navigating
    	SessionLibrary.setFromScreen("Page01");
    	SessionLibrary.setToScreen("Page0"+newPage);
    	    	
    	//SessionLibrary.setFromScreen("From Page 01");
    	InfoBus.publish(ProjectLibrary.CONST_NAVIGATION_DATA_CALLBACK, newPage);    	
    end
    
     
end

Source code for Page 1

 

Page 2

Presented below is a screen shot for page 2. The source code for this page follows.

Page 2


 

Depending upon the version of the IDE you are using, (the open source version of EGL using Eclipse or IBM’s RDi with RDB) you will need to delete the appropriate set of imports. Both sets have been provided for convenience. You just need to decide which set needs to be deleted. No other modifications are required.

package com.mig.testnav.client;

// RUI Widget

//************************************************
//*  Imports for Open Source Verion of EGL
//************************************************
import org.eclipse.edt.rui.infobus.infobus;
import org.eclipse.edt.rui.widgets.Box;
import org.eclipse.edt.rui.widgets.Div;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.GridLayoutData;
import org.eclipse.edt.rui.widgets.GridLayoutLib;
import org.eclipse.edt.rui.widgets.Image;
import org.eclipse.edt.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;



//************************************************
//*  Imports for RBD plug-in for RDi 
//************************************************
import com.ibm.egl.rui.infobus.infobus;
import com.ibm.egl.rui.widgets.Div;
import com.ibm.egl.rui.widgets.GridLayout;
import com.ibm.egl.rui.widgets.GridLayoutData;
import com.ibm.egl.rui.widgets.GridLayoutLib;
import com.ibm.egl.rui.widgets.Image;
import com.ibm.egl.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;


//
//

handler Page02 type RUIWidget{targetWidget = ui, onConstructionFunction = start, cssFile = "css/TestNavProject.css", @VEWidget{category = "Custom"}}



    ui GridLayout{columns = 2, rows = 5, cellPadding = 4, children = [ BodyPane, ControlPane, MenuBar, GridLayout],
    	width = "1400",
    	position = "relative",
    	x = 20,
    	y = 10,
    	borderColor = "Black",
    	borderWidth = 0,
    	borderStyle = "solid" };
    GridLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 1, columns = 2,
    	children = [ Image, GridLayout1],
    	borderColor = "LightGrey",
    	borderStyle = "solid",
    	borderWidth = 1,
    	width = "1350" , backgroundColor = "RGB(40,95,175)"};
    MigDepartmentName TextLabel{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "Department Name",
    	fontSize = "26",
    	fontWeight = "bold",
    	color = "White" };
    MigApplicationName TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 1 }, text = "The Application Name",
    	fontSize = "18",
    	color = "White" };
    GridLayout1 GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 2, columns = 3,
    	children = [ MigApplicationName, MigDepartmentName] };
    Image Image{ layoutData = new GridLayoutData{ row = 1, column = 2,
    	horizontalAlignment = GridLayoutLib.ALIGN_RIGHT },
    	src = "MigLogo00.png"};
    MenuBar GridLayout{ layoutData = new GridLayoutData{ row = 2, column = 1,
    	cellPadding = 0 }, cellPadding = 4, rows = 1, columns = 3,
    	backgroundColor = "RGB(245,245,245)",
    	width = "1350",
    	children = [ InnerMenuLayout ],
    	padding = 0,
    	margin = 0,
    	height = "40" 
    	  };
    HelpMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 4 }, text = "Help", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		} 
	],
    	height = "22"};
    FileMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "File", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    EditMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 2 }, text = "Edit", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    InnerMenuLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1,
    	verticalAlignment = GridLayoutLib.VALIGN_MIDDLE,
    	horizontalAlignment = GridLayoutLib.ALIGN_LEFT }, cellPadding = 4, rows = 1, columns = 4,
    	children = [ HelpMenu, EditMenu, FileMenu, gotoMenu],
    	height = "32" };
    ControlPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 3, column = 1 }, title = "Control Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ ControlPaneGridLayout ]
    } ] };
    ControlPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3,
    	children = [ TextLabel ] };
    BodyPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 4, column = 1 }, title = "Main Data Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ BodyPaneGridLayout ]
    } ] };
    BodyPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3 };

    gotoMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 3 }, text = "Go to", children = [
		new DojoMenuItem {
			text = "Back", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onBack
		},
		new DojoMenuItem {
			text = "Page1", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage1
		}, 
		new DojoMenuItem {
			text = "Page3", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage3
		},		
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	]};
    TextLabel TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 2 }, text="TextLabel" };
	
    function start()
    	
    	//Register a callback function to process communication requests made through the InfoBus.
        Infobus.subscribe(ProjectLibrary.CONST_SESSION_DATA, SessionDataInfoBusCallBack);   	
        
        //Set Page Titles as required      	
    	MigDepartmentName.text = "Information Technology";
       	MigApplicationName.text = "Application Name - Page 02";
       	ControlPane.title = "Control Pane Title";
       	BodyPane.title = "Body Pane Title";
       	
       	//Startup Processing to get Runtime Environment and to read properties from XML file.
       	
       	//Get the screen name from which we came.
       	this.TextLabel.text = SessionLibrary.getFromScreen();
    end
    
 
	function SessionDataInfoBusCallBack(event string in, data any in)
		this.TextLabel.text = "Navigation occurred from " + SessionLibrary.getFromScreen();
	end   
    
    function onBack(e Event in)
    	toPage(-1); 
    end
    
     
    function onPage1(e Event in)
    	toPage(1); 
    end   
    function onPage3(e Event in)
    	toPage(3); 
    end
    
    
	//**********************************************************************
	// This function navigates to the requested screen. If the page's design
	// requires certain data elements to be passed to the destination page
	// place the elements into the Session Library established for this purpose 
	// before publishing the navigation request.
	//    
    function toPage(newPage int in)
    	
    	//Set this page as the page from which and to which we are navigating
    	SessionLibrary.setFromScreen("Page02");
    	SessionLibrary.setToScreen("Page0"+newPage);
    	 
     	//SessionLibrary.setFromScreen("From Page 02");
		InfoBus.publish(ProjectLibrary.CONST_NAVIGATION_DATA_CALLBACK, newPage);    	
    end

    
end

Source code for Page 2

 

Page 3

Presented below is a screen shot for page 3. The source code for this page follows.

Page 3


 

Depending upon the version of the IDE you are using, (the open source version of EGL using Eclipse or IBM’s RDi with RDB) you will need to delete the appropriate set of imports. Both sets have been provided for convenience. You just need to decide which set needs to be deleted. No other modifications are required.

package com.mig.testnav.client;

// RUI Widget

//************************************************
//*  Imports for Open Source Verion of EGL
//************************************************
import org.eclipse.edt.rui.infobus.infobus;
import org.eclipse.edt.rui.widgets.Box;
import org.eclipse.edt.rui.widgets.Div;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.GridLayoutData;
import org.eclipse.edt.rui.widgets.GridLayoutLib;
import org.eclipse.edt.rui.widgets.Image;
import org.eclipse.edt.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;

 
//************************************************
//*  Imports for RBD plug-in for RDi 
//************************************************
import com.ibm.egl.rui.infobus.infobus;
import com.ibm.egl.rui.widgets.Div;
import com.ibm.egl.rui.widgets.GridLayout;
import com.ibm.egl.rui.widgets.GridLayoutData;
import com.ibm.egl.rui.widgets.GridLayoutLib;
import com.ibm.egl.rui.widgets.Image;
import com.ibm.egl.rui.widgets.TextLabel;
import com.mig.testnav.libraries.ProjectLibrary;
import com.mig.testnav.libraries.SessionLibrary;
import dojo.widgets.DojoMenu;
import dojo.widgets.DojoMenuItem;
import dojo.widgets.DojoTitlePane;

//
//

handler Page03 type RUIWidget{targetWidget = ui, onConstructionFunction = start, cssFile = "css/TestNavProject.css", @VEWidget{category = "Custom"}}



    ui GridLayout{columns = 2, rows = 5, cellPadding = 4, children = [ BodyPane, ControlPane, MenuBar, GridLayout],
    	width = "1400",
    	position = "relative",
    	x = 20,
    	y = 10,
    	borderColor = "Black",
    	borderWidth = 0,
    	borderStyle = "solid" };
    GridLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 1, columns = 2,
    	children = [ Image, GridLayout1],
    	borderColor = "LightGrey",
    	borderStyle = "solid",
    	borderWidth = 1,
    	width = "1350",  backgroundColor = "DarkCyan" };
    MigDepartmentName TextLabel{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "Department Name",
    	fontSize = "26",
    	fontWeight = "bold",
    	color = "White" };
    MigApplicationName TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 1 }, text = "The Application Name",
    	fontSize = "18",
    	color = "White" };
    GridLayout1 GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1 }, cellPadding = 4, rows = 2, columns = 3,
    	children = [ MigApplicationName, MigDepartmentName] };
    Image Image{ layoutData = new GridLayoutData{ row = 1, column = 2,
    	horizontalAlignment = GridLayoutLib.ALIGN_RIGHT },
    	src = "MigLogo00.png"};
    MenuBar GridLayout{ layoutData = new GridLayoutData{ row = 2, column = 1,
    	cellPadding = 0 }, cellPadding = 4, rows = 1, columns = 3,
    	backgroundColor = "RGB(245,245,245)",
    	width = "1350",
    	children = [ InnerMenuLayout ],
    	padding = 0,
    	margin = 0,
    	height = "40" 
    	  };
    HelpMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 4 }, text = "Help", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    FileMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "File", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    EditMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 2 }, text = "Edit", children = [
		new DojoMenuItem {
			text = "Item 1, please set onClick", iconClass = "dijitEditorIcon dijitEditorIconCut"
		},
		new DojoMenuItem {
			text = "Item 2, please set iconClass", iconClass = "dijitEditorIcon dijitEditorIconCopy"
		},
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	],
    	height = "22"};
    InnerMenuLayout GridLayout{ layoutData = new GridLayoutData{ row = 1, column = 1,
    	verticalAlignment = GridLayoutLib.VALIGN_MIDDLE,
    	horizontalAlignment = GridLayoutLib.ALIGN_LEFT }, cellPadding = 4, rows = 1, columns = 4,
    	children = [ HelpMenu, EditMenu, FileMenu, gotoMenu],
    	height = "32" };
    ControlPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 3, column = 1 }, title = "Control Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ ControlPaneGridLayout ]
    } ] };
    ControlPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3,
    	children = [ TextLabel ] };
    BodyPane DojoTitlePane{ layoutData = new GridLayoutData{ row = 4, column = 1 }, title = "Main Data Pane", isOpen=true, duration=1000, width = "1350", children = [ new Div {
    	children = [ BodyPaneGridLayout ]
    } ] };
    BodyPaneGridLayout GridLayout{ cellPadding = 4, rows = 3, columns = 3 };

    gotoMenu DojoMenu{ layoutData = new GridLayoutData{ row = 1, column = 3 }, text = "Go to", children = [
		new DojoMenuItem {
			text = "Back", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onBack
		},
		new DojoMenuItem {
			text = "Page1", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage1
		},
		new DojoMenuItem {
			text = "Page2", iconClass = "dijitEditorIcon dijitEditorIconCut", onClick ::= onPage2
		}, 		
		new DojoMenuItem {
			text = "The next item is a separator"
		},
		new DojoMenuItem { },
		new DojoMenuItem {
			text = "Item 3, this one is disabled", disabled = true
		}
	]};
    TextLabel TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 2 }, text="TextLabel" };
	
    function start()
    	
    	//Register a callback function to process communication requests made through the InfoBus.
        Infobus.subscribe(ProjectLibrary.CONST_SESSION_DATA, SessionDataInfoBusCallBack);   	
        
        //Set Page Titles as required	
    	MigDepartmentName.text = "Information Technology";
       	MigApplicationName.text = "Application Name - Page 03";
       	ControlPane.title = "Control Pane Title";
       	BodyPane.title = "Body Pane Title";
       	
       	//Startup Processing to get Runtime Environment and to read properties from XML file.
       	
       	//Get the screen name from which we came.
       	this.TextLabel.text = SessionLibrary.getFromScreen();
       	    	
       	       	
    end

 
	function SessionDataInfoBusCallBack(event string in, data any in)
		this.TextLabel.text = "Navigation occurred from " + SessionLibrary.getFromScreen();
	end  
	
    function onBack(e Event in)
    	toPage(-1); 
    end
    
    function onPage1(e Event in)
    	toPage(1); 
    end

    function onPage2(e Event in)
    	toPage(2); 
    end  
 
 
 	//**********************************************************************
	// This function navigates to the requested screen. If the page's design
	// requires certain data elements to be passed to the destination page
	// place the elements into the Session Library established for this purpose 
	// before publishing the navigation request.
	//   
    function toPage(newPage int in)

    	//Set this page as the page from which and to which we are navigating
    	SessionLibrary.setFromScreen("Page03");
    	SessionLibrary.setToScreen("Page0"+newPage);
    	 
    	//SessionLibrary.setFromScreen("From Page 03");
		InfoBus.publish(ProjectLibrary.CONST_NAVIGATION_DATA_CALLBACK, newPage);    	
    end

        
end

Source code for Page 3

 

 

Credit

The source code for the page navigator was presented by Joe Pluta at the Eclipse Community Forum for the EDT project supporting the open source version of EGL and is the basis for the navigation scheme presented. It was augmented to demonstrate parameter passing between pages supported by employing EGL’s InfoBus.
 
 

Advertisements

Written by iseriesadmin

July 22, 2012 at 5:37 pm

One Response

Subscribe to comments with RSS.

  1. Since the original post, the addPage(newPage int in) function as been modified to call performLazyLoad(newPage). The performLazyLoad(newPage) function takes the page identified by newPage and instantiates it, thereby invoking the page’s start() function which initializes the page and incurs processing demand on the browser and server, the degree of which is dictated by the requirements of the page.

    Page initialization occurs only once for each page but this time, initialization only occurs when the page is requested by the user. Performing this so-called “lazy load” ensures that all pages of the web application are not initialized all at once as was the case of the original design

    Miscellaneous changes were made to support this new approach to page loading.

    iseriesadmin

    August 20, 2012 at 9:13 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: