IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Point and Shoot )PTNS


IBM Mainframe Forums -> TSO/ISPF
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
RazVorox

New User


Joined: 19 Oct 2022
Posts: 32
Location: Israel

PostPosted: Tue Dec 05, 2023 2:57 pm
Reply with quote

*This is a tut, written by a newb *

Since I had problems when i tried to figure it out,
and couldn't really find any examples, or good code samples
(other then that one ISPF manual thing, which wasn't great help),
and things in general where very unclear to me,
trying to sort through the mess which is IBM Documentation..

So I've decided to pick up the glove,
and write my own little tut example.
For future newbs and generations.
(insert )P(a)NTS pun -HERE- icon_smile.gif

-3- Disclaimers -

3rd - TL;DR - this is long, written as a tut.
you can skip to the end.
Full code there. panel + rexx.
should be self explanatory.

1st - I'm new to the mainframe.
If any of you older, wiser obi-ones out there,
have anything to add, comment or say about what is written here -
- PLEASE DO !! -
As stated, I'm new to MF, and I'm pretty sure I've missed quite a lot,
so any notes remarks appends etc - are more than welcomed.

2nd - this is written light, basic, and with puns.
don't take it to srsly.
It's supposed to sort things through, and give you a push,
to get a handle on the the manual. it doesn't (even comes close to)
replacing it in any way. its not the end, its just pants-for-dummies.
so after this - go dive in the docs, with hopefully a better grip on it.

So.. Point And Shoot.
(From here on shall be referred to as POS, since I'm lazy,
and "PointAndShoot" is just toooo much to write..)

The basics -
POS lets you hit "Enter", when your cursor is on a defined POS field.
hence the title - point, and shoot.
meaning, you have 2 components : the "where" - field,
and the "what" - happens when you hit enter, wile on it.
Which is pretty much only being able to assign a value, to a var.
(We -COULD- use said var to trigger things later, in the rexx,
but for the actual POS - its only that.)
So the syntax would be: FIELD, VAR, (and) VAL.

the FIELD bit, is defined in the )ATTR section,
and its (re)action bit, is defined in a special )PNTS section.
(note: each FIELD, -MUST- have a )PNTS !. I mean,
it makes sense, but the manual is adamant about it,
so I thought I'd wirte 3 more lines just to clear the importance
of it. define+action. pair. must have both.)

Since the ISPF has 3 basic types of fields
(TEXT and 2 I/O - INPUT and OUTPUT),
the POS will also have 3 type field options :
TEXT, and the two I/Os - Input, and OUTPUT.

The fields themselves still operate and act as normal fields.
meaning - I can still get some value from an "input",
and put it on an "output", or run it through some rexx.
In fact - since pants cannot really "trigger" anythings,
and can just assign values - we WILL use a rexx-var to trigger things,
and show the back and forth data-flow.

Back from the tangent -
Fields under )ATTR
TEXT type is defined as PS type (PointShoot)
Code:
$ TYPE(PS)


I/O (INPUT, OUTPUT) fields are defined the same,
they just get an extra attribute.
Code:
 } TYPE(INPUT) PAS(ON)
 ! TYPE(OUTPUT) PAS(ON)


The )PNTS bit, is just a -little- more complicated.
The I/O fields, easy enough, are called by name.
Lets create 1 INPUT field, and 1 OUTPUT field.
for OCD reasons which means the both have to have the same
ammount of letters so they'll indent well,
We'll call them IN01, and OUT1, respectively.
(Remeber? where + what => FIELD + VAR (and) VAL)
WHERE - field names: IN01, OUT1
WHAT -
hmm.. ok. so, lets say that when we are on the -OUT1- field,
we want whatever is in there, to go to some rexx-var.
so we can do stuff with it. dont know what yet, but it'll serve a point.( and shoot).
For the -IN01-, lets just say "hit", if we are "on it",
and place that in the same rexx-var.
(you could, of course, put the in, in the out, directly,
but we want to play with it, for demonstration purposes)
Code:
FIELD(OUT1) VAR(REXXVAR) VAL(OUT1)
FIELD(IN01) VAR(REXXVAR) VAL(HIT)


As for the TEXT fields - thats where the -little-
from the before "complicated" - comes into play.
For they go not by names, but by the numbers. (!!)
We essentially have 3 parts:
- Use a "ZPS" as prefix.
- First 2 numbers as an AREA code.
- next 3 numbers as the FIELD number.
Count top to bottom, left to right, first to last.
Not that complex actually. just.. needs a clear explanation.


The "ZPS" part is clear. Next.

The first 2 numbers identify the AREA (code)
if the field is plain and clear and in the )BODY, AREA code = 00.
If its part of some scrollable area.. well, put the area number.
(if its in the first area, put 01. if its in the second - put 02 etc.)

Next 3 numbers, identify the field.
just go count. srsly. that easy.
like, if we have 6 fields, count them, first to last, top to bottom,
left to right, 001, 002, 003, ... 006.

For our example, we'll create 3 fields, in the )BODY.
no fancy scroll. No area codes. beginner style.

Lets make a nice RPG menu.
We'll need a "MAP', (obviously), an "INV" (inventory),
and maybe a "CHR" for some character sheet.
(Respectivly, we could later on use then to call a
different panel - map, a table perhaps, for the inventory,
and perhaps some sort of sheet, a pds, for the char).

so that's "map" (1 - 1st), "inv" (2 - 2nd) and "chr" (3 = 3rd).
And since we count - order matters.
- map )body 1st - will be - ZPS+00+001
- inv )body 2nd - will be - ZPS+00+002 (and..)
- chr )BODY 3rd - will be - ZPS+00+003.
Code:
FIELD(ZPS00001)
FIELD(ZPS00002)
FIELD(ZPS00003)


That handles the "hard", WHERE part.

NEXT, the WHAT -
Lets keep it simple, and just identify the fields,
so we could perhaps later throw them in a REXX-SELECT,
to trigger our future panel, table, of file.
(Again - you could replace those with whatever you want.
they're just values, that just happens to have the same name as the fields.)
So, the complete code would be:
Code:
FIELD(ZPS00001) VAR(REXXVAR) VAL(MAP)
FIELD(ZPS00002) VAR(REXXVAR) VAL(INV)
FIELD(ZPS00003) VAR(REXXVAR) VAL(CHR)


Just for newb clearance -
the )ATTR DEFAULTs are:
text - high, text - low, and input as '_',
so we'll just add those in as well, so its easier to remember -
Code:
% TYPE(TEXT)  INTENS(HIGH) COLOR(GREEN)
+ TYPE(TEXT)  INTENS(LOW)  COLOR(GREEN)
_ TYPE(INPUT) INTENS(LOW)  COLOR(GREEN)


... and.. we'll add just a dash-o-color,
so it's not all completely boring -
Code:
@ TYPE(TEXT)  INTENS(LOW)  COLOR(RED) 
^ TYPE(TEXT)  INTENS(LOW)  COLOR(BLUE)


And to put it all together,
the )ATTR should look something like:
Code:
)ATTR                                     
/* DEFAULTS: */                           
 % TYPE(TEXT)  INTENS(HIGH) COLOR(GREEN) 
 + TYPE(TEXT)  INTENS(LOW)  COLOR(GREEN) 
 _ TYPE(INPUT) INTENS(LOW)  COLOR(GREEN) 
/* SOME COLOR.. */                       
 @ TYPE(TEXT)  INTENS(LOW)  COLOR(RED)   
 ^ TYPE(TEXT)  INTENS(LOW)  COLOR(BLUE)   
/* PONIT AND SHOOT: */                   
 $ TYPE(PS)             /* TEXT   */     
 } TYPE(INPUT) PAS(ON)  /* INPUT  */     
 ! TYPE(OUTPUT) PAS(ON) /* OUTPUT */     


- THATS IT FOR THE HARD PART ! -
now..
LETS DRAW A )BODY !!!

We'll get some fancy title, some "ASCII ART" frame,
that dash of color, our TEXT fields (IN THE RIGHT ORDER !!),
our 2 I/O fields (in whatever order or location we want)
and indent the heck out of them, so they look snazzy.
(we only really care about the text fields.
they are the only ones that count. icon_biggrin.gif.)
(And yes. I made this entire tutorial, just for that one line.)
Code:
)BODY                     
+.-----------------------.
+|   -=[^OPTIONS+]=-    +|
+|                      +|
+| CHOOSE:              +|
+| $MAP (PANEL)         +|
+| $INV (TABLE)         +|
+| $CHR (SHEET)         +|
+|                      +|
+| @GENERAL INPUT:}IN01 +|
+.-----------------------.
+|=> !OUT1               |
+.-----------------------.

blue option nice title, green frame, some red input.. just playing with it.

Putting our )P(a)NTS on.. -
Code:
)PNTS                                   
/* TEXT FIELDS */                     
FIELD(ZPS00001) VAR(REXXVAR) VAL(MAP)
FIELD(ZPS00002) VAR(REXXVAR) VAL(INV)
FIELD(ZPS00003) VAR(REXXVAR) VAL(CHR)
/* INPUT FIELDS */                   
FIELD(IN01) VAR(REXXVAR) VAL(HIT)     
/* OUTPUT FIELDS */                   
FIELD(OUT1) VAR(REXXVAR) VAL(OUT1) 


and last, but not least, our honorary rexx-var.
we'll call him Jhon. (no, not really...)

we want to )INIT it,
Code:
)INIT           
&REXXVAR = 'NOPE'


We'll use )REINIT to refresh the whole thing,
and put a )PROC section in, just for future dev.

Order of ')' SECTIONS is important, up to the )PROC section,
so i think its good practice for beginners to write them down.
its like using )PANEL just to put some comments in.
no necessary, but nice to have at first.

ANYWAYS...
- FINALY ! after all that boring talk,
The complete panel code -
Code:
)PANEL                               
/* BASIC RPG POINT-AND-SHOOT MENU */
)ATTR                                     
/* DEFAULTS: */                           
 % TYPE(TEXT)  INTENS(HIGH) COLOR(GREEN) 
 + TYPE(TEXT)  INTENS(LOW)  COLOR(GREEN) 
 _ TYPE(INPUT) INTENS(LOW)  COLOR(GREEN) 
/* SOME COLOR.. */                       
 @ TYPE(TEXT)  INTENS(LOW)  COLOR(RED)   
 ^ TYPE(TEXT)  INTENS(LOW)  COLOR(BLUE)   
/* PONIT AND SHOOT: */                   
 $ TYPE(PS)             /* TEXT   */     
 } TYPE(INPUT) PAS(ON)  /* INPUT  */     
 ! TYPE(OUTPUT) PAS(ON) /* OUTPUT */     
)BODY                       
+.-----------------------.   
+|   -=[^OPTIONS+]=-    +|   
+|                      +|   
+| CHOOSE:              +|   
+| $MAP (PANEL)         +|   
+| $INV (TABLE)         +|   
+| $CHR (SHEET)         +|   
+|                      +|   
+| @GENERAL INPUT:}IN01 +|   
+.-----------------------.   
+|=> !OUT1               |   
+.-----------------------.   
)INIT                                 
&REXXVAR = 'NULL'                     
)REINIT                               
REFRESH(*)                           
)PROC     
/* FUTURE CODE HERE */                           
)PNTS                                 
/* OUTPUT FIELDS */                   
FIELD(OUT1) VAR(REXXVAR) VAL(OUT1)   
/* TEXT FIELDS */                     
FIELD(ZPS00001) VAR(REXXVAR) VAL(MAP)
FIELD(ZPS00002) VAR(REXXVAR) VAL(INV)
FIELD(ZPS00003) VAR(REXXVAR) VAL(CHR)
/* INPUT FIELDS */                   
FIELD(IN01) VAR(REXXVAR) VAL(HIT)     
)END                                 


and the rexx that comes with it -
Code:
/* REXX */                                                             
ADDRESS ISPEXEC                 /* SELF EXPLANATORY */                 
ISPEXEC CONTROL DISPLAY REFRESH /* CLEAR AND CLEAN DISPLAY */           
                                                                       
/* ADD THE PDS WHERE THE PANEL IS */                                   
"LIBDEF ISPPLIB DATASET ID ('MY.PANEL.LIB') STKADD"                     
                                                                       
/* WE NEED A "FOREVER" LOOP, SO WE CAN PLAY WITH OUR PANEL.  */         
/* "FOREVER" LOOPS ARE DANGEROUS FOR BEGINNERS, SO WE'LL USE */         
/* A WHILE WITH A COUNTER INSTEAD. AND AN RC SAFE-TRIGGER    */         
/* IF WE HIT 10 TIMES, OR SOMETHING GOES WRONG - EXIT.       */         
                                                                       
COUNTER = 0                     /* LEAVE AFTER X REPETITIONS          */
RCC = 0                         /* LEAVE IN CASE SOMETHING GOES WRONG */
DO WHILE RCC = 0 & COUNTER < 10                                         
   ADDRESS ISPEXEC 'DISPLAY PANEL(PANLNAME)' /* SHOW THE PANEL        */
   RCC = RC                     /* GET THE RC - EXIT TRIGGER          */
   SAY 'REXX VAR = ['REXXVAR']' /* CHECKOUT THE REXX-VAR !! :)        */
                                                                       
   IF IN01 ¬= '' THEN DO        /* ANYTHING IN THE IN-FIELD ?         */
     OUT1 = IN01                /* IF SO - SIPHEN IT TO THE OUT-FIELD */
   END                                                                 
   ELSE DO                      /* ELSE, (EMPTY INPUT FIELD)          */
     OUT1 = REXXVAR             /* JUST SHOW US WHAT WE CLICKED..     */
   END                                                                 
                                                                       
   COUNTER = COUNTER + 1        /* FAIL SAFE INC COUNTER              */
END                                                                     
                                                                       
RETURN 0                                                                                                                                                             



Long. I know.
But this is how I eventually got it.
Hope it helps whomever comes across it,
since when I needed one, I couldn't find one.

Checkout the "ISPF Dialog Developer's Guide and Reference "
Parts one and two. It'll help you put things together.

Also an honorable mention to stackoverflow,
where I found a code example,
that eventually made everything fall into place.
Credits due, where credit's due.
Look for a post named - "Panel doesn't execute )PNTS Section"

(Running it one last time,
just to make sure everything still works..
and... )
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> TSO/ISPF

 


Similar Topics
Topic Forum Replies
No new posts A directory in the pathname was not f... ABENDS & Debugging 0
No new posts How to remove DECIMAL POINT (.) from ... SYNCSORT 10
No new posts Online Assembler Program Starting point PL/I & Assembler 4
No new posts how to convert fixed-point data forma... DFSORT/ICETOOL 4
No new posts ICETool : manipulating floating point... DFSORT/ICETOOL 9
Search our Forums:

Back to Top