Create browse rows
- Last Updated: April 11, 2024
- 4 minute read
- OpenEdge
- Version 12.8
- Documentation
In an updateable browser, you might want to allow the user to add new records to the underlying temp-table or database table. Programmatically, this requires three separate steps:
- Create a blank line in the browse viewport with the
INSERT-ROW()method and populate it with new data.INSERT-ROWtakes a single optional argument, which is the string“BEFORE”or“AFTER”. This argument tells the AVM whether to insert the new row before or after the currently selected row in the browse. The default is“BEFORE”. You can use theINSERT-ROW()browse method in an empty browse. It places a new row at the top of the viewport. - Use the
CREATEstatement andASSIGNstatement to update the database or the underlying temp-table. - Add a reference to the result list with the
CREATE-RESULT-LIST-ENTRY()method. This is the list of record identifiers that the AVM uses to keep track of the set of rows in the query. This step is necessary only if you do not plan to reopen the query after the update, because reopening the query completely refreshes the list. However, this method makes reopening the query unnecessary for most applications.
All three steps are required to create the record and keep the database, query, and browse in sync. Also, there are several possible side effects to allowing the user to add a record through an updateable browse. They include placing new records out of order and adding records that do not match the query. To eliminate these side effects, you can reopen the query after each new record is added.
- In the Definitions section of the
h-CustOrderWin5.w procedure, beneath the browse defined
for OlineBrowse, define a handle variable called
hBrowse. You use this variable to hold the handle of the OrderLine browse because it is needed in several places. - Define a new buffer for the
OrderLinetemp-table calledttOline2. You use this buffer to hold onto the values in the current temp-table record as you create a new record, and to copy some of the values from the old record to the new one. - Assign the
OlineBrowsehandle to the newhBrowsevariable:DEFINE VARIABLE hBrowse AS HANDLE NO-UNDO. DEFINE BUFFER ttOline2 FOR ttOline. hBrowse = BROWSE OlineBrowse:HANDLE. - Drop a new button onto the window where it will not be overwritten by the OrderLine browse when it is displayed.
- Name the new button btnNew and give it a label of New OrderLine.
- Define a
CHOOSEtrigger for the button:DO: IF hBrowse:NUM-SELECTED-ROWS = 0 THEN DO: APPLY "END" TO hBrowse. hBrowse:SELECT-FOCUSED-ROW(). END. hBrowse:INSERT-ROW("AFTER"). END.This trigger code uses the handle of the OlineBrowse that you just assigned up in the Definitions section and inserts a new row in the browse after the currently selected row. First, it checks to make sure that there is a selected row using the browse’s
NUM-SELECTED-ROWSattribute. If the value of this attribute is zero, then the user has not selected any row. In this case, the trigger positions to the end of the browse by applying theENDevent to it and then selects that row using theSELECT-FOCUSED-ROWmethod. - Back in the procedure’s Definitions section, add this
ROW-LEAVEtrigger block for the OlineBrowse following the statement that assigns its handle tohBrowse:ON "ROW-LEAVE" OF BROWSE OlineBrowse DO: IF hBrowse:NEW-ROW THEN DO: FIND LAST ttOline2. CREATE ttOline. BUFFER-COPY ttOline2 TO ttOline ASSIGN ttOline.LineNum = ttOline2.LineNum + 1. ASSIGN INPUT BROWSE OlineBrowse ttOline.Qty ttOline.Price ttOline.Discount. DISPLAY ttOline.OrderNum ttOline.LineNum ttOline.ItemNum ttOline.ItemName WITH BROWSE OlineBrowse. hBrowse:CREATE-RESULT-LIST-ENTRY(). END. END.This code first checks the
NEW-ROWattribute of the browse to see if the row the user left is one newly created by the New OrderLine button.Because you are not prepared to do a full-fledged database update from the browse yet, the example simply creates a new row in the temp-table. To simplify the example, you start by copying the fields from the previous record into the new one. To do this, you
FINDtheLASTrecord in the temp-table using the second bufferttOline2. This gives you the highest LineNum value so that you can increment it for the new record. Note that this means that other initial field values are also assigned from the last record regardless of where in the viewport the user inserted the new record.You create a new temp-table record and
BUFFER-COPYthe last record into the new one, incrementing the LineNum field to give it a distinct value. This is important because the temp-table has the same unique index on the OrderNum and LineNum fields as the underlying OrderLine table in the database, so changing the LineNum has to happen in theBUFFER-COPYstatement to avoid a unique index violation.Next, the code assigns values to those columns that are enabled for input. The
INPUTkeyword on theASSIGNstatement tells the AVM to take the values from the screen buffer for each column. Then the new values are displayed in the browse.Finally, you create a result list entry for the new record. If you did not create a result list entry, the row would be lost if you were to scroll it out of the browse’s viewport. Reopening the query would also rebuild the result list, and also assure that all rows are in the proper order, so you can use either technique for getting the browse and the query back in sync.
- Run the window. Now you can add a record to the
OrderLine browse:
Once again, you learn how to get new records into the database in Update Your Database and Write Triggers.