Getting Started-JetNet


Lesson 13. Writing and Executing JPL

You can embed special processing in your application screens with Panther scripting language JPL. Because the JPL is saved with the screen or service component, it is accessible to the screen and its widgets.

In this lesson you learn how to:

This lesson shows how to use the JPL editor and describes its capabilities. The JPL procedures that you need are already written and stored in tutorial.lib. The following diagram illustrates the JPL procedures you will enter in this lesson.


  1. If necessary:

Write a procedure to access a distributor's orders

Write a JPL procedure that is called when a user chooses the New or Orders button on the dstslect.scr client screen. Both buttons call a JPL procedure that opens the Distributor Orders screen; each button passes to this procedure a different parameter (NEW or SELECT), which determines whether the screen is used to add a new distributor to the database, or view orders of an existing distributor.

Because the same procedure is called by two different screen objects, make the procedure available to both by attaching the JPL code to the screen's JPL Procedures property.

  1. Select the dstslect.scr client screen—click on an empty area in the screen to deselect all widgets.

    The Properties window displays screen properties.

  2. Under Focus, select the JPL Procedures property.

Panther opens the edit window for this screen's JPL:

The screen entry procedure enter_screen, produced by the screen wizard, is already attached to the screen's JPL. It calls the public command, which makes the code in the smwizard.jpl module available to all application screens. Leave the wizard JPL code unchanged and add new procedures to this module.

  1. Position the cursor a line or two below the return line of the enter_screen procedure. Insert the JPL procedure send_dst_data, which is stored in tutorial.lib:

More About the send_dst_data Procedure

The send_dst_data procedure is called when a user chooses either the New button or Orders button on the Select Distributor (dstslect.scr) screen. Each button supplies a different string argument to the procedure's cmd parameter, which controls how the procedure executes:

In both cases, the dstord.scr screen is opened through the call to sm_jwindow, which opens the Distributor Orders (dstord.scr) screen at the specified (+5,+5) position: five grid units right and five grid units down from the calling screen.

  1. Choose OK to save the procedure and close the JPL editor.
  2. Choose FileSave.
  3. (Optional) Close the dstslect.scr client screen.

More About the JPL Edit Window

You can write and edit JPL procedures within Panther's own edit window. This window offers access to JPL that is attached to a screen or stored in a library. You can also use any text editor that your system offers and that is specified in the application variable SMEDITOR—for example, Notepad on Windows or vi on UNIX. To access this editor:

When you exit the system editor, you resume in the JPL edit window, where you save your changes back to its source by choosing FileSave. You can also save library JPL modules to a new library member by choosing FileSave AsLibrary Member.

To save the current module's contents to a disk file, choose FileSave AsASCII Text File. Use this option in order to print JPL code from your system, or to send it in an email.

You can insert the contents of other JPL modules into the current one: choose EditInsert From Library to insert from a library module, or EditRead File to read from a disk file. Panther inserts the file's contents at the cursor's current position.

Write a procedure to receive data

The send_dst_data procedure sends data that is needed by the dstord.scr screen. Now you must write a screen entry procedure for dstord.scr that captures this data and uses it to determine the screen's behavior when it is opened by the dstslect.scr screen's New or Orders buttons.

  1. If the dstord.scr client screen and service component are not open, choose ViewLibrary TOC and open them from the client.lib and server.lib libraries, respectively.

  2. Select the dstord.scr client screen by clicking in an empty space within its borders, so no widgets are selected.
  3. Under Focus, choose JPL Procedures.

    The JPL edit window opens and displays screen wizard-generated comments and code. Replace this with code that is in tutorial.lib.

  4. Comment out the original enter_screen procedure by placing // at the beginning of each of the three lines.

  5. Position the cursor a line or two below the return line of the commented procedure.
  6. Choose EditInsert From Library.
  7. From the Open JPL Module dialog, select se_dst.jpl from tutorial.lib and insert the file by double-clicking on its name or choosing OK.

    The enter_screen procedure is read into the JPL edit window:

    proc enter_screen (screen_name, context)
    {
    public smwizard.jpl
    vars cmd

    if ((context & K_EXPOSE) || !(sm_is_bundle("")))
    {
    return 0
    }
    else
    {
    receive DATA cmd, distrib_id
    if (cmd == "NEW")
    {
    LDistrib_id->hidden=PV_YES
    distrib_id->hidden=PV_YES
    }
    call sm_tm_command(cmd)
    return 0
    }
    }

    The enter_screen procedure is invoked as the dstord.scr screen's entry procedure. First, the public command makes the wizard-generated JPL module smwizard.jpl available to the application. Next, the procedure determines whether a user can add a distributor record or edit an existing one:

  8. Choose Apply.
  9. Save the client screen (choose FileSave).

More About Sharing Information Across Screens

The send and receive commands let you transfer data between screens in an application. The send command specifies the data items to send and stores them in a buffer. When the target screen executes the corresponding receive command, the buffered data is retrieved.

Panther provides several ways for screens to access each other's data:

For more information about using send and receive commands and LDBs, CLICK HERE.

Generate a unique ID number

The JPL that you have so far written opens the dstord.scr screen when a user chooses the New button on the dstslect.scr (Select Distributor) screen, and opens dstord.scr (Distributor Orders) in insert mode. You can now write a JPL hook function for the dstord.scr service component that generates a unique distributor ID number. This hook function executes during transaction manager processing and supplements the default transaction model.

  1. Select the dstord.scr service component by clicking in an empty space within its borders (no widgets should be selected).
  2. Under Focus, choose JPL Procedures.
  3. Position the cursor after the enter_service procedure and before the comments to the select procedure.

  4. Choose EditInsert From Library.
  5. From the Open JPL Module dialog, select evnt_svr.jpl from tutorial.lib and choose OK.

    The tm_events_svr procedure is read into the JPL edit window:

    proc tm_events_svr (event_id)
    {
    if ((event_id == TM_INSERT_EXEC) && (distrib_id == ""))
    {
    DBMS ALIAS distrib_id
    DBMS QUERY SELECT MAX(distrib_id)+1 from distributors
    DBMS ALIAS // Clears prior aliasing
    }
    return TM_PROCEED
    }

    The tm_events_svr procedure checks whether an Insert transaction manager event occurred and the distributor ID is blank. If both conditions are true, the first DBMS ALIAS command ensures that the database value from the DBMS QUERY statement is written to the variable distrib_id.

    To generate a unique identification number, the second DBMS ALIAS statement specifies a SELECT to find the highest distributor ID in the distributors database table and increments that number by one. The service component returns that number to the client.

  6. Choose Apply.

More About DBMS QUERY and DBMS RUN Statements

In general, you'll use the transaction manager to automatically generate SQL statements. However, you can also write your own SQL. The Panther DBMS statements let you:

Refer to the Application Development Guide for more information.

Insert the ID in the Database

When a user adds the necessary distributor information and chooses the Save but ton on the Distributor Orders screen, the record must be inserted into the database. Here you modify the insert JPL procedure on the dstord.scr service component to explicitly add the distrib_id into the distributors database table.

  1. In the JPL edit window, scroll down to the insert procedure. Find the statement with the service_return command.
  2. Insert distrib_id within the braces of the service_return command:
    service_return success ({distrib_id})

  3. Save your changes: choose OK.
  4. Save the service component.

Invoke the hook function on the server

When you used the screen wizard to create the dstord.scr service component and client screen in Lesson 7, you specified two tables as their data source. When the wizard created these screens, it copied an invisible table view widget from each table's corresponding repository screen, distributors and orders. Each table view widget contains information about its repository screen's source table; it is created automatically when you import the table into the repository (Lesson 6).

Also, because dstord.scr is based on two tables, it also contains a link widget that specifies their join relationship. Like table widgets, link widgets are automatically created during the import process for each foreign key that is defined for a database table. When the screen wizard creates a screen with multiple table views, it copies from the repository the links that describe their relationship.

More About Table Views

Table views store the following types of database information:

Panther's transaction manager uses the information stored in table view and link widgets to determine the SQL statements to generate for each transaction command. The JetNet transaction model uses the service information to determine how to respond to service calls.

Also, table views let you easily modify the default transaction manager behavior.

At runtime, the transaction manager traverses all screen table views in the order that they are linked, and issues transaction commands to populate the master and detail sections accordingly. If a table view has a hook function attached to it, the transaction manager executes the function when it traverses that table view.

You attach a hook function to a table view through its Function property. In this case, you want to attach a hook function to the distributors table view. You can select a table widget and view its properties through either the Widget List or the DB Interactions window. In this instance, use the DB Interactions window to select the table view widget and access its Function property.

More About the Database Interactions Window

The Database Interactions window displays an interactive, graphical representation of a screen's table view widgets and link widgets. You can view the relationships between parent and child table views and the links that connect them. By selecting the toggle buttons representing these database objects you gain access to their properties.

  1. With focus on the dstord.scr service component, choose ViewDB Interactions.

    The DB Interactions window opens, displaying a graphical representation of table views and links on the dstord.scr service component.

More About Sequential and Server Links

Link widgets are not visible at runtime, but are visible in the editor so that you can access their properties.

There are two type of links—sequential and server:

  1. In the DB Interactions window, select the button that represents the distributors table view.

    The Properties window now displays table view properties.

  2. Under Transaction, set the Function property to tm_events_svr.
  3. Save all the open screens and service components (press F6).

Write a hook function for the client event

So far, the service component dstord.scr determines whether to generate an ID, and saves it to the database if a new one is indicated. But the corresponding client screen is unaware of the new ID. Because the distributor ID field and its corresponding label are hidden when a new record is added, you can programmatically unhide these fields and display the new ID by changing their Hidden property when the record is saved.
  1. Give focus to the JPL edit window of the dstord.scr client screen.
  2. Scroll to the end of the enter_screen screen entry procedure and press Enter twice to insert blank lines between procedures.
  3. Choose EditInsert From Library.
  4. From the Open JPL Module dialog, select evnt_clt.jpl in the tutorial.lib and choose OK.

    The tm_events_clt procedure is read into the JPL edit window:

    proc tm_events_clt (event_num)
    {
    if (event_num == TM_POST_SAVE)
    {
    distrib_id->hidden=PV_NO
    LDistrib_id->hidden=PV_NO
    }
    return TM_PROCEED
    }

    The tm_events_clt hook function checks whether a transaction manager Save command executed and, if so, unhides widgets distrib_id and LDistrib_id by changing their Hidden property to No.

  5. Save the procedure: choose OK.

More About Accessing Properties

All Panther objects and their properties can be accessed and most can be modified programmatically through JPL or C functions. You get or set properties for any screen or widget, or the application itself.

Refer to "Setting Properties Using the Property API" in Chapter 19 of Application Development Guide for information about JPL syntax for identifying screens and widgets, their properties, and property values. For a list of properties and their values, refer to Chapter 1, "Runtime Properties," in Quick Reference.

Invoke the hook function for the client event

Now that the function tm_event_clt has been added to the dstord.scr client screen, this hook function needs to be attached to the screen's table view widget via its Function property. At runtime, the transaction manager uses this function to display the results to the user, confirming visually that a new distributor was added to the database.

  1. Using the DB Interactions window, select the button representing the distributors table view on the dstord.scr client screen.

  2. Under Transaction, enter tm_events_clt in the Function property.

    If a Save command executes and the new distributor record is committed to the database, the new distributor ID displays.

  3. Close the DB Interactions window: use its system menu or choose ViewDB Interactions to toggle the display.
  4. Save the changes in the dstord.scr client screen.

Add a new database record

You now have a working application. You can now test whether the application flow functions as designed.

  1. Bring focus to the dstslect.scr client screen.
  2. Choose FileTest Mode or .

The Select Distributor screen opens.

  1. Choose .

All distributors in the vidsales database are listed.

  1. Choose .

The Distributor Orders screen opens with all data fields clear. The distributor ID fields are not visible.

  1. Enter Movie Time in the Distributor field.
  2. Choose .

    The distributor is added to the database and the ID is displayed in the Distrib_id field.

  3. Close the Distributor Orders screen (choose Close from the system menu).

    The Select Distributor screen regains focus. If you scroll down the list of distributors, notice that the new distributor is not listed. The next lesson shows how to enhance the screen entry procedure on this screen so users can see the latest data changes.

View orders

Select one of the distributors and then gain access to all of their orders.

  1. Select the row in the grid associated with Distrib_id 3 and choose the Orders button.

    The Distributor Orders screen opens and displays all orders for the selected distributor. The screen entry procedure (enter_screen) on the dstord.scr client screen receives the ID you selected (3) and the SELECT command, and calls sm_tm_command to select the specified database record.

  2. When done, return to the editor and save any unsaved screens.

What did you do?

You inserted several screen-level JPL procedures: a pair of procedures that send data from one screen and capture it to another; and two other JPL procedures that tell the transaction manager how to handle database transactions. You did this by writing these procedures:

What did you learn?

You learned: