Ask Reuben

Refreshing Tables

How can I refresh a Table without leaving the current dialog?

In legacy 4gl code, to refresh a Table you might have had some DISPLAY statements in a FOR loop.  In the last Ask-Reuben I demonstrated how you could use DISPLAY ARRAY with  BEFORE DISPLAY EXIT DISPLAY to redisplay the Table.  There was another scenario where legacy 4gl code was clunky in that to refresh a Table, this involved exiting the current dialog, repopulate the array, and then starting the dialog again.

What the developer was unaware of was that by using Multiple Dialog and UNBUFFERED, that Table could be updated from the current dialog.

By using UNBUFFERED, then changes to a program variable are reflected right away in the current dialog.  So if using Multiple Dialog and UNBUFFERED, changes to a Table can be made by simply updating the underling array variable based on values in the other parts of the dialog.   This includes using array methods that change multiple rows of an array such as clear, copyTo, sort.

Best illustrated by example, the code example below consists of a DIALOG statement that has the UNBUFFERED attribute and has two DISPLAY ARRAY blocks.  When the selected row on the left hand side array changes, the array on the right hand side is cleared and re-populated.  Note in the two screenshots, in the left hand side I have moved down one row, the values in the right hand side have changed to reflect the left hand side value.  At no point do I exit the dialog, I simply change the values of the right hand side array (including using the clear method to remove all rows before adding new rows).  The use of the UNBUFFERED attribute means that the rendering of the right hand side array changes immediately.

IMPORT util

DEFINE arrm DYNAMIC ARRAY OF RECORD
    master_id INTEGER,
    detail_count INTEGER
END RECORD
DEFINE arrd DYNAMIC ARRAY OF RECORD
    detail_id STRING
END RECORD

MAIN
    DEFINE i INTEGER
    CLOSE WINDOW SCREEN
    OPEN WINDOW w WITH FORM "askreuben194"

    -- Populate master
    FOR i = 1 TO 99
        LET arrm[i].master_id = i
        LET arrm[i].detail_count = util.Math.rand(40) + 5
    END FOR

    DIALOG ATTRIBUTES(UNBUFFERED)
        DISPLAY ARRAY arrm TO scrm.*
            BEFORE ROW
                -- Update right hand side with detail for current row
                -- No need to exit dialog as UNBUFFERED will cause display to be updated
                CALL refresh_detail(DIALOG.getCurrentRow("scrm"))
        END DISPLAY
        DISPLAY ARRAY arrd TO scrd.*
        END DISPLAY
        ON ACTION close
            EXIT DIALOG
    END DIALOG
END MAIN

FUNCTION refresh_detail(row INTEGER)
    DEFINE i INTEGER
    CALL arrd.clear()
    FOR i = 1 TO arrm[row].detail_count
        LET arrd[i].detail_id = SFMT("%1-%2", row USING "<&", i USING "&&")
    END FOR
END FUNCTION

#! askreuben194.per

LAYOUT
HBOX
TABLE
{
[f01      ]
}
END
TABLE
{
[g01      ]
}
END
END
END
ATTRIBUTES
EDIT f01 = formonly.master_id, TITLE="Master";
PHANTOM formonly.detail_count;
EDIT g01 = formonly.detail_id, TITLE="Detail";

INSTRUCTIONS
SCREEN RECORD scrm(master_id, detail_count)
SCREEN RECORD scrd(detail_id)