Paged List Box Event Handling

The largest and most demanding issue regarding paged list boxes is the additional required event handling. Whenever a paged list box needs more data, it generates an event. The program must detect these events and respond in a way that will update the box's contents appropriately. There are several such events. They are described in detail in Events Reference. In brief, they are:

NTF-PL-NEXT Indicates the user wants to scroll the list box one record in the downward direction.
NTF-PL-PREV Indicates the user wants to scroll the list box one record in the upward direction.
NTF-PL-NEXTPAGE Indicates the user wants to scroll the list box one page in the downward direction.
NTF-PL-PREVPAGE Indicates the user wants to scroll the list box one page in the upward direction.
NTF-PL-FIRST Indicates the user wants to scroll to the top of the list.
NTF-PL-LAST Indicates the user wants to scroll to the bottom of the list.
NTF-PL-SEARCH Indicates the user wants to scroll to the page that contains the text he or she has entered.
NTF-PL-NEXT-WHEEL Indicates the user wants to use a wheelmouse to scroll the list box in the downward direction.
NTF-PL-PREV-WHEEL Indicates the user wants to use a wheelmouse to scroll the list box in the upward direction.

In each case, the program should locate the appropriate records and add them to the box. After adding the records, the program re-ACCEPTs the box to continue processing. Alternatively (and preferably), the program can use an EXCEPTION PROCEDURE to handle the events, thus never leaving the ACCEPT.

The program needs to track where it is in the overall list of items so that it can respond sensibly to the NEXT and PREVIOUS requests. Usually, the list of items consists of records contained in an indexed data file, and the ordering of those records is based on one of the file's keys. In this case, you can track the current location in the list by using the file's current record position. In this way you need only to remember if the last record you read from the file was placed at the beginning or end of the list box. If the record was placed at the beginning, then a single READ PREVIOUS will give you the previous record for the list. If the record was placed at the end, then a READ NEXT will give you the next record for the list. If you must get the next item from the opposite end of the list from your current position, then reading a page worth of records in the appropriate direction will get you to the proper record. The examples that follow explore this scheme in more detail.

Let's begin with a simple example. Suppose you are reading from an indexed file to get records for your list box. Also suppose that you always ensure that the last record you read from the file was the one at the end of the current page. In this situation, the following code fragment illustrates how you might handle the NTF-PL-NEXT event. This code builds on the code shown in the earlier example on constructing a paged list box.

list-1-handler.
   if key-status = w-event
      evaluate event-type
        when ntf-pl-next
          read keywords-file next record
             at end
                continue
             not at end  
                modify list-1, 
                       item-to-add = keywords-word 
          end-read
      end-evaluate
   end-if.

In this example, you first determine if the exception that led you to this paragraph was an event. Then you evaluate the event type. In the case of an NTF-PL-NEXT event, you read the next record in the file and add it to the list box.

To this add the case of handling the NTF-PL-NEXTPAGE event. The code for this is very similar, except that you want to add a full page of records. Here is an augmented example that does that:

list-1-handler.
   if key-status = w-event
      evaluate event-type
         when ntf-pl-next
            perform add-next-record
         when ntf-pl-nextpage
            perform add-next-record 
                    lines-per-page times
      end-evaluate
   end-if.

add-next-record.
   if not keywords-at-end
      read keywords-file next record
         at end      set keywords-at-end to true
         not at end  modify list-1, 
                     item-to-add = keywords-word
      end-read
   end-if.

A problem with this approach is that you have to do a lot more work to implement NTF-PL-PREV and NTF-PL-PREVPAGE. Because the file's current position is at the end of the list, you have to read backward through the entire page to get to the records you want. Then, when you are done adding records, you have to read forward through the page to maintain the program's assumptions. A more efficient technique keeps track of which side of the list you have last read from, and adjusts the position accordingly. This technique is shown in the full example included in Paged List Box Example, or in pagebox.cbl sample program.

Before laying out the full paged list-box example, consider how you might handle the NTF-PL-SEARCH event. This event is unusual in that you have to reposition the file arbitrarily. To get the search text that the user entered, you must first INQUIRE on the list box's SEARCH-TEXT property. That information is then used to do the positioning. Typical code might look like:

list-1-handler.
   if key-status = w-event
     evaluate event-type
       when ntf-pl-next
          perform add-next-record
       when ntf-pl-nextpage
          perform add-next-record
                  lines-per-page times
       when ntf-pl-search
          inquire list-1,
                  search-text in keywords-word
          start keywords-file,
                key not less than keywords-word
            invalid key
               perform search-failure-handling
            not invalid key
               perform add-next-record 
                       lines-per-page times
          end-start
     end-evaluate
   end-if.

The full example that follows explores the issue of handling a failed search.