Delphi Programming

  1. Home
  2. Computing & Technology
  3. Delphi Programming
RTL reference|Glossary|Tips/Tricks|FREE App/VCL|Best'O'Net|Books|Link To
 
ISAPI tutorial for Delphi developers
Page 15: Database enabled applications - Part 3
 More of this Feature
• Pg 1: Intro to web-broker
• Pg 2: Using this tutorial
• Pg 3: Getting started
• Pg 4: Web Actions
• Pg 5: The first ISAPI app
• Pg 6: TWebRequestObject
• Pg 7: Request-responding
• Pg 8: TPageProducers
• Pg 9: Cookies made easy
• Pg 10: Stateless HTTP
• Pg 11: DB enabled apps
• Pg 12: FAQ
• Pg 13: DB apps - Part 1
• Pg 14: DB apps - Part 2

Printer friendly versionPrinter friendly version
 Join the Discussion
"Post your questions, concerns, views and comments to this article..."
Discuss!
 Related Resources
• Internet programming
• CGI and ISAPI with Delphi

Searching for a Record: The TQueryTableProducer

There are dozens of ways you could go about doing this. I'm not referring to the actual searching, but more in the way in which you return the result. To be quite honest I never or hardly ever used the TQueryTableProducer or the TDataSetTableProducer. But since they are on the Palette and as I've seen on the Newsgroups, a lot of people do use them, I've decided to experiment a bit and try them out.

The QueryTableProducer does exactly that. It returns an HTML table based on the query. It doesn't only save us the trouble of wiring the html code to generate a table and loop through the records returned, but it also automatically reads the parameters the query is based on from the request. This parameters can be either QueryFields in a GET or ContentFields in a post. They most coincide with the same name as the parameters given in the Query.

If you look at the source code you will see that I have placed a specific TQuery component with the following sentence:

SELECT * FROM CLIENT WHERE CLIENT_NAME CONTAINING :CLIENT_NAME

The reason I am using CONTAINING instead of = is because for illustration purposes I want the result to be a little less exact so that it returns more than one record in a query. Now take a look at the search.htm page. It's a simple HTML form with a field name CLIENT_NAME and it uses the POST method. We next drop a TQueryTableProducer on the web-module and assign it's dataset property quSEARCH (our TQuery). Next, if you double-click on the component (qtpSEARCH), the component editor will appear where you can add the database fields of the query as columns of the page and other fields if you want. We actually use an additional field that contains a checkbox which will allow us to delete the selected records. What follows is just simple property settings to make it look half decent. Once that is done, we next add the following line of code:

if Request.QueryFields.Values['target']=
   'searchrecord' then begin
  Response.Content := qtpSEARCH.Content ; 
  quSEARCH.Close; 
  sResult := 'DONE'; 
end

Notice how I do a close of the query after calling the Content method. This is because as I've mentioned, once a request is serviced, the web-module remains in memory waiting for other request (CacheConnections = True). If we didn't close the query after calling the Content method, the next request would just call Content and not refresh the query with the new parameters of the request.

Next, we'll take a look at the OnFormatCell event of the TQueryTableProducer. This event gets fired for every cell. We are going to use this event to add a link to the ID of the client so as the user can click on it to consult and/or modify the record. We will also add a checkbox in the last column of the table so we can use it do delete the record. The first check is to see if we are not in the Title row (CellRow >0). If not, we then add certain data depending on the row we are in. If it is the Client_id column, we add a link to call the action?target=consultrecord&client_id=XXX. This will call the action ConsultRecord given the parameter client_id. The other column adds a checkbox with name 'DEL' + Client_id. We'll see how to make use of this in the next section.

One last thing: Take a look at the header and footer properties of the qtpSEARCH component. I have added the necessary html tags to incorporate a form so we can process the values returned by the checkboxes.

Consulting and modifying a record: The TDataSetPageProducer

Up to this point, we have an action that returns a list of records in an HTML table with a link to consult/modify the record and a checkbox to delete the record. In this section will see how to modify and consult the record. The call to "consultrecord" is basically the same as the previous action. The difference here is that we use a TDataSetPageProducer as the response. This component is used to produce the values of a record in the dataset. What it does is replace all the tags in an html page that have the same name as a field in the dataset with their values. If you take a look at the modify.htm file you will see how I used <#FIELD_NAME> tags to fill in the edit boxes with the current value of the record. Certain fields might need additional processing such as memo fields or checkbox fields, drop-down lists, etc. All this processing can be done in the OnHTMLTag event.

So, this action retrieves the information from the database based on the value passed in the query and produces the modify.htm page as the result, filling in the appropriate values. This page is contained in a form. By clicking on the Modify button you can modify the record with the current contents. This is performed by the "modifyrecord" target of the Action event. This event is very similar to AddRecord.

Deleting records
As we saw in the search section, I added a checkbox so the user can select the records to delete. When you submit a form that contains a checkbox, if the checkbox is ticked, a corresponding ContentField is available with the value of the checkbox. If it is not ticked then the ContentFields is not present. I make use of this feature to construct and SQL sentence with the records needed to delete. I loop through the ContentFields and see if any of have DEL in them. If so, I subtract the record number and construct the SQL sentence. Executing this sentence will delete the corresponding records. Of course, this method is not foolproof if you have other fields beginning with DEL or containing DEL but it allows me to show you how you can do something similar.

CONCLUSION
Well, that's about it! This is the last chapter of this tutorial (until I expand it). I hope it has been useful and will allow you to get started on Internet programming with Delphi. It's now 6 am and I have to get up in two hours for work, so I'm going to stop here!

Good luck and PLEASE send me your feedback!

First page > A brief introduction to web-broker technology > Page 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

All graphics (if any) in this feature created by Zarko Gajic.

 More Delphi
· Learn another routine every day - RTL Quick Reference.
· Download free source code applications and components.
· Talk about Delphi Programming, real time.
· Link to the Delphi Programming site from your Web pages.
· Tutorials, articles, tech. tips by date: 2001|2000|1999|1998 or by TOPIC.
· NEXT ARTICLE: ADO Cursors - DB/10.
Chapter ten of the free Delphi Database Course for beginners. How ADO uses cursors as a storage and access mechanism, and what you should do to choose the best cursor for your Delphi ADO application.
 Stay informed with all new and interesting things about Delphi (for free).
Subscribe to the Newsletter
Name
Email

 Got some code to share? Got a question? Need some help?

Explore Delphi Programming

About.com Special Features

Build Your Own Website

Step-by-step advice on how to do everything from choosing a Web host to promoting your content. More >

Connect Your Home Computers

Easy ways to connect two computers for networking purposes. More >

Delphi Programming

  1. Home
  2. Computing & Technology
  3. Delphi Programming

©2009 About.com, a part of The New York Times Company.

All rights reserved.