Chapter Seven - PixieWeb Documentation:
Building Field-by-Field Web Applications
This method for building web apps closely links Host-Server programs to user-interaction when in a field-by-field conversation. The user interface is ONE and ONLY ONE web page which rewrites its internal contents as the PICK program runs. This removes the security and programming problems arising from too much user freedom to hop from page to page.
Coding Conventions Used in This Document
XDL and IFRAME transmission methodsField-By-Field Conversation - basic guidelines
Scripts involved At Start-up
Page container - For Multiple Screen Displays (e.g. Tabbars)
Definition of terms "Request", "Response", "MV TX", "IE TX"PixieWeb Keywords by meaning.
MV transmission format.
IE transmission format.
App shutdown: ERROR, EXIT
Screen regions: IREPLACE, INSERT, DISPLAY
Dialogs: MSGBOX, INPUTBOX, MODALBOX, STATUS, STATUSCUSTOM
Fields: VALUE, FOCUS, ENABLED, VALID, REJECT, READONLY, X, Y, W, DISABLED
Grids: GROWNEW, GROWDEL, GROWINS
LIST, LISTM
CACHE, CACHERETRIEVE, CACHERESETGeneration
Labels
Fields
Grids
Coding Conventions Used in This Document – generic value-by-description
In documents of this nature, it
is common to represent descriptions of values by enclosing them in angle
brackets. eg <html code>, <table data> But because some literals use
angle brackets as custom markup language device, such generic terms will here be
presented with an ellipsis-parenthesis format
eg
IREPLACE|doc=...(html code)...
eg – a literal for
comparison (reply to yesno dialog)
ax2|<yes>
An overview of the operational flow of control for field-by-field processing is outlined in the following diagram.
Front-end Component Descriptions
XML Download Behaviour transport method
All conversations consist of strings passed between the IE client and MV
programs.
In the early stages of login negotiation, the WebServer launching script "MyApp.asp"
(an example script supplied with Pixieweb) may intercept these strings and act on them, but once the framework page
"XDLTemplate.htm" is launched, strings are passed directly to MV programs via
"XDLPixie.asp". Both XDLTemplate.htm and XDLPixie.asp are provided
with PixieWeb.
With IE5, we are using the "XML Download Behaviour" as the
transport mechanism. This is an object which can download pages independently of
the page currently displaying. We point it at the "page" XDLPixie.asp
which is a program for text-command-generation
and passthrough-commands-from-MV-via-PixieWeb.
IFRAME Alternative Transport Methods (e.g. for Netscape 6)
The "XML Download Behaviour" is the simplest and fastest of the 3 "on-the-fly" options we have tested, but it is only available in IE5 and above. At the time of writing, June 2001, we have promising trials going with Netscape6 using an array of IFRAMEs as an alternative on-the-fly communications method. This requires an internal change to one on-page routine "ExecuteA". In use, the protocol should work exactly as outlined below with the only change being use of a different pair of standard webserver files: named "IFRPixie.asp" and "IFRTemplate.htm" instead of "XDLPixie.asp" and "XDLTemplate.htm"Format of Keyword Commands
This covers the 2-way Transport of the Keyword Commands and the Data as text strings.
String Separators are:
1.
"^"(caret), separator between multiple commands in one transmission2.
"|" (pipe), KEYWORD|data separator3.
"\" (backslash) subvalue-type separator for data4.
"~" (tilde) sub-sub-value separator for data.For example: SC := "^READONLY|gx8x":I:"x1=":IREC<1> which illustrates the use of the ^ and the |, using the keyword READONLY.
Page Container - For Multiple Screen Display (e.g. Tabbars)
Example 2 on our website gets a tab-panel effect by having its body divided
into 4 divs called "doc1", "doc2", "doc3", "doc4".
One of these at a time is shown by sending commands like this from UNIVERSE:
DISPLAY|doc3=block^DISPLAY|doc2=none
This switches from requisition entry (doc2) to requisition approval (doc3).
This approach suits smaller apps where the basic design can be "hard coded"
into the doc divs in XDLTemplate.htm and the MV Server's job is to make minor changes
as it runs.
Larger apps (e.g. at "MarCom" by Mike Hiatt), where there are many screen designs, can benefit from a simpler XDLTemplate with only one master document display area, a master div with id="doc". Major changes in screen interface (e.g. from a menu to a program group) are done by complete "doc" rewrites via command "IREPLACE|doc1=....".
Within a suite of programs, this doc remains unchanged so that its first child, a "tabbar" = a top row of clickable divs or buttons called "tx1", "tx2" etc can signal the server to rewrite the second child, a div called "page"
The tab panels can be loaded from MV with
..^IREPLACE|page= ...(html)...Pages can be cached with the CACHE keyword, or RETRIEVED to the "page" display with the CACHERETRIEVE statement.
Within each screen design, individual elements can be dynamically altered with commands such as VALUE, REJECT, GROWNEW. These are the basis of running a closely linked front end under the control of the server free of the old Web limitation of complete page rewrites at each conversation step.
Field-By-Field Conversation - Basic Guidelines
Definition of terms "Request", "Response", "MV TX", "IE TX"
All conversations via a webserver must follow this strict format:
A - B – A – B – A – B ... where A is the IE client request and B is the MV response.
Commonsense however suggests that the role of "request" and "response" can swap by means of either side sending a conversation placeholder, usually "OK".
In this document:
"IE TX" is the term for IE(client) transmissions,
nearly always user input.
"MV TX" is the term for MV(server) transmissions.
"Request" refers to an action requesting on-screen
advancement of the conversation. Most of these come from IE as user
input resulting in MV advancing the display. But MV may request further user input by
means of dialog boxes or popups.
"Response" is data sent as the step following a request.
So in this discussion, the terms "Request" and "Response" take their human rather than
strictly technical meaning. "IE TX" and "MV TX" are our playscript tags used to describe the 2 actors
in this machine conversation.
KEYWORD|argument KEYWORD|argument1\argument2[\..] KEYWORD|object=value
Eg
KEYWORD|argument MSGBOX|This widget is not for breeding
KEYWORD|argument1\argument2 MSGBOX|This widget is pregnant!\vbExclamation MSGBOX|Do you want to reclassify this widget\vbQuestion+vbYesNo LISTM|cat\dog\aardvark\mouse\horse\pig\bear
KEYWORD|object=value
FOCUS|fx4 Focus on field fx4 with no effect on displayed
value
FOCUS|fx4=
Focus on field fx4 and set its value to
""
FOCUS|fx4=John
Focus on field fx4 and set its value to "John"
You can invent your own keywords by extending the SELECT CASE code
in XDLTemplate.htm: Sub ResponseAnalyse
object|value eg
"fx4|Michael Smith"
object|<keyword_value>
eg
"gx10x7x3|<insert>"
A user action may not have an obvious on-screen object to relate to,
eg when user presses Esc, F2, Fn key in a particular context,
a "dummy" object identifier may be used eg "ax1", "ax2"
|
ax1 |
Escape/Exit |
|
ax2 |
User selection from MSGBOX dialog: ax2|<no> ax2|<retry> |
|
ax3 |
User selection from LIST custom dialog |
|
ax4 |
User selection from LISTM custom dialog |
|
ax5 |
User entry into INPUTBOX |
Keywords by meaning
App shutdown: ERROR, EXIT
Any MV TX or Webserver Response starting with ERROR is a signal to IE
to immediately carry out an emergency App Shutdown.
For that reason, for non-fatal error reporting as the app runs,
do NOT use the ERROR keyword, instead use MSGBOX, INPUTBOX, MODALBOX, REJECT.
EXIT is a MV TX for intended shutdown of the App, and will cause IE to make a smooth shutdown with a minimum of dialogs.
EXIT|<disconnect>
.. gives immediate shutdown with the App window closing
EXIT|...(html code) ...
..gives shutdown with the App window still existing and displaying HTML or text following the pipe. This may be useful when you want to display a menu of links or actions on App End.
Replace div contents
IREPLACE|doc=...(html code)...
Append to div contents
INSERT|doc=...(html code)..
Make div appear/disappear
DISPLAY|divtab=True
DISPLAY|divtab=False
Dialogs:
MSGBOX, INPUTBOX, MODALBOX, STATUS, STATUSCUSTOM
Vanilla with confirmation signal back to PICK
Error alert without confirmation
Error alert with confirmation
Exclamation without confirmation
Exclamation with confirmation
YesNo
OKCancel, AbortRetryIgnore etc,
|
Constant |
Value |
Description |
IE TX response |
|
vbOK |
1 |
OK |
ax2|<ok> |
|
vbCancel |
2 |
Cancel |
ax2|<cancel> |
|
vbAbort |
3 |
Abort |
ax2|<abort> |
|
vbRetry |
4 |
Retry |
ax2|<retry> |
|
vbIgnore |
5 |
Ignore |
ax2|<ignore> |
|
vbYes |
6 |
Yes |
ax2|<yes> |
|
vbNo |
7 |
No |
ax2|<no> |
The possible combinations of buttons and icons are:
|
Constant |
Value |
Description |
|
vbOKOnly |
0 |
Display OK button only. |
|
vbOKCancel |
1 |
Display OK and Cancel buttons. |
|
vbAbortRetryIgnore |
2 |
Display Abort, Retry, and Ignore buttons. |
|
vbYesNoCancel |
3 |
Display Yes, No, and Cancel buttons. |
|
vbYesNo |
4 |
Display Yes and No buttons. |
|
vbRetryCancel |
5 |
Display Retry and Cancel buttons. |
|
vbCritical |
16 |
Display Critical Message icon. |
|
vbQuestion |
32 |
Display Warning Query icon. |
|
vbExclamation |
48 |
Display Warning Message icon. |
|
vbInformation |
64 |
Display Information Message icon. |
|
vbDefaultButton1 |
0 |
First button is default. |
|
vbDefaultButton2 |
256 |
Second button is default. |
|
vbDefaultButton3 |
512 |
Third button is default. |
|
vbDefaultButton4 |
768 |
Fourth button is default. |
|
vbApplicationModal |
0 |
Application modal; the user must respond to the message box before continuing work in the current application. |
|
vbSystemModal |
4096 |
System modal; all applications are suspended until the user responds to the message box. |
|
vbMsgBoxHelpButton |
16384 |
Adds Help button to the message box |
|
VbMsgBoxSetForeground |
65536 |
Specifies the message box window as the foreground window |
|
vbMsgBoxRight |
524288 |
Text is right aligned |
|
vbMsgBoxRtlReading |
1048576 |
Specifies text should read as right-to-left on Hebrew,Arabic systems |
The numbers are added to produce the "recipe"
eg vbRetryCancel+vbExclamation
Enables MV TX to request free-form user input via dialog box independent of interface design.
MV TX
IE TX
Generate the dialog from scratch from the server-side.
The modalbox is a blank HTML dialog which you fill in with any display you like.
The rule: it can only accept one user action because it closes itself on reporting that action back to MV.
In practice, this means that it is mainly of use for arrays of buttons, and maybe selections off lists.
We provide an example MODALBOX template with a VBSCRIPT
Sub Dprocess. To use it, any active input object must include this event fragment script:onClick=JSCRIPT:DProcess(this);
eg For a custom set of dialog buttons: (View this example - click here)
MODALBOX|<p>The quick brown
(what ?) jumps over the lazy dog?</p>
<p><input type=button id=dx1 class=button3
onClick="JSCRIPT:DProcess(this);" value="Hen">
<input type=button id=dx2 class=button3
onClick="JSCRIPT:DProcess(this);" value="Fox">
<input type=button id=dx3 class=button3
onClick="JSCRIPT:DProcess(this);" value="Rabbit">
<input type=button id=dx4 class=button3
onClick="JSCRIPT:DProcess(this);" value="Badger">
</p>
When the user selects "Fox", the IE TX response is:
dx2|Fox
On the user closing the MODALBOX with no input, the IE TX is:
dx0|
For compatibility with this, any "Cancel" button should have
id=dx0MODALBOX has very good potential for extensive customisation.
STATUS|...(text_to_display)...
STATUSCUSTOM|...(text_to_display)...
Fields:
VALUE, FOCUS, ENABLED, VALID, REJECT,
READONLY ,DISABLED
Fields can be referred to as
<current> and <previous> as well as by literal id.VALUE|fx3= clears value of fx3
VALUE|fx3=John sets value of fx3 to "John"
The others, FOCUS, ENABLED etc are variations on VALUE, adding other property changes.
Default behaviour
is given here. Implementors can edit the VBSCRIPT
Sub ResponseAnalyse to
modify these.
Whether or not
to focus on a field is usually the biggest question, eg some of
you may find it useful to bundle focus with ENABLED.
Apart from the simple VALUE, the others have 3 variations: eg:
FOCUS|fx3
focus on fx3 with no change to contentsENABLED – assigns value the same as VALUE but also enables the field
if currently disabled.
ENABLED|fx3
enable fx3 without any effect on its valueREADONLY with synonym DISABLED – assigns value the same as VALUE but also disables the field if currently enabled.
DISABLED|fx3
disable fx3 without any effect on its valueVALID – assigns value the same as VALUE but can also
color the field (default = light green)
and also enables it if disabled.
VALID|fx3
color and enable fx3 without any effect on its valueREJECT – assigns value the same as VALUE but also
REJECT|<current>
– alert-color <current> and (OneStep) focus on it or (TwoStep) focus on <previous>REJECT|<previous>
- same as REJECT|<current> except that the alert-color will be applied to <previous>, no anticipated use but documented for completeness.REJECT|fx3=
- as above, also clears value of fx3
X, Y, W = alter field position or width, in equivalent character units:
eg
X|<current>=30^Y|<current>=10^W|<current>=17
We anticipate that this will be especially useful in the "multiple nominate" situation, ie when user input of 2 or more values is needed to uniquely identify the record to be edited. With this solution, there is only the one input field, "fx1", but it is moved from one label to another during the "nomination" phase of the program.
Grids: GROWNEW, GROWDEL, GROWINS,
To generate a grid (see details later), we need a parent container.
A Grid must have at least 1 row on first generation because the first row is used as the template for adding or inserting new rows.
Eg container id=gx8
Row id's are gx8x1, gx8x2, gx8x3 ...
Cell id's
gx8x1x1 gx8x1x2 gx8x1x3 gx8x1x4 gx8x1x5 gx8x1x6
gx8x2x1 gx8x2x2 gx8x2x3 gx8x2x4 gx8x2x5 gx8x2x6
gx8x3x1 gx8x3x2 gx8x3x3 gx8x3x4 gx8x3x5 gx8x3x6
gx8x4x1 gx8x4x2 gx8x4x3 gx8x4x4 gx8x4x5 gx8x4x6
Cells are input and other elements and have similar behaviour to their single value counterparts.VARs have used a variety of HTML interface techniques for users to request row inserts, and deletes. Eg: right-mouse-click, right-mouse-click with popups, F-Keys
Our own method and supplied default is to include 2 small command buttons labelled "i" and "d" at the start or end of the row. These would have ids of eg
Whichever interface you choose, Expect IE to transmit object id followed by the user's requested action in angle brackets, giving conversations like this:
IE: gx8x5|<insert>
MV: GROWINS|gx8x5
IE: gx8x5|<delete>
MV: GROWDEL|gx8x5
GROWINS and GROWDEL only analyse up to the third "x" so you can send insert and delete commands from any element in a row and your MV code can echo that id back and get the desired result. eg
"GROWINS|gx8x5", "GROWINS|gx8x5xi" and "GROWINS|gx8x5x3" are equally acceptable and all have the same effect.Example of handling of illegal user request
IE: gx5x4xi|<insert>
MV: MSGBOX|Cannot insert row until present entry is completed or cancelled.
It is quite operationally ok,although somewhat user-unfriendly, for MV to simply ignore IE user requests of this kind.
Generation of New Grid Rows
This process is controlled by MV issuing a new-object command in response to detected program conditions eg valid user data entry in the last row of a grid.
MV: GROWNEW|gx8
A custom popup list box is built into
XDLTemplate.htmeg
MV: LISTM|cat\dog\aardvark\fish\giraffe
(User selects "dog", "aardvark" and "giraffe")
IE:
ax4|2\3\5
LIST, LISTM are automatically centered by IE.
CACHE, CACHERETRIEVE, CACHERESET
These are supplied setup to act on a child div called
"page" rather than master "doc1" etc containers.
but remember that
XDLTemplate.htm is supplied as source code and the CACHE code is some of the easiest to customise..
CACHE -
Load current "page" into the
cache.
eg
CACHERETRIEVE|n - Retrieve
from cache into "page" and clear cache from position n
upwards
eg
CACHERESET - Clear out cache and set cache
pointer to 0
eg
example fields,containers, rows and columns.
Implemented as divs. Class and positioning required. Usually only style= ...LEFT ... TOP are required because divs are elastic. NOTE: spaces need to be escaped as " " to prevent unwanted word wrapping. We supply PICKBASIC SUBROUTINE WEBD5 to generate Labels.eg
<div style="LEFT: 0px; TOP: 0px" class=label1>MYAPP123</div>
<div style="LEFT: 270px; TOP: 0px" class= title1>Sales order detail</div>
Input field - order of attributes(optional attributes shown as [..])
<input [type] id class style events [disabled] [value] [title]>
eg
<input id=fx6 class=field1 style="LEFT:175px; WIDTH:130px; TOP:73px " onChange="JSCRIPT:EProcess(this);" disabled>
<input id=gx11x1x1 class=field1 style= "LEFT:24px;WIDTH:230px;TOP:0px" onChange= "JSCRIPT:EProcess(this);" onfocus= "JSCRIPT:GelSel(this);">
INPUT tag "Attributes" - the keyword= value pairs separated by spacesinput - the literal 'input'
[type] - eg ' type=button'. The most common ' type= text' is thedefault.
id
- eg ' id=fx4'. Single-value fields are named fx1, fx2, fx3
...
Grid containers are named with gx... eg gx12 , with the number being
where they come in the fieldorder.
NOTE: do NOT put id values in quote marks, eg id="fx4" < /FONT> because our string-parsing routines supplied in XDLTemplate.htm depend on the simpler layout of leaving them out.
class eg
class=field1
(standard left-justified, font size similar to what we work with on
terminals)
class=field2 -
right-justified, usually for numeric
data
class=button1 -
standard button with same font asfield1
style - LEFT, TOP, WIDTH are usually required.
The "
position: absolute" declaration is supplied by the class so you do not need to bulk up your transmissions with many repeats of it.events - all active input text input fields need to have:
onChange=JSCRIPT:EProcess(this);
For a button, this becomes:
onClick="JSCRIPT:EProcess(this);"
An additional "special" for text input fields only:
"TwoStep" fields where you can confirm navigation with your server before
permitting the user to change value:
onFocus="JSCRIPT:TwoStep(this);
Fields within grids gain a nice effect of
row-highlighting from this additional event:
onFocus="JSCRIPT:GelSel(this);
TwoStep fields within grids need both of the above
combined:
onFocus="JSCRIPT:GelSel(this);TwoStep(this);
Command Buttons for the custom MODALBOX require
'DProcess:
[disabled]
- string literal 'disabled=true' can be included in the generated code.
Many Appswill require this in most fields on first generation.
[value]
- eg value="John
Calder"< /FONT>
Displayed text in an input
field, or a button caption. Default is zero-length string ie empty field.
[title]
- also known as "tooltip". Help text to pop-up when user hovers the
mouse over the field.
eg title="Number of faulty widgets found at this
site"
Input field id's within a grid follow the pattern
g{object sequence number}x{row number}x{column number}
Example: A parent container with id=gx3
Rows are gx3x1, gx3x2, gx3x3 ..
row 1: gx3x1x1 gx3x1x2 gx3x1x3 gx3x1x4 gx3x1x5
row 2: gx3x2x1 gx3x2x2 gx3x2x3 gx3x2x4 gx3x2x5
row 3: gx3x3x1 gx3x3x2 gx3x3x3 gx3x3x4 gx3x3x5
Grid generation
G-Grids are container divs with Rows as children.
Rows are container divs with Input fields as children.
Such container divs become the x-y co-ordinate frame of reference for the positioning of their children.
Grid container:
<div ID=gx11 class=grid1 style="LEFT: 0px; WIDTH: 750px; TOP: 139px; HEIGHT: 200px">< /FONT>
Row – overall container div specification
<div id=gx11x1 class=gridrow1 style="WIDTH: 720px;TOP:0px;HEIGHT:38px" onClick= "JSCRIPT:GelSel(this);">< /FONT>
NOTE: the default HEIGHT is 22px, but more complex rows eg with note lines, can be built by extending the HEIGHT.
Inside the row, we first need to generate a div to display the row number.
<div class=label1 style="LEFT: 2px; WIDTH: 22px">1</div>< /FONT>
Then buttons for insert and delete
<input type=button id=gx11x1xi
class=button1 style="LEFT: 26px"
onClick="JSCRIPT:EProcess(this);"
onfocus="JSCRIPT:GelSel(this);" value= "i">< /FONT>
<input type=button id=gx11x1xd class=button1 style="LEFT: 35px" onClick="JSCRIPT:EProcess(this);" onfocus="JSCRIPT:GelSel(this);" value= "d">< /FONT>
We then generate the fields.
NOTE that all fields inside a grid require the script fragment:
onfocus="JSCRIPT:GelSel(this);"
..to cause the row being worked on to highlight when users tab or mouse there.
The first field will usually be a controlling field which means it may need additional script fragments eg as shown here for TwoStep :
<input id=gx11x1x1 class=field1
style="LEFT: 24px; WIDTH: 130px; TOP: 0px" onChange="JSCRIPT:EProcess(this);"This next example is a special case, an additional notes field positioned below gx11x1x1.
Note the use of "...TOP: 20px;..." rather than the default "..TOP: 0px;..."
<input id=gx11x1x10 class=field1 style="LEFT: 24px; TOP: 20px; WIDTH: 130px" onChange="JSCRIPT:EProcess(this);" onfocus="JSCRIPT:GelSel(this);">
Here is the pattern for most dependent fields, eg
gx11x1x2Note the attribute 'disabled' is usually part of their generation.
<input id=gx11x1x2 class=field1 style= "LEFT:166px; TOP:0px;WIDTH:20px" onChange= "JSCRIPT:EProcess(this);" onfocus="JSCRIPT:GelSel(this);" disabled= true>< /FONT>