Title: WebSnap II: Interacting with the user
Question: on this article I'll show you one way to allow the user to enter some data and use that to query our database
Answer:
ok, here we are back after a while
Lately we haven't had many visits as we used to in delphi3000, and not many people is interested in articles about
websnap... I guess because is not as easy as everyone is so used with Delphi
so, I wasn't very motivated to continue these articles, however I know there's people that is interested and appreciate
this work, so for all of them, here it is, a second article on websnap
I'm going to continue the project Websnap I: the unknown powerful and now I will upload all the source code to my personal website (yet to come... just got cable internet!) so you can actually get the whole picture
you should be able to get it right here
Web Snap I & II full source code, executable and database
ok, let's start
open your project (you did create it, right?... ok, open the project you just downloaded and just follow so you know what's going on on each unit of the project)
on this article I will cover:
- Using data entered by the user on a form to interact with a database
- Retrieving more detail data based on previous reports using our project database
so far all our pages have the header and the footer and our main page has 3 links to the 3 shifts of employees, then you click on each link and get a list of employee numbers and names, the employee number itself is a link for which now we will create the report of his production
so, let's add another 2 links to our main page
- Employee Lookup: this will have a box where the user enters the employee number to lookup, and we show the employee information with his production
- Administration: This page will allow us to add/remove employees to our database
ok, first lets add the links
open your homeU unit and click on the html code for it and add the following lines right after the last link
a href="#MODULE/emplookup"Employee Lookup/a |
a href="#MODULE/admin"Administration/a
so now we have 5 links in our page, you can run your project, run the "Web App Debugger" and see the results
now, let's create the Employee Lookup page
File|New|Other|WebSnap|WebSnap Page Module
put emplookup as the Name, Employee Lookup as the Title (or whatever more creative you can think of), and leave everything else untouched
Save your new unit as emplookupu.pas, click on the html and remove all the jscript crap, just leave the basic html tags
add sharvarsu to your new unit uses, go to your pageproducer component events and add this code to its OnHTMLTag
If (TagString='MODULE') Then
ReplaceText:=ScriptName
go to its html code and add this code (between the body tags):
!-- #include file="header.htm" --
form method="GET" action="/#MODULE/empshow"
input type="text" name="EmpBox" size="20"
input type="submit" value="Lookup" name="LookUpBtn"
input type="reset" value="Clear" name="ClearBtn"
/form
!-- #include file="footer.htm" --
the usual header and footer, and in the middle a form with a text box and two buttons, I will let you be more creative and put a background or a nice box around the form or whatever... that's what websnap is all about! let the web pages designers do this job so you can concentrate on the ISAPI development
if you take a closer look at the action on that form it says action="//empshow"
we now know that "MODULE" will get changed to our project name and /empshow will be our new page to show the employee information and his production, so, yes... we need to create a new page
so, go ahead and create a new websnap page module and put empshow as the Name, save your new unit empshowu.pas, add the usual sharvarsu to the uses clause, go to its html code and clean up all the mess and add your header.htm and footer.htm
and put
#EMPSHOW
between header and footer... we will change that to be the actual report of one employee production or whatever
We will use this page to show the report for an employee when the user types the employee number and submits... and we will also use this same page to show the same report for a page we left unfinished, that shows list of employees per shift, and has a link to the employee number... so, we're providing two ways of getting to the same place
I added two more queries to my datamodule, one to get the production for a given employee and one to find if an employee exists or not... I won't get on detail on that, you'll see it on accion on the source code...
ok... so now, the fun part... as always we are going to add the "onHTMLTag" event to this new page
we're going to replace "EMPSHOW" with the employee information and his production
so, on this new page pageProducer event, write the following code:
procedure Tempshow.PageProducerHTMLTag(Sender: TObject; Tag: TTag;
const TagString: String; TagParams: TStrings; var ReplaceText: String);
Var Emp, EmpName, EmpProd:String;
begin
Try
If (TagString = 'EMPSHOW') Then
Begin
If (Request.QueryFields.IndexOfName('EmpBox')-1) Then
Emp:=Request.QueryFields.Values['EmpBox']
Else
Raise Exception.Create('Page called with bad arguments');
With WebDataModule1.qEmployee Do
Begin
Try
Parameters.ParamValues['paEmpNo']:=Emp;
Open;
If (IsEmpty) Then
Raise Exception.Create('Employee: '+Emp+' does not exist on the database')
Else
EmpName:=FieldByName('EmpName').AsString;
Finally
Close
End
End;
With WebDataModule1.qProduction Do
Begin
Try
Parameters.ParamValues['paEmpNo']:=Emp;
Open;
If (RecordCount0) Then
Begin
//Put some header for this list
EmpProd:='Employee:'+Emp+'';
EmpProd:=EmpProd+'Name:'+EmpName+'';
EmpProd:=EmpProd+''+
''+
'Process dateItem No'+
'';
//Add the employees production
While Not (EOF) Do
Begin
EmpProd:=EmpProd+Format(' %s %d ',
[FieldByName('ProcessDate').AsString, FieldByName('ItemNo').AsInteger]);
Next
End;
EmpProd:=EmpProd+'';
ReplaceText:=EmpProd
End
Else
ReplaceText:='Employee: '+Emp+''+'Emp Name: '+EmpName+'No production.'
Finally
Close
End
End
End
Else If (TagString = 'MODULE') Then
ReplaceText:=ScriptName
Except
On E:Exception Do
ReplaceText:='Error during process: '+E.Message
End
end;
...done =o)... we request the parameter "EmpBox"... this works because on our emplookup page we named our "TEdit" name="EmpBox", so that gets sent to this page as parameter, then we do the queries to find if the employee is in our database and raise an exception if not... as you see at the bottom the exceptions get handled, so we show a nice message and we get to keep our header.htm and footer.htm and the error shows in the middle... =o)
ok... now, to use this same page for the other one we had left with links pointing to nothing (the list of shift page), we go open the shiftu and change the link... to something like this:
EmpList:=EmpList+Format(' %s %s ',
[ScriptName, EmpNo, EmpNo, FieldValues['EmpName']]);
this means, call the page "empshow" with the parameter "EmpBox" and then the employee number, which we read from the database... and we saw above we read the parameter "EmpBox"... so, it works =o)
Ok... finally we implement an administration page, which will allow us to add/delete employees from our database
basically it will be the same... a page to ask the user for the employee number and two buttons, one to add, one to delete...
then another page to read the parameters and execute a query on the database and we're done...
ok... here we go
create a new page, call it admin... everything default, remove the jscript crap, add the usual header and footer... add the sharvarsu to the uses...
and add this code between the header and footer
I called this unit adminu (for some reason I always add a "U" at the end of the unit names...)
form method="GET" action="/#MODULE/empaction"
Emp No : input type="text" name="EmpBox" size="10"
Emp Name: input type="text" name="EmpName" size="40"
Shift : input type="text" name="Shift" size="1"
input type="submit" value="Add" name="Add"
input type="submit" value="Delete" name="Del"
/form
that's it on this page, we need a new page of course called empaction
form method="GET" action="/#MODULE/empaction"
oh, I almost forgot, you need to add this code to the page producer OnHTMLTag event, just so the links don't get broken
procedure Tadmin.PageProducerHTMLTag(Sender: TObject; Tag: TTag;
const TagString: String; TagParams: TStrings; var ReplaceText: String);
begin
If (TagString = 'MODULE') Then
ReplaceText:=ScriptName
end;
New websnap page, header, footer, blablabla... same as everyother page
of course the unit name will be empactionu =o)
The source of the page producer OnHTMLTag looks like this:
procedure Tempaction.PageProducerHTMLTag(Sender: TObject; Tag: TTag;
const TagString: String; TagParams: TStrings; var ReplaceText: String);
Var Emp, EmpName, Shift:String; ToDoAction:(acAdd, acDelete, acUnknown);
begin
Try
If (TagString = 'EMPACTION') Then
Begin
If (Request.QueryFields.IndexOfName('Add')-1) Then
ToDoAction:=acAdd
Else If (Request.QueryFields.IndexOfName('Del')-1) Then
ToDoAction:=acDelete
Else
Raise Exception.Create('Page called with bad arguments. No action specified.');
If (Request.QueryFields.IndexOfName('EmpBox')-1) Then
Emp:=Request.QueryFields.Values['EmpBox']
Else
Raise Exception.Create('Page called with bad arguments. No employee number specified.');
EmpName:=Request.QueryFields.Values['EmpName'];
Shift :=Request.QueryFields.Values['Shift'];
With WebDataModule1.qEmployee Do
Begin
Try
Parameters.ParamValues['paEmpNo']:=Emp;
Open;
If (IsEmpty) Then
Begin
If (ToDoAction=acDelete) Then
Raise Exception.Create('Employee: '+Emp+' does not exist on the database')
End
Else If (ToDoAction=acAdd) Then
Raise Exception.Create('Employee: '+Emp+' already exists on the database')
Finally
Close
End
End;
With WebDataModule1.qAddDelete Do
Begin
Try
SQL.Clear;
If (ToDoAction=acAdd) Then
Begin
SQL.Add('insert into employees');
SQL.Add('(EmpNo, EmpName, Shift)');
SQL.Add('VALUES ('+QuotedStr(Emp)+', '+QuotedStr(EmpName)+', '+QuotedStr(Shift)+')');
End
Else
SQL.Add('delete from employees where EmpNo='+QuotedStr(Emp));
Try
ExecSQL;
Except
On E:Exception Do
Raise Exception.Create('Error executing action query: '+E.Message);
End;
If (ToDoAction=acAdd) Then
ReplaceText:='Employee: '+Emp+' succesfully added to the database'
Else
ReplaceText:='Employee: '+Emp+' succesfully deleted from the database'
Finally
Close
End
End;
End
Else If (TagString = 'MODULE') Then
ReplaceText:=ScriptName
Except
On E:Exception Do
ReplaceText:=ReplaceText+'Error during process: '+E.Message
End
end;
done... it tells you if you attempt to delete an employee that does not exist... or try to add an employee that already exits, so... we're done...
I added links to all the pages from all the pages so it's easier to navigate, you'll see on the full thing, look at the html code of each page...
looks something like this for all the pages:
!-- #include file="header.htm" --
a href="/#MODULE/shift?Shift=N"Night Shift/a |
a href="/#MODULE/shift?Shift=M"Morning Shift/a |
a href="/#MODULE/shift?Shift=A"Afternoon Shift/a |
a href="/#MODULE/emplookup"Employee Lookup/a |
a href="/#MODULE/admin"Administration/abr
hr
#EMPACTION
!-- #include file="footer.htm" --
as you can see is pretty simple, it's always the same:
put some html code with "transparent tags", replace those tags on your page producer OnHTMLTag event, and that's it
you just need to do it 2 or 3 times and you get used to it
If you guys are interested I'll upload more articles on other aspects of websnap, if not... we'll just move on to IntraWeb
'til then... keep up coding
salu2
EberSys