Update Forms without IC's Classes
Posted March 1 1999
(Author's Note: This article examines calling update forms in Internet Connect using HTML and Javascript. Vince Russo, in another article in this issue, shows you how to use the IC classes to call forms while staying within a single application.)NOTE: Clarion Magazine was not able to obtain an archive of the original source code for this article. If you have the source, we'd very much appreciate it if you would email it to us so we can post it for other readers.
Adding, changing and deleting records using Internet Connect presents no special problems. "No special problems," that is, until you decide to use HTML to present lists.
The problem is not with adding new records but editing or deleting existing records. This is not an IC-specific issue but is due to the way Clarion browses work.
Clarion depends on a relationship between the disk file, a view, a queue and the browse. Update and delete depend on a browse box row being highlighted, selected. The code retrieves the underlying queue record and from that can access the view and file records.
Because inserting a record does not require an accurate record buffer (even though the templates do update the buffer before calling a form), the standard Insert button should (and does) continue working with HTML lists. But editing and deleting do require the buffer be accurate and this is just what using HTML makes impossible. That is, when we use HTML to display lists instead of the built in classes, there is no way to select a single line and, therefore, select a record and update the file buffer. Immediately, update and delete will fail to effect the correct record.
WebHtmlListClass
By default, a browse is implemented using the WebJavaListClass. But you may override this with WebHtmlListClass to create a Java-free list box (see "Decaffeinating Forms and Browses," Clarion Online, 2, 1, August 1998 for a full discussion of this technique).(Editor's Note: If you do not have access to that particular back issue, simply call Jeff at COL's toll-free number, (888) 675-9477 and he will be glad to provide you with a copy of that article.)Because the standard browse box (or, at least, its first column) is still used, the synchronization of browse box to its underlying queue is maintained. Therefore, all standard buttons can and do work as expected.
In this scenario, your list is created as an HTML <select>. If the functionalities and aesthetics of an HTML <select> meet your needs, you don't need to consider other Java-free techniques.
The Web-ish Look and Feel
To get the look and feel of other Web application, lists cannot be presented using browse boxes. Instead we have to use HTML <table>s.This can be done by using the built in LOOP Clarion uses to fill the browse queue (see "The Best of Both Worlds," Clarion Online, 2, 7, February 1999 for a full discussion of this subject). It can also be done by hand coding a LOOP (see "Dual-Dual-Mode Apps," Clarion Online, 2, 4, November 1998 and "Dual-Hybrid Apps - The Details," Clarion Online, 2, 6, January 1999). In either case, however, the displayed <table> cannot be synchronized to the underlying queue (if a queue is used at all) much less the file. If you use the built in LOOP or create your own queue, only the first record in the queue will be accessible (this record will change as you page through the queue). If you work directly from the file, only the first record will be available for editing.
Not exactly what we want or users expect.
The Alternatives
The word "alternatives" implies that there are two or more things to choose between. Therefore, the phrase "only alternative" is nonsense in the pure sense of "does not make sense."At its foundation, if you use an HTML <table> to present a list, the "only alternative" is to hand code a hypertext (HTTP) link.
Your alternatives are in the kind of link you decide to code.
Here, you do have some real choices ... two to be precise:
- emulate the call made by the templates
- use standard HTML techniques
Using standard HTML techniques, you again have exactly two alternatives:
- you may open your form in the same browser window
- you may open a second browser window
- straight HTML
- Javascript (in varying degrees)
Assume the following file structure:
Files
FILE,DRIVER('TOPSPEED'),PRE(FIL),BINDABLE,CREATE,THREAD
DateKey KEY(-FIL:FileDate),DUP,NOCASE,OPT
ID_Key KEY(FIL:ID),NOCASE,OPT,PRIMARY
Record RECORD,PRE()
ID LONG
Description STRING(50) ß
Author STRING(20) ß
URLPath STRING(80)
FileName STRING(20)
FileType STRING(5)
FileDate LONG ß
Category STRING(20)
END
END
To create an HTML <table> displaying the file date,
description and author, we would use code like:
Listing 1
Set(FIL:ID_Key)
Loop Until Access:Files.Next()
DisplayString = Clip(DisplayString) & ('<<tr>')
DisplayString = Clip(DisplayString) & ('<<td width="15%">' &|
Format(FIL:FILEDATE,@D8) & '<</td>')
* DisplayString = Clip(DisplayString) & ('<<td width="55%">' &|
Clip(FIL:Description) & '</td>')
DisplayString = Clip(DisplayString) & ('<<td width="30%">' &|
Clip(FIL:Author) & '<</td>')
DisplayString = Clip(DisplayString) & ('<</tr>')
End
Straight HTML
To turn FIL:DESCRIPTION into a hypertext link:
Listing 2
* DisplayString = Clip(DisplayString) & ('<<td width="55%">' &|
'<<a href="http://' & Clip(FIL:URLPath) &|
Clip(FIL:FileName) & Clip(FIL:FileType)'">'&|
Clip(FIL:Description) & '<</a><</td>')
This demonstrates constructing a hypertext link from file fields.
In this case, the called page will appear in the same browser
window as the calling page. This is no different than your visiting
a site and jumping to another.
In the file spec, FIL:ID is a unique key value. So, the above code can be modified to call a second IC app accessing that record as follows:
Listing 3
* DisplayString = Clip(DisplayString) & ('<<td width="55%">' &|
'<<a href="http://FormApp?' & FIL:ID &|
'">'& Clip(FIL:Description) & '<</a><</td>')
In the receiving app, you would capture the parameter and retrieve
the record (details below).
This means that the user can use the browser's back and forward keys to navigate between the two apps (something not normally supported in IC applications). However, it also means that the original app and the called app are both running on the server. And, if the second is a Form, there is no way to move from the second to the first while saving the record (except by a timeout).
A slight modification of this code will cause the second app to open a new browser window:
Listing 4
* DisplayString = Clip(DisplayString) & ('<<td width="55%">' &|
'<<a href="http://FormApp?' & FIL:ID &|
'">'& Clip(FIL:Description) &|
'<</a target="_blank"><</td>')
which may be more visually appealing but is not supported in all
browsers.
Your call.
Javascript
- (My thanks to Troy Sorzano who originally provided the script on which this discussion is based.)
First, you can provide a Status Bar to describe the link (i.e., hide the URL). Second, you can control whether a second window, if used, has various features such as scroll bars, tool bars, etc.
To open in the same window, the following Javascript skeleton can be adapted:
<a href="http://localhost" onmouseover="self.status='download now'; return true">Go there now</a>
Just substitute the page or application you actually want to call for "localhost," what you want to show in the Status Bar for "download now" and your file field or literal for "Go there now."
To use a second window, adapt:
<a HREF="JavaScript:void(0)" onClick="window.open('http://localhost','','toolbar=no,|
directories=no,captionbar=no,|
status=yes,menubar=no,scrollbars=yes,location=no,width=550,height=400,resizable=yes');|
" onmouseover="self.status='Check it out.'; return true ">Go there now</a>
(Note: line continuation does not work when dynamically
creating these scripts. They should all be on one line.)
Since large portions of each script will be re-used, it is probably wise to break each script into a series of segments or blocks and simply hardcode them into local variables. This makes your code much easier to follow (in the actual code, this is a single line):
DisplayString = Clip(DisplayString) & ('<<td width="60%">' & SEG1 &|
Clip(FQ:URLPath) & Clip(FQ:FileName) & Clip(FQ:FileType) & SEG2 & Clip(FQ:Description) & SEG3)
The Form
This part of the discussion is based on the accompanying app. While normally bad practice, there is no unique key. The app would be called with something like:http://domain_name.EXT/cws/cwlaunch.dll/formapp.exe?NAM:LastName+NAM:FirstNameThere are two things a Form must be told so that it can function as desired.
First, the Form must know the requested action: add, change or delete. Second, if called to edit or delete a record, it must know which record is to be updated or deleted.
We are talking about here is calling a Form procedure as a stand-alone application (see "Calling Form Procedures, Clarion Online, 1, 9, April 1998 for a fuller discussion of the underlying issues). Therefore we have to handle communication of both of these items to the Form.
To make a very long story short, we can handle both in one go. To effect this relies on the Internet Builder Class property, COMMANDLINE.
You can capture COMMANDLINE in the Program Setup embed. However, in this case the Form's INIT embed (before "Snap-shot GlobalRequest") gives greater flexibility:
pPassedName = WebServer.CommandLine
If pPassedName = ''
GlobalRequest = InsertRecord
Else
GlobalRequest = ChangeRecord
pos = Instring('+',pPassedName )
NAM:LastName = pPassedName[1 : pos - 1]
NAM:FirstName = pPassedName[pos + 1 : Len(pPassedName)]
End
Of course, priming the key values directly into the buffer, as
shown, only works in the form's INIT procedure. If you use the
Program Setup embed, you will need variables to hold the results of
parsing the command line. That is why I think INIT is to be
preferred for this purpose.
Then, in the Form procedure, after the files are opened:
If pPassedName Access:NAMES.Fetch(NAM:NameKey) EndThis snippet does not handle deletes, but does handle adding and editing records.
How does this code work? If the app is called with no parameter or with a blank parameter, GlobalRequest is set to InsertRecord. Otherwise, the intended action must be to edit the record. In that case, parse the parameter string and prime the key values. Finally, retrieve the referenced record. (Of course, this sort of strategy works better if you pass a unique key value.)
You will quickly discover that you want to open the form in a second window. How do I know what you want?-When the form procedure terminates, you are left facing the "app is no longer running" page and you have to press back page ... several times.
Nope, ain't gonna' work.
You will also probably want to point your "Page To Return To" at a page that will close the second window also (using a simple piece of Javascript). For example,
<html> <head></head> <body> <script language="Javascript"> document.close() </script> </body> </html>
Uses for this technique
Other than getting a handle on how IC works and using command line parameters in IC, calling forms in this way surely seems ... clumsy. Perhaps with a second window, in a different size (to graphically show what is happening) and automated closing of that second window, it would be a bit more elegant.There is, however, at least one scenario where I think this should be the technique of choice.
When the called page is a standalone external file, this way of calling "forms" (actually, more like "view" procedures) works very nicely. The CWICWEB download site, http://www.cwicweb.com/apps/cwlaunch.dll/download.exe.0, is a good example.
By presenting HTML or download confirmations in a second window, the user is given the option of reading a page at leisure (there is no timeout on straight HTML and there are no server resources committed). But the user is visually reminded that a base application is still running because it is still visible (in this case, Clarion developers are the users and, unfortunately, they - you - still let the app run until it times out, visual indication notwithstanding; so much for that theory). File downloads can take place in a second window while the user continues to browse the file and article list.
In general, the rule appears to be that when the target is an external file and the browser knows what to do with it, using standard HTML techniques works quite smoothly. The file (MIME) types that a browser can handle without further instructions include .HTM, .HTML, .PDF (usually), .ZIP, .EXE and standard image files. So, HTML and Adobe files can be read without having to hack the IC classes and images can be viewed. Most other file extensions (i.e., files that the browser does not have associations for) will prompt for saving to disk. Neat.
If the FAQs I've been collecting were in separate HTML or text files, I wouldn't hesitate to use this method.
I suppose there are other cases where this might be the presentation method of choice, but these are pretty obvious.
Summary
For several years, Clarion has supported multi-language programming. Most often we use this capability for Windows' API calls (C/C++).However, the more I work with Internet Connect, the more clear it becomes that you simply can't produce a decent IC app without HTML (a scripting language counts as a language, doesn't it?) and the baggage that can accompany it (viz., Javascript).
It is not that your apps will fail to work without HTML and/or Javascript. It's that so many facilities are made available through the ability to embed HTML, so many new ways of doing things and so many new things that can be done, calling forms is but the latest example.
Article comments
Search ClarionMag
From the archives
A Callback Technique for Capesoft's FileManager2
12/21/2006 12:00:00 AM
CapeSoft's FileManager2, and its more recent incarnation FileManager3, are amazing products: they completely automate the process of upgrading client databases, whether local or across a network, and make it easy to do file maintenance. Randy Rogers shows how to add a callback procedure to FM2 to provide user feedback during startup.

Steve
Parker started his professional life as a Philosopher but now tries to imitate
a Clarion developer. He has been attempting to subdue Clarion since version 2007 (DOS,
that is). He reports that, so far, Clarion is winning. Steve has been writing
about Clarion since 1993.