I teach at a small college in the United States where I use an application similar to this sample on my Class web site. The application collects information about the students enrolled in the class. I require that each student enter their name, student ID number, email address, campus username, and a password. With this information in a database table, I create web server login accounts, file upload folders, an online grade book, a class listserve, and customized project files.
After reading the Web.How paper and with the help of the Web Wizards, creating a web-based data entry form was a breeze. Most of my students, however, are 18-year-old freshmen (i.e., first year of college in the US) and they tend to submit inaccurate information. First I tried to validate the data that the students entered with JavaScript in the web form, but there were still many inaccuracies. So I needed a way to let the student modify the information they had entered.
About eighteen-month ago, when I ran an application like this on the College LAN, modifying records was simply a mode of the rowset. However, this is not the same with a web application. After a web application finds the data to modify, it prints a web page containing that data, and, then, the application is suspended. The data table is closed when the web user is viewing the data as a web form. Thus, to modify a record, I needed two procedures: One to seek the record to modify and "paint" the web page, a second to receive the modified data, find the correct record in the data table, and update the record.
My application needed three sub-procedures: one to add new data, a second to find data for modification, and a third to update the data. I did not want to create a separate executable for each of these sub-procedures so I needed a way for the web forms to control the application. To do this, my dBASE application uses a Case statement to evaluate commands from the web forms.
I will now discuss these two issues.
Modify Data
The basic steps to modify a record are as follows:
01 fOut.Puts([<TD BGCOLOR="#009999"><B>Last Name:</B></TD>]) 02 fOut.Puts([<TD BGCOLOR="#009999"><INPUT TYPE=TEXT NAME="Lname"]) 03 If not empty(data->lname) 04 fOut.Puts([VALUE="] + trim(data->lname) + ["]) 05 Endif 06 fOut.Puts([></TD>]) |
|
The first line prints the HTML
for the field label in a table’s cell. The second line prints the
beginning of the HTML input tag. If there is data in the field, line
four prints the value of the input. Line six closes the HTML input tag
and ends the table cell. In the web page these lines will look as
follows:
<TD BGCOLOR="#009999"><B>Last Name:</B></TD> <TD BGCOLOR="#009999"><INPUT TYPE=TEXT NAME="Lname" VALUE="Nuwer"></TD> |
|
When the modified data is returned
to the web server, the application must be able to find the record that
was modified. For this reason I include a hidden field in the modify page
which contains the value of the AutoIncrement field.
fOut.Puts([<INPUT TYPE="hidden" NAME="ID" VALUE="] ; + str(data->ID,3,0) + [">]) |
|
In the web page these lines will
look as follows:
<INPUT TYPE="hidden" NAME="ID" VALUE=" 14"> |
|
When the browser submits the web form, the dBASE application seeks this value in the data table. The important point here is that there must be at least one field in the table that users can not modify. Otherwise there will be no way to know which record needs to be updated.
Controlling Application Flow
My simple application includes three primary procedures. Each procedure could be compiled separately and the web forms could call the requisite executable. I find it simpler, however, to create one executable and let the program branch with a Case statement.
In order to control the application
from a web browser, all the submit buttons in the web forms are named "action."
For example, the HTML for the two buttons on the modify record page looks
like this:
<INPUT TYPE=SUBMIT NAME=action VALUE="Modify This Record"> <INPUT TYPE=SUBMIT NAME=action VALUE="Abandon Changes"> |
|
When the user clicks the button titled "Modify This Record," the CGI query_string includes the name/value pair: action= Modify This Record. In my application this name/value pair is always the last pair in the query_string. (This is controlled by the order of the <INPUT> tags within the <FORM> tag.) The last name/value pair is stored to the memory variable called cAction when my dBASE application receives the CGI query_string.
Custom buttons could be used as an alternative method of submitting web forms. An explanation of how to use custom command buttons is available here .
There are four values of cAction
that my application is looking for
Add -> this will generate a web
page for data entry.
Add Record -> data passed from
the data entry page is appended to the data table
Modify Record -> This will generate
a web page that is populated with data from our table.
Modify This Record -> Data passed
from the modify page replaces the existing data in the table.
Since the dBASE developer is now
on familiar ground I will simply explain what each case does in my simple
application.
Do Case Case (ltrim(trim(cAction)) == "Add") |
|
Case (cAction == "Add Record") |
|
Case (cAction == "Modify Record") |
|
Case (cAction == "Modify This Record") |
|
Otherwise |
|
The simple dBASE application that I’ve discussed here can be modified and/or expanded to do many different things. I hope that this discussion helps cut away some of the mystery of web application. For more information, I encourage you read Alan Katz’s Web.How paper and to create a few applications with the web wizards. (Be sure to get the newest version at http://www.dbase.com/Docs/Downloads.htm) Read the PRG file that is created by the web wizards, because there’s a lot of good stuff in those programs. Finally, if you would like to look at a few more web sample, I have posted some at http://www.nuwermj.potsdam.edu/dSamples/.