Page tree
Skip to end of metadata
Go to start of metadata

This exercise guides you through creating a simple Hello World module that uses a JSON-based Rich Display File for the user interface. You will use the Visual Designer tool for Profound.js to create the UI.

Before you proceed, make sure the pjshello directory is created and configured as described here.

 

Create the UI

Start the Visual Designer for Profound.js by pointing your browser to a URL formatted as follows:

http://host:port/nodedesigner

Where host is the server you installed Profound.js on and port is the port number Profound.js is running on. If the installation is on your PC or Mac computer, use localhost.

Design the following interface:

Use these steps:

  1. Name the record format "helloworld"
  2. Drag the CSS Panel Blue widget (under Panels) onto the Visual Designer canvas
  3. Double-click the panel title and type "Hello World"
  4. Drag a CSS Button to the canvas, double-click the button and change the text to "Continue"; then set other button properties as desired
  5. Bind the button's response property to a Boolean Indicator field named "continue"
  6. Save your work to /profoundjs/modules/pjshello/example2.json (replace /profoundjs with your Profound.js installation directory)

 

Create Node.js server-side logic

Next, you will create the Profound.js module named example2.js:

/profoundjs/modules/pjshello/example2.js
function example2() {
  pjs.defineDisplay("display", "pjshello/example2.json");
  display.helloworld.execute();
}
 
exports.run = example2;

The code uses the pjs.defineDisplay() API to declare a JSON display file and create an object named "display". Every record format within the Rich Display becomes a property of the "display" object. The display.helloworld.execute() method shows the screen to the user and waits for the user to respond.

Note that qualifying the .json file with directory pjshello is optional. If the file is not qualified, the pathlist is used to search for the file.

 

Try the application using the initial module alias

Open your browser and navigate to the following URL:

http://host:port/example2

Where host is the Profound.js server host name or IP address and port is the Profound.js port number. You should see the following:


Try the application using PJSCALL on IBM i

Now, start a Genie session by navigating to the following URL:

http://puihost:port/profoundui/genie

Where puihost is the sever or host name for where Profound UI is installed and port is the port number used by Profound UI. Please note, this is not the same as the Profound.js server host name and port number.

Next, sign into the Genie session by using your IBM i user id and password. Then, edit your library list to include libraries PROFOUNDUI and PROFOUNDJS or their equivalents if you installed Profound UI and Profound.js into non-default libraries.

You are now ready to call your application. Use the following command and the Hello World application should appear within your interactive Genie session:

PJSCALL MODULE(example2) DIRECTORY(pjshello)

In order to use the PJSCALL command, you must have a valid license key that includes Genie and the Profound.js Connector.

Note, if you are testing and creating Profound.js modules on your PC, you can use the PJSMYIP command before running PJSCALL to point Genie to the Profound.js installation on your PC.

 

Try the application using a Proxy Program on IBM i

Using a Proxy Program object allows you to call your Node.js application with a standard IBM i CALL.

If the library PJSHELLO does not yet exist, create it using the following command:

CRTLIB LIB(PJSHELLO) TYPE(*TEST) TEXT('Profound.js Hello World Exercises')

Next, create the Proxy Program:

PJSCRTPRXY PGM(PJSHELLO/EXAMPLE2)

Finally, you can call your program from a Genie session using the following command and the Hello World application should appear within your interactive Genie session:

CALL PJSHELLO/EXAMPLE2

Before you can use Proxy Programs, you must have a valid license key that includes Genie and the Profound.js Connector.


Expand the application to use dynamic fields

In the Visual Designer, follow the steps:

  1. Add a Label
  2. Double-click the Label and change the text to say "Number:"
  3. Add a Dynamic Output Field to the canvas
  4. Double-click the Dynamic Output Field to bind its value and set the following Binding Dialog properties:
    1. Field Name = number
    2. Data Type = Decimal
    3. Length = 5
    4. Decimals = 0
  5. Drag another CSS Button to the canvas, double-click the button and change the text to "Exit"; then set other button properties as desired
  6. Bind the button's response property to a Boolean Indicator field named "exit"
  7. Save your work

Change your Node.js code as follows:

/profoundjs/modules/pjshello/example2.js
function example2() {
  pjs.defineDisplay("display", "pjshello/example2.json");
 
  while (!exit) {
    number++;
    display.helloworld.execute();
  }
}
 
exports.run = example2;

The code now uses the new fields number and exit. Note that you do not have to declare these fields in your Node.js code because they are already defined in the Rich Display File. Due to compatibility mode, Display File fields and record format names are referred to in lower case within your Node.js module regardless of the case used in the Visual Designer.

When you rerun the application, you will see some new functionality. The number increases every time you click Continue and the script ends when you click Exit.

 

Make your application call an interactive command on IBM i

Let's add another button to your screen and label it "Active Jobs". Bind the button's response property to a Boolean Indicator named "activejobs" and save your work.

Then, change your Node.js code as follows:

/profoundjs/modules/pjshello/example2.js
function example2() {
  pjs.defineDisplay("display", "pjshello/example2.json");
 
  while (!exit) {
    number++;
    display.helloworld.execute();
    if (activejobs) {
      pjs.runCommand("WRKACTJOB");
    }
  }
}
 
exports.run = example2;

Because we're calling an interactive command, this functionality will only work when the module is called from an interactive Genie session, either using PJSCALL or a Proxy Program. When the Active Jobs button is clicked you should see a screen like this:

You can interact with the screen as necessary. When you exit the Work with Active Jobs screen, you will return to your Node.js Hello World interface.

 

Displaying information in grids

Let’s add a grid of information to the screen.

  1. Drag a label to the canvas, and modify the label text to say “Select your favorite language:”
  2. Drag a subfile grid widget to the canvas
  3. Modify the grid’s “record format name” property to “grid”
  4. Remove the last column of the grid, so that you are only left with two columns
  5. Double-click to modify the grid headings to say “Select” and “Languages”, then resize the grid columns as you wish
  6. Add a Checkbox (no label) from Input Controls into the first column of the grid
  7. Double-click to bind the checkbox value property; type “selected” for the field name and 1 for the field length
  8. Add a Dynamic Output Field to the second column
  9. Double-click to bind the output field; type “language” for the field name and 30 for the field length

Your screen should look as follows:

Now, let’s add logic to the code to load the grid. Your Node.js module will look as follows when you are done:

/profoundjs/modules/pjshello/example2.js
function example2() {
  pjs.defineDisplay("display", "pjshello/example2.json");
  
  while (!exit) {
 
    // Clear and load the grid
    var data = [ "JavaScript", "RPG", "CL", "C++", "Java", "Python", "SQL" ];
    display.grid.clear();
    for (var i = 0; i < data.length; i++) {
      selected = "0";
      language = data[i];
      display.grid.write();
    }

    number++;
    display.helloworld.execute();
 
    if (activejobs) {
      pjs.runCommand("WRKACTJOB");
    }
  }
}
 
exports.run = example2;

The output will look as follows:

 

Processing input from the grid

Next, add elements to the screen to show selected records:

  1. Drag a label to the canvas, and modify the label text to say “Your selection:”
  2. Add another Dynamic Output Field to the screen
  3. Double-click to bind the output field; type “selection” for the field name and 500 for the field length

Then, modify the code to process selected records and populate the "selection" field you created above. The end result should look as follows:

/profoundjs/modules/pjshello/example2.js
function example2() {
  pjs.defineDisplay("display", "pjshello/example2.json");
  
  while (!exit) {
 
    // Clear and load the grid
    var data = [ 
      "JavaScript", 
      "RPG",
       "CL",
       "C++",
       "Java",
       "Python",
       "SQL"
    ];
    display.grid.clear();
    for (var i = 0; i < data.length; i++) {
      selected = "0";
      language = data[i];
      display.grid.write();
    }
 
    number++;
    display.helloworld.execute();
 
    // Retrieve selected records
    selection = "";
    display.grid.readChanged();
    while (!display.eof()) {      
      if (selected == "1") selection = selection.trim() + " " + language;
      display.grid.readChanged();
    }
 
    if (activejobs) {
      pjs.runCommand("WRKACTJOB");
    }
  }
}
 
exports.run = example2;

At runtime, after you select some records and click the Continue button, you should see output that looks like this:

 

Working with grid records in bulk

So far, we have worked with grid records one at a time. In the code above, each record is written and read individually. Using the various Grid API, it is also possible to work with records in bulk. The following accomplishes the same task as above, but with less lines of code:

function example2() {
  pjs.defineDisplay("display", "pjshello/example2.js");
  
  while (!exit) {
 
    // Clear and load the grid
    var data = [ 
      { language: "JavaScript", selected: "0" },
      { language: "RPG", selected: "0" },
      { language: "CL", selected: "0" },
      { language: "C++", selected: "0" },
      { language: "Java", selected: "0" },
      { language: "Python", selected: "0" },
      { language: "SQL", selected: "0" }
    ];
    display.grid.replaceRecords(data);
 
    number++;
    display.helloworld.execute();
 
    // Retrieve selected records
    selection = "";
    display.grid.forEach(function(record) {
      if (record.selected == "1") selection = selection.trim() + " " + record.language;
    });
 
    if (activejobs) {
      pjs.runCommand("WRKACTJOB");
    }
  }
}
 
exports.run = example2;
  • No labels