Getting Started-2-Tier


Lesson 9 . Writing and Executing JPL

You can embed special processing in your application screens with Panther's scripting language JPL. Because the JPL is saved with the screen, 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 tutorstd.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.

  3. 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 tutorstd.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 Apply to save the procedure.
  2. Choose FileSave to save the 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 Apply or OK. You can also save library JPL modules to a new library member by choosing Save As.

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 as 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 necessary, reopen the dstord.scr screen from client.lib.

  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 tutorstd.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 tutorstd.lib. Choose 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
    }
    }

More About the enter_screen Procedure

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:

  1. Save the procedure by choosing Apply.

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, refer to Chapter 25, "Moving Data Between Screens," in the Application Development Guide.

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 dstord.scr that generates a unique distributor ID number. This hook function executes during transaction manager processing and supplements the default transaction model.
  1. Position the cursor at the very end of the JPL file for the dstord.scr to start a new procedure.
  2. Choose EditInsert From Library.
  3. From the Open JPL Module dialog, select evnt_svr.jpl from tutorstd.lib and choose OK.

    The tm_events procedure is read into the JPL edit window:

    proc tm_events (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
    }
    else if (event_id == TM_POST_SAVE)
    {
    distrib_id->hidden=PV_NO
    LDistrib_id->hidden=PV_NO
    }
    return TM_PROCEED
    }

More About the tm_events Procedure

The tm_events 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 statement specifies a SELECT to find the highest distributor ID in the distributors database table and increments that number by one.

The hook function then 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.

  1. Choose OK to save the procedure and exit the JPL window.
  2. Choose FileSave to save the screen.

More About SQL DBMS 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 Chapter 28, "Writing SQL Statements," in Application Development Guide for more information

Invoke the hook function

When you used the screen wizard to create dstord.scr in Lesson 4, 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 entry's source table; it is created automatically when you import the table into the repository (Lesson 3).

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.

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 dstord.scr, choose ViewDB Interactions.

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

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 and choose OK.
  3. Save all the open screens (press F6).

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.

Refine the screen for GUI display

In Lesson 4, you created the screen and chose web-friendly output, which affects the appearance of the screen when it is called from another screen. To adjust the appearance of the screen for GUI:

  1. Bring focus to the dstord.scr screen. Click on an empty area in the screen to deselect all widgets. If the Properties window is not open, double-click on the screen or choose ViewProperties Window.
  2. In the Properties window, select the Display heading.
  3. Select the Border property.
  4. Click on the option menu to display its drop-down list, and select Yes. Press Enter or choose OK.
  5. Select the System Menu property and repeat Step 27.
  6. Select the Title Bar property and repeat Step 27.
  7. Save the dstord.scr screen (press F5).

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.

  3. Choose .

    All distributors in the vidsales database are listed.

  4. Choose .

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

  5. Enter Movie Time in the Distributor field.
  6. Choose .

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

  7. Close the Distributor Orders screen (choose Close from the system menu or press Escape).

    The Select Distributor screen regains focus. If you choose View and then scroll down the list of distributors, notice that the new distributor is now 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 all screens (FileSave All).

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 including these procedures:

What did you learn?

You learned: