Dig more into what you can do with frames and see why they could be useful for you.
In my previous frame-crossing tip, I showed you how to send information between various frames on a Web page using just HTML and JavaScript. This time, I have added in a few RPG CGI programs and some more JavaScript. Actually, I have written a small application in which you can maintain an order header and add order lines to an order detail file.
The RPG CGI programs are very simple programs that read some input from an HTML form or query string and output some HTML using "normal" skeleton HTML documents. Please note that they don't have much error-checking or anything built into them. Their only purpose is to function as "drivers" for the frame examples.
I have saved them all in a save file that you can download. I included compile instructions in the top of the source files if you need to re-compile when making changes to the programs.
Let me explain how it all works.
When the page is loaded, four frames will be created, each containing a different kind of information. If you look at Figure 1, it's easy to see how the Web page is designed. In the top frame, you have some order header information; in the middle, you have the detail information, which is the order lines; then comes the working area, where you can type in products and quantity; and in the bottom, you have the status area, where messages will be written out.
Figure 1 shows the name of the frames plus the HTML or RPG CGI program that will be loaded within the frame.
Figure 1: Here's your basic frame design. (Click images to enlarge.)
When the page is loaded, the two RPG CGI programs FORM014HD and FORM014DT are called on the Web server. They look for the data on the System i and display it on the Web page if any is found. The page is now ready to use.
Changing the Header Information
If you click the "Change header data" button, a pop-up window will appear looking like the one in Figure 2.
Figure 2: Change your header information.
This simple HTML document shows a form containing all the information from the frame site. Not much there you might think, but behind the scenes, a lot has happened. If you display the HTML source, you will easily see it. Find the <body> tag, and there you'll see that the onLoad event is specified. You'll also see that a JavaScript function called InitData is called with no parameters.
<body onload="javascript:InitData();">
Scroll up again and find the function. Wow! That looks really complicated!
//-------------------------------------
// Focus cursor and default text
//-------------------------------------
function InitData() {
document.DataForm.name.value = opener.document.getElementById('name').value;
document.DataForm.address.value = opener.document.getElementById('address').value;
document.DataForm.zip.value = opener.document.getElementById('zip').value;
document.DataForm.city.value = opener.document.getElementById('city').value;
document.DataForm.name.focus();
WriteMessage('Data retrieved from frame...');
}
Well, it's not. Please let me introduce to you the opener property. The opener property sets or retrieves a reference to the window that created the current window; that means that a "tube" is created between the two pages, and it allows you to pass data through it. This data passing can occur when an event is fired. The event can be an onChange, an onClick, or something else. If you look at the line below and read from right to left, it is all pretty easy to understand:
document.DataForm.name.value = opener.document.getElementById('name').value;
The value of the field with the ID called 'name' in the HTML document that opened the window will be moved into the field called name in the HTML form called DataForm in the current document. I then repeat the lines for all the fields I want to update in the pop-up window, and in the end, I write out a message to the opening document's frame called statusx by calling function WriteMessage and passing the data I want written to the browser. The line looks like this:
opener.parent.frames["statusx"].document.getElementById("statustext").innerHTML='Last action:<b> '+msg+'</b>';
Again, read from right to left: Create the message and send it at the div tag called "statustext" in the frame named "statusx" in the browser window that opened the pop-up. This might seem a little confusing the first time you see it, but try playing around a little and change some of the parameters, and you'll soon discover that it's not that complicated.
Now, change some information and press the Save Data button. This causes function SaveData to be called. The content of the fields in the form are read and sent back through the opener "tube," and a message saying "Data saved from pop-up..." is written to the statusx frame. Then press Close Window, and the window will close, and a message saying "Window closed..." will appear in the statusx frame.
Of course, this example will be a little over the top in the real world, but for testing purposes, it works just fine.
Well, that was the hardest part. If you're still with me, let's move on to the detail information.
Writing Detail Lines
Writing detail lines is very easy. Two frames are used in this example, one called "detail" and the one called "work."
In the work document, I have created a simple HTML form called DataForm, which looks like the one in Figure 3.
Figure 3: The simple HTML form called DataForm looks like this.
The source is below:
<form method="post" name="DataForm" action="http://yourserver/cgi-bin/form014DT" target="detail">
<table border="0" cellspacing="0" cellpadding="5">
<tr bgcolor="#C0C0C0">
<td align="center">
Product
</td>
<td>
<input type="text" size="10" maxlength="10" name="prod" id="prod" class="border">
</td>
<td align="center">
Qty
</td>
<td>
<input type="text" size="3" maxlength="3" name="qty" id="qty" class="border">
</td>
<td align="center">
<input type="hidden" value="Y" name="showmessage">
<input type="submit" value="Save data on i5" name="savedata">
</td>
</tr>
</table>
</form>
You can enter a product number and a quantity, and when you press "Save data on i5," RPG CGI program FORM014DT is called through the action attribute in the <form> tag. The data will be read by the RPG CGI program, and the page will reload, displaying the data.
The interesting thing here is the target="detail" attribute in the <form> tag. This causes all the above to happen inside the detail frame, which is where we want it to occur. Try to remove the target attribute and see what happens.
Installing
To install the HTML files, do the following:
1. Download the zip file called framecrossing2.zip by clicking here.
2. Important: Change index.htm to point to your Web server.
3. Unzip and upload all the documents to an IFS directory called /your web server root/mcpressonline/framecross2.
To install the RPG CGI programs and the two data files called FRAMEHEAD and FRAMEDETAL, download the zipped save file framecros2.zip from here.
1. Unzip framecros2.zip to framecros2.savf.
2. Create a save file called FRAMECROS2 in your cgilib on your Web server.
3. FTP the framecros2.savf to the save file you just created.
4. Restore the source file QFRAMECRS2 into your CGI library using the following command:
RSTOBJ OBJ(QFRAMECRS2) SAVLIB(CGILIB) DEV(*SAVF) SAVF(yourlib/FRAMECROS2) MBROPT(*ALL) ALWOBJDIF(*ALL)
Important: Change constant IFSpath in FORM014DT and FROM014HD to reflect the actual path where form014hd-reply.htm and form014dt-reply.htm are located.
5. Compile the FRAMEDETAL and FRAMEHEAD DDS description.
6. Compile FORM014DT and FORM014HD using the compile commands in the description area of the source files or copy/paste the commands below and change according to your needs.
FORM014DT
CRTRPGMOD MODULE(yourlib/FORM014DT) SRCFILE(yourlib/QFRAMECRS2)
SRCMBR(FORM014DT) DBGVIEW(*SOURCE) REPLACE(*YES)
CRTPGM PGM(yourlib/FORM014DT) MODULE(FORM14DT)
BNDSRVPGM(QHTTPSVR/QZHBCGI)
FORM014HD
CRTRPGMOD MODULE(yourlib/FORM014HD) SRCFILE(yourlib/QFRAMECRS2)
SRCMBR(FORM014HD) DBGVIEW(*SOURCE) REPLACE(*YES)
CRTPGM PGM(yourlib/FORM014HD) MODULE(FORM014HD)
BNDSRVPGM(QHTTPSVR/QZHBCGI)
7. If you do not have CGIPARSEZ from one of my previous tips, compile it using the following commands:
CRTRPGMOD MODULE(yourlib/CGIPARSEZ) SRCFILE(yourlib/QFRAMECRS2)
CRTPGM PGM(yourlib/CGIPARSEZ) BNDSRVPGM(QHTTPSVR/QZHBCGI)
When the compiles are done, use the following link to start up the page:
http://your-server/mcpressonline/framecross2/index.htm
You've Been Framed!
This ends the frame-crossing TechTip series. I know a lot of people do not like frames for various reasons, but if you create in-house applications, frames are powerful and easy to use, and you can gain a lot of functionality that is very easy to control with a little use of JavaScript and common sense.
One very important thing to remember is that frame crossing is only--and I repeat only--allowed within the same Web server and even the same port. If you try to cross servers, you'll get a message saying something like "Access denied," which can lead to a lot of extra work.
But try it out yourself and see if it can do you any good.
Until next time, stay tuned and don't get framed.
LATEST COMMENTS
MC Press Online