Recently I was asked how I perform a specific task with the eRPG SDK.
Suppose you have a table with each row being a row of data. There is also a checkbox for each row which will tell your application to update/delete this specific row.
You want to know:
One of my personal applications that I use to keep track of licensing for our software has just such an application. Here is how we do it in a very simplified version:
First, the detail template line (which will be written out for each record) looks like the following:
/$list1
<tr>
<td">
<input type="checkbox" name="/%detrrn%/del" value="y" title="Delete" onChange="updateRow('/%detrrn%/change');">
<input type="hidden" name="/%detrrn%/change" id="/%detrrn%/change" value="n">
<input type="hidden" name="detrrn" value="/%detrrn%/">
</td>
....
</tr>
You will see a replacement value of /%detrrn%/ on this record in a few places. This will be replaced with the Relative Record Number (RRN) of the record we are reading from our Customer Key file. Adding the RRN as a prefix on the field names is what will allow us to have unique form field names for each record of our file. We also have a hidden field named detrrn that is written out only in this first cell, just so the RRN itself will be available to our application.
When writing out this information using the eRPG SDK to a web page, the program looks like this:
FCSTKEY1 IF E K DISK INFDS(DETDS)
****************************************************************
* Prototypes *
****************************************************************
/COPY QCOPYSRC,P.ERPGSDK
/COPY QCOPYSRC,P.STRING
****************************************************************
D DETDS DS
D DetRRN 397 400I 0
...
/free
#loadSection('list1');
SETLL CMEMAIL CSTKEY1;
READE CMEMAIL CSTKEY1;
dow (not %eof(CSTKEY1));
#replaceData('/%detrrn%/':%editc(DetRRN:'Z'))
...
READE CMEMAIL CSTKEY1;
enddo;
This was done quite a few years ago, so the %editc() could be replaced with %char() if you wanted. But, once we are done we will have a table row that looks like this:
<tr>
<td>
<input type="checkbox" name="10364del" value="y" title="Delete" onChange="updateRow('10364change');">
<input type="hidden" name="10364change" id="10364change" value="n">
<input type="hidden" name="detrrn" value="10374">
</td>
...
</tr>
A sample of the actual table is as follows:
Now, we are using an onChange action in our application. The JavaScript for the updateRow() function looks like the following:
function updateRow(row) {
document.getElementById(row).value="y";
}
Again, this was done a few years ago (before jQuery) so this could also easily be updated if needed. But, we see that all this does is update the hidden field of 10364change to the value of "y", What this does is in our processing program (the program that runs when the form is submitted) allows us to know if a specific row has changed. In the real application, more than just this checkbox can initiate a change (such as an updated serial number or model number), but for this example, we will stick to just using the checkbox.
The next step is reading the data into our program and finding which rows have changed. This is done using the following:
...
D i S 10i 0
D detrrn S 10i 0
D detRRNx S 32
...
/free
i = 1;
detRRN = #CtoN(#getData('detrrn':i));
dow (detRRN > 0);
detRRNx = %editc(detRRN:'Z');
if (#getData(%trim(detRRNx) + 'change') = 'y');
CHAIN detRRN CSTKEYPF;
if (%found(CSTKEYPF));
if (#getData(%trim(detRRNx) + 'del') = 'y');
exsr $DelCal;
DELETE RCSTKEY;
...
i = (i + 1);
detRRN = #CtoN(#getData('detrrn':i));
enddo;
The #CtoN() function is something I wrote many years ago to convert characters to numeric. It is included with the eRPG SDK as well. These days we can use %dec(), but I've found I like using #CtoN() even so because if the data is invalid, instead of using a MONITOR block and issuing an error, it will just return zero, which, in most cases lets me know that there is an error.
To start, we set the index variable of i to 1. This will be used as an index to retrieve the specific instance of the detrrn variable. Because each row of our table has a detrrn variable, we will retrieve a list of them like this:
detrrn=10374&detrrn=10375&detrrn=10376...
For each RRN we retrieve, we use the value of that field to retrieve the values for the uniquely named fields in our form. That means that on our first iteration this code:
#getData(%trim(detRRNx) + 'change')
Will really be doing this:
#getData('10375change')
We can then use this method to retrieve any form fields from our page, each of them uniquely prefixed with this specific row id.
Now, the one issue one could have with using the RRN as a unique ID is if someone does a Reorganization on the file between the time the page is displayed and the update is performed. This of course will throw off the RRN. And if this will be an issue, I would recommend some other way of uniquely identifying each record in the file (such as your own RRN as a field in the file that is unique). Or better yet, don't reorg while your web applications are running. ;)
But, for me, using the actual RRN of the record works just fine.
There are some updates that could be done with this, but it's "not broke" so I'll save "fixing" it for sometime when I have more free time. :)