Most importantly we need the PK for each developer. But in order to make this method more flexible we can pass a parameter that's a field list on the fields to return. In order to get our cursor nicely formatted for wwShowCursor() we'll need to post parse the data with a secondary SQL statement. Let's start by fixing the DeveloperList method:
LPARAMETERS lcCountry, lcFields, lnMode
IF EMPTY(lcCountry)
lcCountry = "United States"
ENDIF
IF EMPTY(lcFields)
lcFields = "company,name,state,City,Country,pk"
ENDIF
RETURN THIS.Query("SELECT " + lcFields + ;
"WHERE country like '" + lcCountry +"%' " + ;
"ORDER BY State,City,Company","TDevelopers",lnMode)Now we can return fields more cleanly for our queries with a typical default. Note that the original code in DevProcess::ShowDeveloper still works without any changes because the default parameters provide the data just fine.
The next step for us is to add the ability to display and edit developer records. In order to do this and still use wwShowCursor we'll need to post process the SQL statement to create the hyper links as part of the Company field:
loDev = CREATEOBJECT("cDeveloper")
lnCount = loDev.DeveloperList(lcCountry,"Company,Name,State,City,Country,pk")
*** Fixup the SQL statement
SELECT [<a href="Showdeveloper.dp?Id=] + TRANSFORM(pk) + [">] + Company + [</a>] as Company, ;
Name as Contact, State, City, Country ;
FROM TDevelopers ;
INTO CURSOR TQuery
We now have links:
To handle the links we need to create a new method called ShowDeveloper. What we'll do here is load a customer business object using the PK we embedded into the link and then use an external template page to display the developer information.
The ShowDeveloper method has next to no code because the HTML display is handled externally:
FUNCTION ShowDeveloper()
lnPk = VAL(Request.QueryString("ID"))
loDev = CREATEOBJECT("cDeveloper")
IF !loDev.Load(lnPK)
THIS.ErrorMsg("Invalid Developer",loDev.cErrorMsg)
RETURN
ENDIF
poDev = loDev.oData
*** Load ShowDeveloper.dp page
Response.ExpandTemplate(Request.GetPhysicalPath())
RETURNThe wwBusiness object base class loads an oData member with the data from the underlying table. In the code above you can reference the company with loDev.oData.Company for example. poDev is assigned for easier reference (and slightly faster operation) when displaying these fields inside of the template.
The template page is ShowDeveloper.dp which is maintained with FrontPage and looks like this:
The HTML inside of this document contains embedded ASP like tags that reference the poDev object. For example:
<tr>
<td width="131" valign="top" bgcolor="#00008B" align="right">
<font color="#FFFFFF"><b>Web Site:</b></font></td>
<td valign="top" width="453"><a href="<%= iif(lower(poDev.WebSite) # "http://","http://","") + TRIM( poDev.WebSite) %>">
<%= poDev.WebSite %></a> </td>
</tr>
<tr>
<td width="131" valign="top" bgcolor="#00008B" align="right">
<font color="#FFFFFF"><b>Services
offered:</b></font></td>
<td valign="top" width="453">
<%= IIF(poDev.Dev=1,"<img src='images/checkbox.gif'>Development ","") %>
<%= IIF(poDev.Training=1,"<img src='images/checkbox.gif'>Training ","") %>
<%= IIF(poDev.Support=1,"<img src='images/checkbox.gif'>Support ","") %>
<hr>
<%= DisplayMemo(poDev.Services) %> </td>
</tr>
Note that we're using VFP functions here as well as using the properties of the poDev object reference to our fields. loDev is also available in this page - you could call a method of the business object if that would make sense.
BTW, I actually created the table used here with wwShowCursor, captured the string to the clipboard and pasted it into this page. I then went through the field values and replaced them with the ASP tags of the object to replace the values. This is a quick way to pre-create content and then fix it up with a few table formatting options to make it look nicer and add in the dynamic data.
When we run this form now by clicking in the ShowDevelopers list on any company we'll see:
Look how little code it's taken to write all of this to this point. Using the business object keeps the Web Connection code really minimal. For the lookup code here we didn't even have to write any data access code because the business object provided us the services to retrieve the object. And once the object is loaded we can immediately plug it into the page.