Data Entry State Handling
Data Entry State Handling
The following code is adapted from the program DoCst3 in the Example Application that ships with Zim. It is typical of older code found in Zim programs that handle data entry.
case
when $transmitkey in (“escape”, “F3”)
if SaveFormChanged = $true
DoChange ($true)
endif
break
when $transmitkey in (“F4”, “F5”)
if SaveFormChanged = $true
DoChange ($true)
let SaveFormChanged = $false
endif
if $transmitkey = “F4”
DoSelect ()
else
DoOrder (SaveFieldNum)
endif
when $transmitkey in (“PageUp”, “PageDown”, “Home”,
End”)% Next,Previous,First,Last
if SaveFormChanged = $true
DoChange ($true)
let SaveFormChanged = $false
endif
%% scroll in required direction
…
when $transmitkey = “F9”
if SaveFormChanged = $true
DoChange ($true)
let SaveFormChanged = $false
endif
BrwCusts ()
SetScroll ()
when $transmitkey = “F11” % Reset
if SaveFormChanged = $true|
DoChange ($true)
let SaveFormChanged = $false
endif
find 0 Customers -> cset
SetScroll ()
endcase
Note that the code “if SaveFormChanged … endif” is repeated; the reason is as follows:
- The current “modified status” of the window is being saved in the local variable SaveFormChanged. This variable keeps track of whether the data on the screen has been changed (and, therefore, is different from the current database contents).
- In each case above, the “if SaveFormChanged…” code is checking to see if the change data should be committed to the database before the requested action takes place. For example, pressing F9 is used in this application to switch the view from a single record view to a tabular (multi-record) view. Before switching views, the application checks to see if the screen data has been changed. If it has changed, then DoChange (not shown here) is called. The $true parameter indicates that DoChange should prompt the user to see if the changes should be saved or not.
USING FRAMEWORK DATA ENTRY STATE HANDLING
As the above example illustrates, the status of a data entry window is defined by
- modified status (has the screen been changed)
- view (single record, tabular, …)
- mode (adding new records, editing existing data, …)
Some actions require that any changes be committed first. In some cases, the user should be prompted first while there are other cases where the data should be committed unconditionally. The Framework pValidateAction program assists in tracking a windows status and can eliminate the need for much of the checking done in the above code. Here is the same code, rewritten to react to actions rather than $transmitkey and using pValidateAction.
%% pValidateAction handles all status checking.
let vlValidAction=$true vlNewState=”” vlNewView=””
pValidateAction (vlStatus, vlAction, \
vCustState.stWindowName, vCustState.stView, \
CustState.stState, vCustState.stModified, \
vlNewView, vlNewState, vlValidAction)
if (vlValidAction = $false)
return
endif
case
%% New “SAVE” action.
when vlAction = “SAVE”
DoChange ()
let vCustState.stModified = $false
when vlAction = “EXIT”
break
when vlAction = “SELECT”
DoSelect ()
when vlAction = “SORT”
DoOrder (SaveFieldNum)
when vlAction = “SCROLL”
% Next,Previous,First,Last|
%% scroll in required direction
…
%% No need to do status checking in each case.
when vlAction = “BROWSE”
BrwCusts ()
SetScroll ()
when vlAction = “RESET”
find 0 Customers -> cset
SetScroll ()
endcase
Notes:
- A structure, vCustState, is used to keep track of the status of this window. It contains the window name (stWindowName), if the screen has been modified (stModified that replaces SaveFormChanged), the mode or state (stState), and the view (stView).
- pValidateAction checks to see if the action is valid in the current state. It can also determine that, if the window has been modified, the user should be prompted. If the data must be saved, pValidateAction pushes the current action onto the message queue and returns SAVE in vlAction.
- A new SAVE case has been added that saves the data. Notice that the parameter to DoChange has been removed since any prompting is already handled by pValidateAction.
- None of the individual action cases need to be concerned about whether data must be saved, so the code is greatly simplified.