The easiest way to start, is by looking at a simple, but useful example:
You company wants to allow it's customers to query the status of outstanding orders. Each customer has a customer number and has been assigned a password so that they cannot see each other's information.This is a simple three-page web application.
Page 1 asks the customer for an account number and a password.Here are the three pages layouts:Page 2 displays all of the outstanding orders as a list.
Page 3 displays details for a particular order.
Please enter your customer information:
|
|
Order 31075: Order entered Jan 17, 1997 by J. Higgens Ship to: American Products 271 Main street Fairbanks, MN 88871 Contact: George Jeffrey x 181 Qty Part # Style 3 887453 White/Brown shirt 5 887454 White/Grey shirt Order 31075: Order entered Jan 17, 1997 by J. Higgens Ship to: American Products 271 Main street Fairbanks, MN 88871 Contact: George Jeffrey x 181 Qty Part # Style 8 887453 White/Brown shirt 4 887454 White/Grey shirt |
|
At first, this may appear to be a daunting bit of logic, but when broken down, it is really quite simple.PicLan-IP/BASIC { } * OPEN 'ACCTS' TO ACCT.FILE ELSE STOP 201,'ACCTS' OPEN 'ORDERS' TO ORDER.FILE ELSE STOP 201,'ORDERS' * PL_GETVAR ACCT.NO FROM 'ACCT' ELSE ACCT.NO = '' PL_GETVAR PSWD FROM 'PSWD' ELSE PSWD = '' * READ ACCT FROM ACCT.FILE , ACCT.NO ELSE CALL PLW.PAGE('BADACCT.HTM','',R.ERR,RESX) RETURN END * IF PSWD <> ACCT<10> THEN CALL PLW.PAGE('BADPSWD.HTM','',R.ERR,RESX) RETURN END * EXECUTE 'SSELECT ORDERS WITH STATUS = "OPEN" AND WITH ACCT = "' : ACCT.NO : '"' * EOF = 0 NO.ORDERS = 0 * LOOP READNEXT ID ELSE EOF = 1 UNTIL EOF DO READ ORDER FROM ORDER.FILE , ID THEN IF NOT(NO.ORDERS) THEN TABLE = '<table border=1 width=100%>' LINE = '<tr>' LINE = LINE : '<th>Order Number</th>' LINE = LINE : '<th>Order Date</th>' LINE = LINE : '<th>Purchase Order</th>' LINE = LINE : '<th>Amount</th>' LINE = LINE : '</tr>' TABLE<-1> = LINE END NO.ORDERS = NO.ORDERS + 1 LINE = '<tr>' LINE = LINE : '<td><input type=checkbox name="A':CNT:'" value="':ID:'">':ID:'</td>' LINE = LINE : '<td>' : OCONV(ORDER<1>,'D') : '</td>' LINE = LINE : '<td>' : PL_QUOTE(ORDER<2>) : '</td>' LINE = LINE : '<td align=right><tt>' : OCONV(ORDER<3>,'MD2') : '</tt><td>' LINE = LINE : '</tr>' TABLE<-1> = LINE CNT = CNT + 1 END REPEAT * IF NOT(CNT) THEN CALL PLW.PAGE('NOORDERS.HTM','',R.ERR,RESX) RETURN END * TABLE<-1> = '</table>' TABLE = PL_AMTOCRLF(TABLE)
The first part of the MV/Basic code opens files. In general, you will need to open files with every subroutine call unless you save file variables in named common. The PicLan-IP web server uses standard common, so named common is usually easier to manipulate. If you must use standard common, the PicLan-Ip web server allocates an array of 500 unused variables at the front of the common block for your application code to use.
After the files are open, the code retrieves the values for ACCT.NO and PSWD. These values are then used to retrieve an item from the ACCTS file. If the account number is invalid, the logic chains to the page BADACCT.HTM. If the password does not match, the logic chains to the page BADDPSWD.HTM. If the account number and password both match, the logic continues.
In this example, an ACCESS SSELECT statement is used to retrieve the orders that meet the specified criteria. In most cases, you would replace this SSELECT with some sort of cross-reference or index lookup function that the application maintains. When the select list is retrieved, one of two cases can occur. If the list is empty, the logic chains to the page NOORDERS.HTM. If there are orders present, the MV/Basic code builds an HTML table "on the fly" that will be inserted as a single element into page 2. This is an example of where the MV/Basic code must actually know something about HTML layouts and tags. Because the table is variable in size, you cannot simply use a fixed number of simple insertion points, but must instead build a variable length table based on the size of the select list. Fortunately with HTML, building a table is a bit verbose, but simple never the less. If you do not know how to build an HTML table, build a sample HTML document with your HTML editor and then copy the table's layout into MV/Basic.
This example table has a header row and well as one detail row for each order on file. The detail row contains a checkbox form input field along with some additional display fields. The input field allow the user to check off the order(s) that they wish to see detail for.
Some notes on HTML quoting are important here. The insertion point for table is coded as {{RAW(TABLE)}}. The RAW(...) function indicates that the PicLan-IP web server should merge the variables without quoting HTML tag characters first. This is necessary because the TABLE variable that is being inserted intentionally includes HTML tags.
When building the TABLE variable, the function PL_QUOTE is used to convert the string contained in ORDER<2> to a string that is compatible with HTML. You see, certain characters such as less than '<' are not allowed within HTML documents unless they are first converted to a multi-character string that is interpreted the same way. The < characters is stored in HTML as <. You could actually use the PL_QUOTE(...) function for all of the fields, but numbers and dates are known not to contain HTML quoted characters, so using PL_QUOTE(...) is unecessary.
After the table is built, the variable NO.ORDERS contains the size of the table. This variable is merged with a hidden input field so that the next page can easily scan for which orders are selected.
And finally, the PL_AMTOCRLF(...) function is used to convert the MultiValue attribute marks into HTML CRLF sequences.
{RAW(RESULT)} |
Again, the logic here is pretty straightforward. First the NO.ORDERS variable is retrieved from the posted page. This is then used to retrieve all of the checkbox variables and build a list of item ids to display. Once you have the list, it is a simple task to build a normal ASCII display for each order using whatever data you wish. <hr> tags are added between each entry to insert an HTML horizonal rule and the final result is merged in CRLF format into the final page.PicLan-IP/BASIC { } * OPEN 'ORDERS' TO ORDER.FILE ELSE STOP 201,'ORDERS' * PL_GETVAR NO.ORDERS FROM 'NO.ORDERS' ELSE NO.ORDERS = 0 * LIST = '' FOR I = 1 TO NO.ORDERS PL_GETVAR ID FROM 'A' : I THEN LIST<-1> = ID END NEXT I * IF LIST = '' THEN CALL PLW.PAGE('NOSELECT.HTM','',R.ERR,RESX) RETURN END * I1 = DCOUNT(LIST,AM) FOR I = 1 TO I1 READ ORDER FROM ORDER.FILE , LIST<I> THEN R = 'Order ' : LIST<I> : ':' R<-1> = '' R<-1> = 'Order entered ' : OCONV(ORDER<2>,'D') : ' by ' : ORDER<14> ... more code to build order detail information RESULT<-1> = R IF I < I1 THEN RESULT<-1> = '<hr>' END END NEXT I * RESULT = PL_AMTOCRLF(RESULT)