Build the user interface for the new ProDataSet
- Last Updated: March 30, 2020
- 3 minute read
- OpenEdge
- Version 12.2
- Documentation
Now build a user interface for the new ProDataSet.
To build the user interface:
-
Create a new window procedure in the AppBuilder.
Name it
CodeWindow.w. - Make the window 10 rows by 130 columns.
-
Name the default frame
CodeFrameand the windowCodeWin. -
Use the AppBuilder's temp-table utility to define a temp-table
ttState LIKEtheStatedatabase table. -
Drop a browse called
StateBrowseonto the design window and attach it thettStatetable and its three fields.Your window should look roughly like this when you place the
StateBrowseto leave room for other objects. For example:
-
Add a statement to the Main
Block to run a procedure where all the code will go to startup the window.
For example:
MAIN-BLOCK: DO ON ERROR UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK: RUN enable_UI. RUN startupCodeWindow. IF NOT THIS-PROCEDURE:PERSISTENT THEN WAIT-FOR CLOSE OF THIS-PROCEDURE. END. -
Add a line to the
CLOSEtrigger in the Main Block for a procedure to shut down the window support code. For example:ON CLOSE OF THIS-PROCEDURE DO: RUN shutdownCodeWindow. RUN disable_UI. END. -
Add these variables to the Definitions section:
DEFINE VARIABLE hCodeSupport AS HANDLE NO-UNDO. DEFINE VARIABLE hCodeSet AS HANDLE NO-UNDO. DEFINE VARIABLE hRepBrowse AS HANDLE NO-UNDO. DEFINE VARIABLE hRepQuery AS HANDLE NO-UNDO. DEFINE VARIABLE hStateQuery AS HANDLE NO-UNDO. -
Create the internal procedure
startupCodeWindow. This starts theCodeSupportprocedure and then asks it for a ProDataSet with just thettSalesRepandttStatetables in it, as shown:/*--------------------------------------------------------------------- Procedure: startupCodeWindow Purpose: Fetch needed code tables from server. Parameters: <none> ---------------------------------------------------------------------*/ RUN codeSupport.p PERSISTENT SET hCodeSupport. RUN fetchCodeTables IN hCodeSupport (INPUT "ttSalesRep,ttState", OUTPUT DATASET-HANDLE hCodeSet). -
Create a dynamic query for the
ttStatetable that comes back as part of the dynamic ProDataSet, attaches it to theStateBrowse, prepares it, and opens it. The variables you use in this procedure are the ones you added in the Definitions section:CREATE QUERY hStateQuery. hStateQuery:ADD-BUFFER(hCodeSet:GET-BUFFER-HANDLE("ttState")). StateBrowse:QUERY IN FRAME CodeFrame = hStateQuery. hStateQuery:QUERY-PREPARE("FOR EACH ttState"). hStateQuery:QUERY-OPEN().Again, you might ask why you need a new dynamic query for this table. After all, you just defined a static temp-table
ttStateand a static browseStateBrowseagainst that temp-table.Once again, the answer is that you are not really using that static temp-table. It only provides a definition to base the browse on. What comes back from
fetchCodeTablesis a separate dynamic temp-table that happens to have the same name and the same fields so that you can easily use it in place of the static temp-table you defined.You cannot simply open the static query and use it. For example:
/* Can't do this: OPEN QUERY StateBrowse FOR EACH ttState. */If you do, you will not see any data in the browse.
-
To reinforce how to do this properly, you can create
a dynamic query for the other table you are getting back,
ttSalesRep:CREATE QUERY hRepQuery. hRepQuery:ADD-BUFFER(hCodeSet:GET-BUFFER-HANDLE("ttSalesRep")).Be sure to add the right buffer to the query, which is the one for the temp-table that comes back as part of the dynamic ProDataSet
hCodeSet. If you had a local definition ofttSalesRep, its buffer would not do you any good for the same reason that your local definition ofttStatecannot be used.This dynamic browse uses the
ttSalesRepquery:CREATE BROWSE hRepBrowse ASSIGN QUERY = hRepQuery ROW-MARKERS = FALSE FRAME = FRAME CodeFrame:HANDLE HIDDEN = FALSE NO-VALIDATE = TRUE WIDTH = 74 HEIGHT = 5 ROW = 6 SEPARATORS = TRUE SENSITIVE = TRUE. hRepBrowse:ADD-COLUMNS-FROM("ttSalesRep"). -
Finally, the procedure needs to prepare and open the dynamic
query on
ttSalesRep:hRepQuery:QUERY-PREPARE("FOR EACH ttSalesRep"). hRepQuery:QUERY-OPEN(). -
Now, when you run the window, you see both the static browse
and the dynamic browse. Both are, in fact, using dynamic temp-tables
that came back as part of the dynamic ProDataSet
hCodeSet, as shown:
-
Define the internal procedure
shutdownCodeWindowto delete the supporting procedure instance:/*--------------------------------------------------------------------- Procedure: shutdownCodeWindow Purpose: Cleanup supporting procedure and any other objects when deleting the window. ---------------------------------------------------------------------*/ APPLY "CLOSE" TO hCodeSupport. END PROCEDURE.Rather than deleting it directly, applying the
CLOSEevent to it gives it a chance to clean up after itself. This is modeled on the standard code the AppBuilder generates to close a procedure by runningdisable_UI. -
To handle the
CLOSEevent in CodeSupport.p, add the following trigger to its main block so that it can delete the other persistent procedure CodeSource.p that manages the Data-Sources, and then delete itself:ON CLOSE OF THIS-PROCEDURE DO: DYNAMIC-FUNCTION("detachDataSet" IN hSourceProc, INPUT hCodeSet). DELETE PROCEDURE hSourceProc. DELETE PROCEDURE THIS-PROCEDURE. END.