File externalhostexample2.htm is designed to generically represent an external host and to demonstrates the basics of automated 5250 screen navigation. You should read the section Using Example 1 beforehand.

Summary of Example 2

By working through externalhostexample2.htm you should be able to see how to:

  • Make a 5250 session act like a subroutine or service.
  • Make a 5250 session navigate to a particular screen.

Setting Up Example 2

First, put a shortcut on your desktop that makes it easy to open example 2.

http://<axes>/ts/screens/<your project>/externalhostexample2.htm

where

  • <axes> is the IP address and port of your aXes server
  • <your project> is the name of your project folder.

Now open externalhostexample2.htm with NOTEPAD.

Modify it to work with your project. Right at the start you will find these lines:

/* Some basic details you may need to change */

var protocol = "http";
var host = document.location.host;
var projectfolder = "aexternalhosting";

Typically you only need to change the project folder variable to name your project folder.

Save your changes.

You also need to add a small amount of logic to your USERENV file so that scripts executing inside aXes can easily communicate with those executing outside Axes in the external host.

Using the aXes Project Home Page open your project and edit you USERENV object.

Add these new functions to the USERENV object definition (copy/paste them is easiest):

HOSTUSERAREA : function()
{
if (AXES.HOSTSESSION == null) return(null);
if (AXES.HOSTSESSION.USERAREA == null) return(null);
return(AXES.HOSTSESSION.USERAREA);
},

getAutoAction : function(forScreen)
{
var ua = this.HOSTUSERAREA();
if (ua == null) return("");
var aa = ua.AutomaticAction[forScreen];
if (aa == null) return("");
return(aa);
},

setAutoAction : function(forScreen,action)
{
var ua = this.HOSTUSERAREA();
if (ua == null) return;
ua.AutomaticAction[forScreen] = action;
},

Save your changes to update your project's USERENV.JS file.

Next you need add some logic to the aXes 5250 screen definitions so that they can automatically navigate between screens.

This is done by adding code to the screen's onArrive property …. JavaScript code that is executed whenever the screen arrives.

To do this, go to the screen in question, check that it is being correctly identified and then use the Edit Screen or Start Customizing this Screen button to edit the screen definition.

Click anywhere on the screen (except for a field) to see the screen level properties, then input the required onArrive script as shown in the table below

Screen Name

onArrive Script

DSPMSGS
if (USERENV.getAutoAction("DSPMSGS") == "ELIMINATE") SENDKEY("Enter");
MAIN
var USERAREA = USERENV.HOSTUSERAREA();
var autoaction = USERENV.getAutoAction("MAIN");
var CommandLine = FIELDS("CommandLine");
if (CommandLine != null)
{
switch ( autoaction )
{
case "SHOW_LIB":
CommandLine.setValue("DSPLIB " + USERAREA.Library);
USERENV.setAutoAction("DSPLIB","GET_OBJECT");
USERENV.setAutoAction("MAIN","SIGNOFF");
SENDKEY("Enter");
break;

case "SHOW_OUTQ":
CommandLine.setValue("WRKOUTQ " + USERAREA.Queue);
USERENV.setAutoAction("MAIN","SIGNOFF");
SENDKEY("Enter");
break;

case "SIGNOFF":
CommandLine.setValue("SIGNOFF");
USERENV.setAutoAction("MAIN","");
SENDKEY("Enter");
break;

default:
break;
}
}
DSPLIB
var autoaction = USERENV.getAutoAction("DSPLIB");

switch ( autoaction )
{
case "GET_OBJECT":
var o1 = FIELDS("Object_1"); var o2 = FIELDS("Object_2");
var o1v = "NOT AVAILABLE"; var o2v = "NOT AVAILABLE";
if (o1 != null) o1v = o1.getValue();
if (o2 != null) o2v = o2.getValue();
USERENV.HOSTUSERAREA().ReturnLibraryObjects(o1v,o2v);
SENDKEY("F12");
break;

default:
break;
}

Running Example 2

Use your desktop shortcut to open externalhostexample2.htm.

The resulting display should look like this:

Image

Again the blue area represents the external host, the white area the aXes 5250 session.

Display IBM i Library Button

Enter a valid user profile and password at the top of the web form.

This must be a user profile that causes the IBM i Main Menu to be displayed.

Enter a valid IBM library name, like QGPL.

Click the Run Example 1 – Display IBM i Library button.

If you have set everything up correctly, an aXes 5250 session should appear, and then you should see some 5250 screens being navigated and finally the logon screen should appear again.

On the top of the screen, two white lines should appear containing the name of the first two objects in the IBM i library, like this:

Image

What should happen is:

  • The 5250 session is created and automatically logged on
  • The command DSPLIB is automatically executed for the specified library
  • The object names are read from the 5250 DSPLIB screen and sent to the external host
  • The 5250 session is logged off again.
In effect the 5250 session acts like a subroutine or service to the external host.

Note: If you were designing a real 5250 service like this you would probably not log the session off and on again like this between requests - but introducing that feature would obscure the intent of this example.

Display IBM i Output Queue Button

Use your desktop shortcut to open externalhostexample2.htm again.

Enter a valid user profile and password at the top of the web form.

This must be a user profile that causes the IBM i Main Menu to be displayed.

Enter a valid IBM output queue, like QPRINT.

Click the Run Example 2 – Display IBM i Output Queue button.

If you have set everything up correctly, an aXes 5250 session should appear, and then you should see some 5250 screens being navigated and the IBM WRKOUTQ screen should appear;

Image

You should be able to perform actions on the spool files by using the options like 5=Display, etc. However, as soon as you exit this screen by F3=Exit or F12=Cancel you will be signed off and the 5250 session will end.

This example demonstrates taking some value from the external host (in this case a queue name) navigating some 5250 screens and displaying the result.

Once the displayed information is exited from the session is closed.

Automatically Logging On

The automatic logon is this example is performed by this logic in externalhostexample2.htm:

In function SetUp() a function is nominated to be notified about screen arrivals:

function Setup(trace)
{
if (my5250Session != null) Close();
var frame = document.getElementById("aXesIFrame");

my5250Session = new AXESHOST.HOSTSESSION(frame);
my5250Session.onFormArrive = myonFormArrive; /* Hook up for screen arrivals */
}

and the function looks like this:

function myonFormArrive()
{
var screenname = my5250Session.currentForm.symbolicName;

switch (screenname)
{
/* Log on automatically */

case "MainLogin":
MainLogin_Attempts++;
if (MainLogin_Attempts == 1)
{
var lusr = my5250Session.FIELDS("loginUser");
if (lusr) lusr.setValue(UserProfile.value);
var lpwd = my5250Session.FIELDS("loginPwd");
if (lpwd) lpwd.setValue(UserPassword.value);
my5250Session.SENDKEY("Enter");
}
break;
/* Do nothing */
default:
break;
}
}

This code is watching for the login form named MainLogin to arrive. When it does the user profile (a field named loginUser) and password (a field named loginPwd) are set from the external host's values you typed in. The enter key is then pressed.

Note: The variable MainLogin_Attempts is used to stop infinite looping if you provide a bad user profile or password - and to stop logging on again after logging off.

Automatically Navigating 5250 Screens

There are many techniques you can use to control automatic screen navigation.

The technique used here is neither especially recommended, nor specific to aXes.

It just a simple technique that is fairly easy to understand.

The USERENV object has a two user defined functions added earlier: getAutoAction : function(forScreen) … etc
setAutoAction : function(forScreen) … etc

In effect these functions allow any aXes 5250 screen script to do two things:

  • Check for the condition "Is there some automatic action I need to take?"
  • Setup the condition "I want you to take this automatic action" for upcoming screen(s).

If you look at the sequence of events when running the first example this simple navigation technique may become clearer:

You click the button and this significant code runs in externalhostexample2.htm:

function Setup(trace)
{
etc, etc
my5250Session.USERAREA.AutomaticAction["DSPMSGS"] = "ELIMINATE";

and

function Example(task)
{
Etc, etc

case "EXAMPLE1":
etc, etc
my5250Session.USERAREA.AutomaticAction["MAIN"] = "SHOW_LIB";

So at startup, the automatic actions table looks like this:

Screen Name

Requested Automatic Action

DSPMSGS ELIMINATE
MAIN SHOW_LIB

The session is opened and the user is automatically logged on (see preceding topic for hoe this happens).

Now the DSPMSGS screen may appear.

It onArrive script says this:

if (USERENV.getAutoAction("DSPMSGS") == "ELIMINATE") SENDKEY("Enter");

In effect it is saying "If there is an entry in the automatic actions table entry for me ("DSPMSGS") and it contains the request "ELIMINATE" then send the enter key.

In other words … DSPMSGS automatically eliminates itself whenever it is displayed (hence the action name ELIMINATE) by pressing enter.

Next the MAIN screen will appear.

It's onArrive script says this:

var USERAREA = USERENV.HOSTUSERAREA();
var autoaction = USERENV.getAutoAction("MAIN");
var CommandLine = FIELDS("CommandLine");
if (CommandLine != null)
{
switch ( autoaction )
{
case "SHOW_LIB":
CommandLine.setValue("DSPLIB " + USERAREA.Library);
USERENV.setAutoAction("DSPLIB","GET_OBJECT");
USERENV.setAutoAction("MAIN","SIGNOFF");
SENDKEY("Enter");
break;

case "SHOW_OUTQ":
CommandLine.setValue("WRKOUTQ " + USERAREA.Queue);
USERENV.setAutoAction("MAIN","SIGNOFF");
SENDKEY("Enter");
break;

case "SIGNOFF":
CommandLine.setValue("SIGNOFF");
USERENV.setAutoAction("MAIN","");
SENDKEY("Enter");
break;

default:
break;
}
}

The significant part is the switch operation.

MAIN can handle 3 different types of automatic requests – they are named SHOW_LIB, SHOW_OUTQ and SIGNOFF.

In this case the automatic actions table says "SHOW_LIB" so MAIN does this:

  • Builds DSPLIB XXXXXX command (where xxxxxx is the requested library name) and inputs to the commandLine field on the screen.
  • Sets the autoaction for the DSPLIB screen to be "GET_OBJECT".
  • Sets the autoaction for itself to be SIGNOFF.
  • Sends the enter key.

The autoaction table now looks like this:

Screen Name

Requested Automatic Action

DSPMSGS ELIMINATE
MAIN SIGNOFF
DSPLIB GET_OBJECT

Next the DSPLIB screen appears for the specified library.

It has this onArrive scripting:

var autoaction = USERENV.getAutoAction("DSPLIB");

switch ( autoaction )
{
case "GET_OBJECT":
var o1 = FIELDS("Object_1");
var o2 = FIELDS("Object_2");
var o1v = "NOT AVAILABLE";
var o2v = "NOT AVAILABLE";
if (o1 != null) o1v = o1.getValue();
if (o2 != null) o2v = o2.getValue();
USERENV.HOSTUSERAREA().ReturnLibraryObjects(o1v,o2v);
SENDKEY("F12");
break;

default:
break;
}

The autoaction table says "GET_OBJECT" so it extracts the name of the first two objects displayed on the 5250 screen (screen fields named Object_1 and Object_2).

It then sends their details back to the external host (see later section about this).

It then sends key F12 (Cancel).

This causes the screen MAIN to be redisplayed, and the automatic action table says this:

Screen Name

Requested Automatic Action

DSPMSGS ELIMINATE
MAIN SIGNOFF
DSPLIB GET_OBJECT

MAIN looks in the autaoction table and finds the request SIGNOFF - so it signs the 5250 session off by setting Commandline to "SIGNOFF" and sending the enter key.

The autoaction table is a very simple an extensible way to automatically script screen navigation. Once a small amount of infrastructure has been established in the USERENV object it can be used by many different screens fairly simply.

Of course more sophisticated and generic means of automatic screen navigation are also possible.

Passing Information into aXes 5250 screen scripts

In externalhostexample2.htm the HOSTSESSION class object (my5250Session) is extended by the addition of a USERAREA object.

You can see various code lines doing things like:

my5250Session.USERAREA.Library = LibraryName.value; my5250Session.USERAREA.Queue = QueueName.value;

In the various aXes screen's onArrive scripts you can see code like this:

var USERAREA = USERENV.HOSTUSERAREA();
CommandLine.setValue("DSPLIB " + USERAREA.Library);
CommandLine.setValue("WRKOUTQ " + USERAREA.Queue);

This is because my5250Session.USERAREA and USERENV.HOSTUSERAREA() both effectively refer to the same JavaScript object.

So in an external host you refer to mySession.USERAREA.xxxxxxxxxx.
In an aXes screen's script you refer to USERENV.HOSTUSERAREA().xxxxxxxxxx.
It is the same xxxxxxxxxx property that you are referring to in both cases.

The USERAREA provides an infinitely expandable place for passing information between external host scripts and aXes screen scripts.

When used in large applications you should consider further dividing up the USERAREA namespace (eg: USERAREA.HR.CurrentEmployee, USERAREA.ERP.CurrentOrder, etc).

Passing Information back to the External Host Scripts

The preceding point about also allows aXes screen scripts to call functions provided by the external host.

You can see this in these lines of script in the external host externalhostexample2.htm:

case "EXAMPLE1":
my5250Session.USERAREA.ReturnLibraryObjects = ReturnLibraryObjects;

and

function ReturnLibraryObjects(object1,object2)
{
Object1Result.innerText = "Object 1 in library " + my5250Session.USERAREA.Library + " was " + object1.toString();
Object2Result.innerText = "Object 2 in library " + my5250Session.USERAREA.Library + " was " + object2.toString();
}

And the calling of this external host function from the DSPLIB screen's onArrive script:

case "GET_OBJECT":
var o1 = FIELDS("Object_1"); var o2 = FIELDS("Object_2");
var o1v = "NOT AVAILABLE"; var o2v = "NOT AVAILABLE";
if (o1 != null) o1v = o1.getValue();
if (o2 != null) o2v = o2.getValue();
USERENV.HOSTUSERAREA().ReturnLibraryObjects(o1v,o2v);
SENDKEY("F12");
break;

Administrators

Legal Mentions

aXes is brought to you by:

LANSA

Serving the IBM i community for 30 years.