Dynamic ISPF Panels – Getting the Input Data
In the previous article I looked at the general process of building the ISPF screen dynamically, including the creation of input fields. Now it’s time to get the users input from those fields into the application. Again I am using REXX as the driving code.
In a typical static ISPF panel, fields are referred are named and the data in them can be set and retrieved by variable name within the application.
With a dynamic ISPF panel there are no variables that you can refer to, only the variable being used to refer to the data string that is the panel definition. when the user enters some data into the input fields on your screen and presses enter, ISPF rebuilds the entire data string and updates the dynamic screen variable, complete with text fields you output, attributes and input data from the user. You have to manually extract the input data from that string and place the data into your own variables.
The process of extracting the input data from the screen variable is a lot simpler if you only ever use one attribute character to mark the start of an input field and one attribute character to mark the end of an input field.
In the previous article I had the following hexadecimal attribute definitions in my skeleton panel:
01 TYPE(DATAOUT) INTENS(LOW) 02 TYPE(DATAOUT) INTENS(HIGH) 03 TYPE(DATAIN) INTENS(LOW) COLOR(GREEN) PAD(_) 04 TYPE(DATAOUT) INTENS(LOW) COLOR(RED) 05 TYPE(DATAOUT) INTENS(LOW) COLOR(YELLOW)
And I built each input line using the following code:
dol='01'x din='03'x doy='05'x dynvar=doy||SetSize('Enter something..............',24)||din||, SetSize('here',8)||dol
The effect of the above code is that the start of each input field is marked by a ’03’x attribute byte and the end of the input field is marked by an ’01’x attribute byte.
The following piece of code extracts the input fields from the screen variable and places them into stem variables, then sets the total number of input fields in the dot zero stem variable:
input.='' i=0 do while pos('03'x,dynvar) <> 0 i=i+1 parse var dynvar . '03'x data '01'x dynvar input.i=data end input.0=i
Hopefully it is now obvious why I chose to use hexadecimal values for attribute characters. If I had used something the user could enter, as the end of field attribute byte then if the user entered that character, the above code would only extract data up to that character, in effect cutting the input data short.
If you use multiple differing attribute bytes to delimit the start or end of the input fields then the above code becomes more complex since you have to allow for the multiple differing start and end of field markers.
This technique works fine if the input fields are always in the same order on the screen. Remember, there is nothing in the input data from the screen that really defines what each field contains unless you look at the text that occurred before it, so you have to know that the first input field always contains data for a specific item, the second input field always contains data for the next specific item and so on.
If your application can build the screen with input fields that appear in differing order for different situations then YOU have to keep track of the order of the input fields on the screen and extract the data into the appropriate variables for your application code to process.
One way is certainly to look at the prompt that occurred before the input field and use that to determine what the data is and which variable it should go into in the application and I am sure there are many other ways to achieve the same thing. As all the best books say, this is left as an exercise for the reader!