| Sybernet SDK |
|---|
We will begin this discussion with a description of four stored procedures that allow you to create hyper-text links (anchor objects), forms, form elements, and image-buttons (real images that behave like buttons to submit a form). These procedures reside in SYBSYSTEMPROCS which makes them global to every database that references them. You do not need to qualify the database name when invoking them. In fact it is probably a good idea not to since the database context will change if you do.
The next section will describe how these procedures are put together and used in a real world example. It uses the background.gif image that contains a blue margin bar on the left with a white background on the right. A template that uses this background image is explained before we actually start adding buttons and fields.
If you are already familar with writing HTML (in particular forms and links), you should find it fairly easy to call a stored procedure to accomplish the same thing.
Input fields separate each item with NAME=VALUE pairs; for example, you may already be used to specifying something like this:
select '<INPUT TYPE="TEXT" NAME="ADDRESS" VALUE="' + @ADDRESS + '">'With these procedures the NAME part is a parameter name and the VALUE part is the value for that parameter. Its execution resembles the following:
exec sp_html_input @TYPE="TEXT", @NAME="ADDRESS", @VALUE=@ADDRESS
By using the SDK you can also eliminate a lot of redundant coding. The RADIO and CHECKBOX fields illustrate this nicely when you want to indicate whether or not the field is CHECKED. To do this in a stored procedure you would probably compare two strings for equality and append the CHECKED option when they are equal. The SDK will do this for you automatically.
The SDK is also JavaScript aware. With a single string parameter you can warn your users that clicking a particular button will cause a record to be deleted. This is convenient both for the user because the feed-back is immediate and for you because you do not need to handle a similar warning in your stored procedure.
The SDK also recognizes many of the standard Sybase datatypes such as INT and NUMERIC and will automatically validate that values entered in these fields are within an acceptable range; for example, a TINYINT must be a whole number between 0 and 255. Without this validation your stored procedure might generate an exception condition when that parameter was converted. And again, the validation occurs on the client side so the feed-back is immediate.
Though I haven't seen any harm as of yet, you will want to review the section on sp_html_form so that these functions are not included on multiple invocations of same, if for no other reason than to reduce the bandwith.
Version 2.22 also introduced the PICTURE tag. This feature is now used by the SDK to format numeric data when it is displayed on your browser. Numeric data may now be right-aligned (ALIGN), scaled to the correct number of decimal digits (SCALE), and displayed with commas (COMMAS) at the proper location.
MONEY, SMALLMONEY and DECIMAL were also added to the Sybernet SDK in version 2.22. In addition, you can now pass numeric data containing commas and they will be stripped and reedited before they are displayed on your form.
NAME specifies the name of the form object. NAME is optional, but if specified, it is used to reference a form and its form elements in JavaScript.
NAME is needed when calling sp_html_button and you are creating an "image button" so that procedure can determine which form is being submitted when a user clicks an image.
METHOD may be POST or GET. The default is POST if not specified.
ACTION is the name of the Sybernet CGI. This parameter is ignored since there is only one Sybernet CGI.
ENCTYPE determines the type of form data being submitted. The default is "application/x-www-form-urlencoded." Sybernet also allows you to specify "multipart/form-data." This ENCTYPE is required when submitting a file with TYPE="FILE".
onSubmit handles the onSubmit event handler. In this case you must supply the complete JavaScript syntax yourself, and that is its purpose.
TARGET optionally specifies the windowName to be used for output when this form is submitted. If not specified, output returns to the same window as the form.
PROCNAME corresponds to the Sybernet reserved word PROCEDURE. sp_html_form calls sp_html_input to create a hidden field when this value is not NULL. If omitted, you will need to call sp_html_input yourself to specify this value.
FORMAT corresponds to the Sybernet reserved word FORMAT. sp_html_form calls sp_html_input to create a hidden field when this value is not NULL.
FILTER corresponds to the Sybernet reserved word FILTER. sp_html_form calls sp_html_input to create a hidden field when this value is not NULL.
This parameter determines whether or not to invoke the JavaScript functions that are used to validate your input fields. If you use the Sybernet SDK to create more than one form on your HTML page, JAVASCRIPT should be explicitly assigned to FALSE on all but the first call. The default is TRUE.
Surprisingly, it doesn't hurt to invoke the JAVASCRIPT stored procedure multiple times because JavaScript reassigns the function names on each invocation; however, the extra invocations are wasteful at best.
exec sp_html_form
@NAME = "myForm"
, @METHOD = "post"
, @ACTION = "Sybernet.cgi"
, @PROCNAME = "sp_html_template"
, @FORMAT = "SUPPRESSED"
Since METHOD is optional and ACTION is ignored, the minimum needed to create the beginning
form tag (assuming the form is not named) would be accomplished with the following:
exec sp_html_form @PROCNAME = "sp_html_template"The next example simply creates the ending Form tag. The ending tag is created because no parameters were passed to this procedure.
exec sp_html_formIf you use the SDK to create more than one input form, then you will want to inhibit the inclusion of the JavaScript functions that validate your form fields.
exec sp_html_form
, @METHOD = "POST"
, @JAVASCRIPT = "FALSE"
Failure to do so will include these functions for each invocation; however,
although this does not create a problem for JavaScript, it does increase the
size of your HTML screen.
ALERT and CONFIRM are special names that are not normal items in this tag. ALERT and CONFIRM are automatically passed to the onClick event handler to display a JavaScript alert and confirm, respectively.
All of the parameters are optional just like in regular HTML . All parameters are varchars unless otherwise indicated.
TYPE is the type of input field. Type may be any of the standard HTML input types including TEXT, CHECKBOX, RADIO, HIDDEN, PASSWORD, BUTTON, RESET, and SUBMIT.
The Sybernet SDK also recognizes the following Sybase databatypes: CHAR, VARCHAR, TINYINT, SMALLINT, INT, NUMERIC, DECIMAL, DATETIME, SMALLDATETIME, MONEY, and and SMALLMONEY.
In addition, the following generic datatypes are also supported in the SDK: PHONE, SSN and TIME.
Internally, the Sybase datatypes are treated as TYPE=TEXT execept numeric and date fields are validated with JavaScript. For numeric fields this validation insures that these values are indeed numeric and are within the range supported by this datatype; for example, TINYINT must be an integral value between 0 and 255. Commas are also removed when the field is validated unless COMMAS=TRUE.
By default, date fields are converted to the form Month day, year; for example,
Dec 25, 1995. The current implementation uses built-in
JavaScript functions which automatically correct for invalid dates; for example,
a date of "12/32/1996" is converted to "Jan 1, 1997." You can control the
style of date formats with the STYLE parameter.
The PHONE and SSN datatypes remove non-numeric data when an onBlur event occurs. This allows the user to enter these values in any format while at the same time making sure that only numeric data is returned to your procedure. These datatypes also format the current value when an onFocus event occurs; for example, 4158595328 is expanded to (415)859-5328.
The TIME datatype converts time to a 24 hour clock value; for example, 2:15 pm is converted to 1415.
NAME is the name of this field. Remember that a recent change to Sybernet no longer requires that parameter names to Sybase stored procedures require the preceding at-sign.
NAME may also be the name of a column in a Sybase table. In this case TYPE, SIZE and MAXLENGTH are automatically determined. A fully qualified name may also include the name of the database and owner; for example, PDS.DBO.EMPPER.EMP_ID represents the column EMP_ID in table EMPPER owned by DBO in the database PDS; however, for efficieny sake, do not include the database name if you are already in that database.
VALUE is the default value of this field.
For numeric data, your VALUE parameter may contain gratutious commas. They will be stripped and reedited when your field is built.
CHECKED applies only to types of RADIO and CHECKBOX. Its value is compared to the value of the VALUE parameter and sets the CHECKED option when the two are equal.
To set CHECKED manually, simply pass the same value for CHECKED and VALUE.
SIZE is the size of this input field.
If SIZE is not specified and TYPE is a Sybase datatype, SIZE is determined by that datatype; for example, the SIZE of TINYINT will be 3 since the range of valid values are whole numbers between 0 and 255.
MAXLENGTH is the maximum number of characters that may be specified in this field. If not specified, the default is 255.
If MAXLENGTH is not specified and TYPE is a Sybase datatype, MAXLENGTH is determined by that datatype; for example, the MAXLENGTH of a TINYINT field will be 3 since the range of valid values are whole numbers between 0 and 255 .
ALERT calls the JavaScript function alert. The effect is an alert box with the message in this parameter, and the form is not submitted.
CONFIRM calls the JavaScript function confirm. This causes a warning or confirmation to be displayed that allows the user to cancel or allow the submit; for example, you may wish to warn them that a particular button is going to delete a record.
A blur event occurs when a select, text, or textarea field on a form loses focus. The onBlur event handler executes JavaScrapt code when a blur event occurs.
A change event occurs when a select, text, or textarea field loses focus and its value has been modified. The onChange event handler executes JavaScript code when a change event occurs.
The onChange event is where the SDK validates input fields. If specified, your onChange code occurs before any validation by the SDK.
onClick handles the onClick event handler. In this case you must supply the complete JavaScript syntax yourself, and that is its purpose.
onClick may be specified for buttons, radio buttons, checkboxes, submit buttons and reset buttons.
ALERT, CONFIRM and onClick are invoked in this order. ALERT will override CONFIRM and onClick. CONFIRM will override onClick if its result is FALSE.
A focus event occurs when a field receives input focus by tabbing with the keyboard or clicking with the mouse. Selecting within a field results in a select event, not a focus event. The onFocus event handler executes JavaScript code when a focus event occurs.
A select event occurs when a user selects some of the text within a text or textarea field. The onSelect event handler executes JavaScript code when a select event occurs.
If TYPE is a Sybase numeric field, minValue determines the minimum value allowed in this field. If minValue is not specified, the minimum value for that datatype is used instead; for example, the smallest value for a TINYINT is 0.
minValue is a string and can also be used to specify the minimum value allowed for char, varchar, datetime, and smalldatetime fields. In this case it is a good idea to provide a default value.
If TYPE is a Sybase numerc field, maxValue determines the maximum value allowed in this field. If maxValue is not specified, the maximum value for that datatype is used instead; for example, the largest value for a TINYINT is 255.
maxValue is a string and can also be used to specify the maximum value allowed for char, varchar, datetime, and smalldatetime fields.
ROWS applies only to TYPE=TEXTAREA and indicates the number of rows to be displayed.
COLS applies only to TYPE=TEXTAREA and indicates the number of columns to be displayed.
WRAP applies only to TYPE=TEXTAREA and indicates how text is wrapped when it is displayed and edited. NOWARP means no wrapping occurs. VIRTUAL means text wraps automatically to fit the textarea's window. PHYSICAL is similar to VIRTUAL except that carriage returns are physically inserted in the text at the end of each line.
STYLE allows you to control the format for datetime and smalldatetime types and corresponds to the same in Sybase. Since date validations are done by JavaScript, some styles recognized by Sybase may not be recognized in JavaScript.
In Sybase, the STYLE 8 and 108 correspond to the time relative to January 1, 1900. In the SDK, STYLE 8 and 108 correspond to the time relative to January 1, 2000.
ALIGN determines whether or not you want to right-align numeric data when it is edited. Numeric data is any TYPE of TINYINT, SMALLINT, INT, NUMERIC, and DECIMAL. The SDK will also right-align any non-null VALUE when ALIGN is TRUE.
ALIGN may be either TRUE, FALSE, or NULL. When NULL, the default is FALSE unless the TYPE is MONEY or SMALLMONEY. MONEY and SMALLMONEY default to TRUE (right-alignment) when ALIGN is NULL.
For numeric data, SCALE determines the number of decimal digits that are displayed. When NULL, SCALE will automatically default to the number of decimal digits that were entered by the user or 2 when the TYPE is one of MONEY or SMALLMONEY.
This option determines whether or not numeric data is suppose to contain commas at the expected position. When TRUE, 1234 is displayed as 1,234. Since numeric fields containing commas are not valid Sybabase values, you will have to manually remove them before they are converted to a numeric data type.
If TYPE is one of MONEY or SMALLMONEY, the default is TRUE. For all other numeric types, the default is FALSE.
exec sp_html_input
@TYPE = "text"
, @NAME = "address"
, @VALUE = @ADDRESS
, @SIZE = "30"
Here are two radio buttons. sp_html_input will automatically determine if
the button is checked based on the parameter name (@PIZZA). This is
actually very convenient because to do this yourself you would have to
test whether or not @PIZZA was equal to each button value.
exec sp_html_input
@TYPE = "radio"
, @NAME = "PIZZA"
, @VALUE = "Cheese"
, @CHECKED = @PIZZA
exec sp_html_input
@TYPE = "radio"
, @NAME = "PIZZA"
, @VALUE = "Pepperoni"
, @CHECKED = @PIZZA
The next example illustrates how you can use Sybase datatypes when calling
sp_html_input.
exec sp_html_input
@TYPE = "SMALLINT"
, @NAME = "Balance"
Because they were not specified, the Sybernet SDK will automatically set both
SIZE and MAXLENGTH to 6. It will also validate that the value in this
field is a whole number between -32,768 and 32,767. Here's another example
that overrides these defaults:
exec sp_html_input
@TYPE = "INT"
, @NAME = "Account"
, @SIZE = "30"
, @MAXLENGTH = "30"
, @minValue = "200000"
, @maxValue = "299999"
The next example specifies the Sybase datetype DATETIME and validates that the date
entered is at least November 25, 1996.
exec sp_html_input
@TYPE = "DATETIME"
, @NAME = "Birthday"
, @minValue = "Nov 25, 1996"
A standard submit button which displays a confirmation before submitting the
form. The button is named because the procedure that receives this form wants
to know which button the user clicked.
exec sp_html_input
@TYPE = "submit"
, @NAME = "button"
, @VALUE = "Save"
, @CONFIRM = "Are you sure you want to save this form?"
Similar to the example above except an alert is displayed and the form is not
submitted. Normally, this would be preceded by some condition that tests
whether or not the user is allowed to click this button.
exec sp_html_input
@TYPE = "submit"
, @NAME = "button"
, @VALUE = "Drop"
, @ALERT = "You are not permitted to drop this form!"
This is just a simple button that behaves exactly like the BACK button on
your browser's tool bar. Notice that it uses the onClick event handler
and supplies the entire JavaScript code in the onClick parameter.
exec sp_html_input
@TYPE = "button"
, @VALUE = "Back"
, @onClick = "window.history.back()"
Version 2.22 of the Sybernet SDK introduced 3 new parameters that allow you
to control how numeric data is displayed and edited by the user. They are
ALIGN, SCALE and COMMA.ALIGN may be either TRUE, FALSE or NULL. When TRUE, numeric data is right-aligned. SCALE is a positive integer that determines the number of decimal digits that are displayed and edited. If zero, no decimal digits are displayed. COMMAS may be either TRUE, FALSE or NULL. When TRUE, commas are inserted at the expected location.
exec sp_html_input
@TYPE = "NUMERIC"
, @VALUE = "1,234.5678"
, @ALIGN = "TRUE"
, @SCALE = "2"
, @COMMAS = "TRUE"
In the above example, the value is right-aligned, scaled to two decimal
digits, and commas are inserted at the proper position. Notice too that
the value contains commas; these are removed and then reinserted as
expected.
An image that acts like a submit button is accomplished by the JavaScript
submit() and reset() functions. This means that a button or
image built by sp_html_button must be able to refer to the form being
submitted. This is the NAME that is given to
sp_html_form when you define that form. NAME
is passed as FORM when calling this procedure.
WARNING: If you attempt to call this procedure
in the middle of a form (between the <FORM> and
</FORM> tags), results will probably not be correct.
This is especially true if you are creating "regular" submit buttons (as
opposed to image buttons) or you are using the PROMPT
option of this procedure. Either declare your buttons normally using
sp_html_input or place these buttons outside of your form.
WARNING: This procedure assumes that you are
using FORMAT=SUPPRESSED. If you are not using this
format, some of the buttons will not work or cause conversion errors in
Sybase when your form is submitted.
All of the parameters are varchars. Only TYPE is
required, but if that is the only parameter passed to this procedure,
you are probably doing something wrong.
FORM is the name of the form that is to be submitted
when this image or button is submitted. FORM is the
value of NAME that was passed to sp_html_form, but
you will need to qualify this name if your form is in another window or
frame.
PROCNAME represents the name of the stored procedure
that you want to execute when this button or image is clicked. Normally,
PROCNAME is NULL because
you want to submit a form and not execute a procedure, and the form that
is submitted has already defined the procedure name. It's not only
redundant to specify PROCNAME when you don't mean to,
but also wrong and the effect will not be what you desire!
Use PROCNAME only when you don't want to submit a form,
but instead want to execute a procedure; for example, a button that points
to the main menu page would be a good candidate for this option.
SEARCH represents the parameters to PROCNAME.
sp_html_button will automatically URL Encode this string so you no longer
have to worry about special characters when invoking a procedure.
Be aware that if you are passing multiple parameters to a procedure
that the entire length of this string does not exceed 255 characters.
SEARCH corresponds to the Search argument in a URL request.
TARGET optionally specifies the windowName
to be used for output when this image or button is clicked. Normally,
this is not required since the form being submitted is already
armed with this information (even if it were not explicitly specified).
A button that points to the main menu page when frames are being used
would be a good candidate. In this case, TARGET
would be specified as "_parent" so that the page invoked is allowed to
use the entire screen.
TYPE specifies the type of button you are creating.
TYPE can be either SUBMIT,
BUTTON and RESET, or it can be
the name of an image. Except for the keyword UNDO
all image names are interpreted as submit buttons.
Images reside in the "images" directory of your default documents
folder, and within this directory are grouped together under the
GALLERY directory; for example, a button type of
SAVE defaults to an image called
"/images/buttons/netscape/save.gif" where "netscape" is the default
gallery.
Currently, the following images exist in the default gallery:
SAVE, FIRST, FORWARD, BACK, LAST, NEW, DELETE, HOME, UNDO,
CONTENT, INDEX, EXIT, and FIND.
These special keywords are used only to associate their name with an
image and type; for example, the keyword UNDO
assigns IMAGE to "undo.gif" and
TYPE to RESET. It is up to you to make
the buttons actually do something.
TYPE is required.
IMAGE represents the name of an image in the
images directory. If TYPE is one of the keywords
listed above, the value of IMAGE is ignored.
If IMAGE is NULL,
regular type submit buttons are created.
GALLERY allows you to choose different images that
all correspond to their image name. The default gallery name is
"netscape." You can create your own images and copy them to their own
gallery and use that name when calling this procedure.
NAME is the name of your button and the name of
an input field (hidden or otherwise) that exists in your form. This
name is going to be set to the value of VALUE
when the form is suibmitted. Failure to supply this name (either in
this procedure or in your form declaration) will result in a
JavaScript error.
VALUE is the value that is assigned to
FORM.NAME.value when this button or image is
clicked.
ALERT causes a JavaScript alert and the form
is not submitted.
CONFIRM calls the JavaScript function confirm.
If the result is false, the form is not submitted.
onClick is inserted after ALERT and
CONFIRM and just before the form is submitted. It is possible,
for example, to call a validation function here and return false if
you decide on your own that the form should not be submitted.
The value of STATUS is written to the status line when a MouseOver
event occurs on this link.
PROMPT allows you to prompt the user for some
input text. Normally, PROMPT is NULL
because you want to submit the entire form and use that information to
determine your next action; for example, when they click the next button,
you probably need the current information to determine exactly what next
actually means.
PROMPT is primarily designed to implement a search
function in your stored procedure so the values of your input fields
are not as critical. As it is currently implemented, the PROMPT
option returns the value of your button (indicated by NAME)
and the text returned by your user in the field (probably hidden) identified
by the value supplied in this name. The examples below explain this further.
Although you can specify a value for onClick, doing so will override
the code that performs this function. onClick should be NULL
unless you absolutely know what you are doing.
Since our buttons are no longer part of our form, we want to declare a
hidden field that will be used to store the value of our button. In the
following form declaration, the name of this button will be called
BUTTON.
The first example illustrates how to define a reset button:
While this looks like a regular reset button, it can actually reside in
a different window or frame. If your buttons do not, you should probably
define your submit buttons with sp_html_input.
Here is how to define the same button as an image:
The next example illustrates how to define a submit button:
Here's a similar example that first asks the user if they really want to
save their change and then calls a JavaScript function (defined by you)
before the form is submitted:
The next example illustrates how to override the form submission and call
another procedure:
The next example illustrates how you can prompt your user for some text. It
uses the PROMPT option, and only the value of your button
(indicated by NAME) and the text that was entered when the
prompt was displayed is returned to your procedure:
If you create more than one button with this procedure, you should probably
include the whole thing in a table so that the buttons are exactly where
you want them. Here is an example of how you might create a tool bar:
To add the ability to create a directory of hyper-text links, we've
added some parameters to do this. In particular, DESCRIPTION will cause the
anchor and description to be separated by paragraph tags.
All of the parameters are optional (which doesn't make a lot of sense, but
it is consistent with HTML) and they are all varchars.
PROCNAME is the name of the stored procedure to invoke. PROCNAME
corresponds to the direct argument in a URL request.
If not NULL, PROCNAME is appended to the name of the Sybernet CGI.
SEARCH represents the parameters to PROCNAME. sp_html_href will
automatically URL Encode this string so you no longer have to worry
about special characters when invoking a procedure.
Be aware that if you are passing multiple parameters to a procedure
that the entire length of this string does not exceed 255 characters.
If it does, you will need to construct this argument the old fashion way.
SEARCH corresponds to the Search argument in a URL request.
HREF allows you to specify the URL yourself. This would be used when you
need to point this link to something other than a stored procedure. If
specified, PROCNAME and SEARCH are ignored.
If DESCRIPTION is not NULL, the value in CHECKED is compared to the
value in SEARCH. If equal, the color of the anchorText will
be red; otherwise, it will be white.
TARGET optionally specifies the windowName to be used for output
when this link it clicked. If not specified, output returns to the same
window.
anchorText is the text to display at the anchor. If not specified, the
value of SEARCH is used instead.
If specified, DESCRIPTION is displayed after the anchor object. It will
also separate that anchor with a <P> tag. In addition, a non-NULL
value of DESCRIPTION determines the color of the anchorText. The
CHECKED option determines what that color will be.
The value of STATUS is written to the status line when a MouseOver
event occurs on this link.
A mouseOver event occurs once each time the mouse pointer moves over an
object from outside of that object.
A mouseOut event occurs each time the mouse pointer leaves an object.
A click event occurs when a link is clicked. The onClick event handler
executes JavaScript code when a click event occurs.
If specified, IMAGE represents the name of an image in the images directory
and this image is used in lieu of anchorText.
NAME represents the name of your image. This is optional unless you need to
refer to that image name in JavaScript.
BORDER defines the size of the border that bounds your image. When 0, no
border occurs.
Since the name of the Sybernet CGI is automatically included when PROCNAME is
not NULL, you wouldn't use this procedure to create anchor tags that point to
anything other than a Sybase stored procedure; however, JavaScript is quite
powerful, and this can be accomplished by the following example:
The parameters allowed to this procedure include the following:
PROCNAME is the name of the stored procedure that should be executed
when the user clicks on the Instructions image on the menubar.
SEARCH are any arguments that you wish to pass to this procedure; for
example, you might wish to have one help procedure defined that displays
help text based on the parameter passed to it.
While the SEARCH string could be appended to PROCNAME in the usual way,
passing it separately guarantees that this string will be valid because
it will automatically be URL Encoded.
STATUS is written to the window's status line when a mouseOver
event occurs on this link.
When TARGET is specified, a new window is created which will be used for
the output text of your stored procedure. When NULL, output is sent to
the same window.
WIDTH specifies the width of your new window in pixels. The default is
200. WIDTH is ignored if TARGET is NULL.
HEIGHT specifies the height of your new window in pixels. The default is
400. HEIGHT is ignored if TARGET is NULL.
RESIZEABLE determines if the new window created can be resized. Allowed
values are yes and no. The defulat is yes.
SCROLLBARS determines if the new window created will have scroll bars.
Allowed values are yes and no. The default is no.
The next example works exactly the same way except that it creates a new
browser window to send this information.
The prototype for sp_audit looks like this:
When PeopleSoft was installed last year, all of the web reports that were created used
a common convention that made it possible to develop these applications in the shortest
time possible while providing a common look and feel to every report.
The common look and feel was accomplished by a stored procedure called sp_html_frame.
This look and feel was not only seen by the user in what was rendered on their browser,
but also by the developer because the internal working of every procedure followed the
same convention. The point is, without close inspection it is difficult to tell the
difference between Personnel Roster #5 and Employees Compensation Report.
Here is the prototype of sp_html_frame:
The frames are called NORTH, SOUTH, EAST, WEST, and CENTER.
That is what they are called and that is how you will refer to them in your application. The
NORTH frame is required and is built automatically by sp_html_frame. The
other frames are optional are are built only when non-null values are given to their name.
When all frames are defined they resemble the following layout:
BUTTON's sole purpose is to represent the state of your application.
When it is null, your application is initializing and will call sp_html_frame. When it
is not null, its value might be the name of the frame you are to populate, or it might
be the value of a button on one of your form screens.
PROCNAME is passed to sp_html_frame and is displayed in the upper-left
hand corner of the NORTH frame. Your users probably don't care about this
name, but you do.
The single line patch comments at the top of this procedure go hand-in-hand with the
version number of your program. Everytime a change is made to the source (no matter
how trivial), add a description of that change to the patch heading and increment
the version number.
sp_html_frame will cause your application to be invoked for each frame that is not
NULL, and it does this by passing that frame name for the value of BUTTON.
In this example, BUTTON will be assigned to SOUTH. Your
application will test for this value and populate the frame that corresponds to this value.
Again, the result of our submit is targeted at the NORTH
frame and BUTTON is assigned to LOOKUP.
The code for that function first calls sp_html_frame to redraw the
NORTH frame. The result is that the
NORTH flickers ever so briefly.
The JavaScript that is created then populates the fields on our form. Since
our code is now running in the NORTH frame, it qualifies
these field names appropriately:
Because I modified the original source, I commented this change in the patch
heading and incremented the version number.
Examples
We first need to define a form screen. The form screen is required, but
since the form is referenced by its name, you can actually create your
buttons before creating the form. For our purposes, however, it will be
clearer if we define the form first and then show how the procedure is
used. exec sp_html_form
@NAME = "myForm"
, @PROCNAME = "sp_html_form"
, @FORMAT = "SUPPRESSED"
exec sp_html_input
@TYPE="HIDDEN"
, @NAME="BUTTON"
exec sp_html_input
@TYPE="HIDDEN"
, @NAME="SEARCH"
exec sp_html_form
The important parts are displayed in bold. NAME
is going to be used to reference our form, BUTTON
is going to be the value that is set when our form is submitted, and
SEARCH will be assigned the text entered by
your user when the prompt option is used. exec sp_html_button
@TYPE="RESET"
, @NAME="BUTTON"
, @VALUE="Reset"
, @FORM="myForm"
Since IMAGE was not defined and TYPE
is not one of our keywords, this is just a simple reset button. exec sp_html_button
@TYPE="UNDO"
, @NAME="BUTTON"
, @VALUE="Reset"
, @FORM="myForm"
, @STATUS="Reset information on this page"
Since UNDO is one of our keywords, IMAGE
and TYPE are automatically assigned. exec sp_html_button
@TYPE="SAVE"
, @NAME="BUTTON"
, @VALUE="Save"
, @FORM="myForm"
, @STATUS="Click here to save your changes"
When this image button is clicked, the form "myForm" is submitted and the
value of @BUTTON is set to "Save." exec sp_html_button
@TYPE="SAVE"
, @NAME="BUTTON"
, @VALUE="Save"
, @FORM="myForm"
, @CONFIRM="You really want to save this?"
, @onClick="if (!validate(myForm)) return false;"
, @STATUS="Click here to save your changes"
In order, the user is first asked to confirm that that they really want to
save this form. If that succeeds, your JavaScript function validate
is called. If that succeeds, only then is the form submitted. exec sp_html_button
@TYPE="HOME"
, @PROCNAME="sp_html_login"
, @TARGET="_parent"
, @FORM="Home"
, @NAME="Home"
, @VALUE="Home"
, @STATUS="Return to the Sybernet main menu"
Since a procedure name is specified for PROCNAME, the
values for FORM, NAME, and VALUE
are not important. When this button or image is clicked,
TARGET is set to "_parent" and the procedure "sp_html_login" is
invoked. exec sp_html_button
@TYPE="FIND"
, @PROCNAME="sp_html_form"
, @TARGET="Frame2"
, @NAME="Button"
, @VALUE="Find"
, @STATUS="Search for some text in this file"
, @PROMPT = "SEARCH"
Since the PROMPT option does not invoke our form, it is
important to supply the name of the procedure you wish to execute. The name
of the form is not needed; in fact, it is ignored. TARGET
should be specified if you are using frames so that the results of the find
can appear in their own window.
PROMPT also defines the name on your form (and is probably
hidden) that is to receive the user's response. Note too that the value entered
is "remembered" if your buttons appear in their own window or frame; otherwise,
the value is reset whenever a form is submitted and the buttons are redrawn. select "<TABLE BORDER=4 BGCOLOR=BLACK><TR><TD ALIGN=CENTER>"
select "<TABLE BORDER=0 WIDTH=100% BGCOLOR=BLACK CELLPADDING=0 CELLSPACING=0><TR><TD>"
exec sp_html_button @TYPE="SAVE", @NAME="BUTTON", @FORM="MyForm", @VALUE="Save"
exec sp_html_button @TYPE="NEXT", @NAME="BUTTON", @FORM="MyForm", @VALUE="Next"
exec sp_html_button @TYPE="LAST", @NAME="BUTTON", @FORM="MyForm", @VALUE="Last"
select "</TD></TR></TABLE>"
select "</TD></TR></TABLE>"
sp_html_href
sp_html_href creates an anchor tag and is specifically
designed to make calling stored procedures and passing parameters to
those procedures as easy as possible.
Examples
The first example is a simple anchor object that calls the main menu screen. exec sp_html_href
@PROCNAME = "sp_html_login"
, @anchorText = "Return to the Sybernet Main Menu screen"
, @STATUS = "Click here to return to the main menu"
The next example constructs a hyper-text link that will invoke the procedure
sp_html_template with a single (unnamed) parameter of "Order Pizza." That
parameter is received by this procedure in the variable @SEARCH, not to be
confused with the @SEARCH parameter that we set when we call sp_html_href. exec sp_html_href
@PROCNAME = "sp_html_template"
, @SEARCH = "Order Pizza"
, @CHECKED = @SEARCH
, @DESCRIPTION = "Click here to order your pizza on the world wide web."
It is also worth noting that the anchorText will default to the value
for @SEARCH and @STATUS will default to @DESCRIPTION since neither of these
were specified. exec sp_html_href
@PROCNAME = NULL
, @anchorText = "Sybernet Home Page"
, @onClick = "this.href='http://Sybernet.sri.com/'"
Normally, this trick is reserved for those cases where the href needs to be
determined dynamcially. Or it might be used to open a second window: exec sp_html_href
@PROCNAME = NULL
, @anchorText = "Open Another Window"
, @onClick = "window.open('','Sybernet','width=600,height=160');this.href='http://Sybernet.sri.com/'"
, @TARGET = "Sybernet"
http..sp_html_menubar
You can override the default Instructions when calling the menubar by
specifying the name of the stored procedure that will provide instructions.
Examples
The first example is how you would direct output of your help procedure to
the same window. exec http..sp_html_menubar
@PROCNAME = "sp_html_help"
, @SEARCH = "Step 3"
, @STATUS = "Click here for information on how to use this tool!"
Notice that the parameter "Step 3" is passed to "sp_html_help." exec http..sp_html_menubar
@PROCNAME = "sp_html_help"
, @SEARCH = "Step 3"
, @TARGET = "HelpWindow"
, @WIDTH = "400"
, @HEIGHT = "600"
sp_audit
sp_audit is used to track the execution of stored procedures. Your web server's log file
can also track this information, but the data is hard to get at and the web server cannot
track form requests. create procedure sp_audit
(
@PROCNAME varchar(92) -- Name of procedure.
)
The audit file that this information is written to contains the following columns:
sp_audit can of course be called anytime you desire. sp_html_frame automatically calls
this procedure whenever BUTTON is NULL.
Example
The following example calls sp_getProcname to retrieve your procedure name at run-time.
It then calls sp_audit and passes that name as the only parameter. select @PROCID = @@procid
exec sp_getProcname @PROCID, @PROCNAME output
exec http..sp_audit @PROCNAME
Example
Here's an example that does not call sp_getProcname. Can you spot the error? create procedure sp_example
as
/*
** Call sp_audit and pass my procedure name to it.
*/
exec http..sp_audit "sp_exumple"
return 0
sp_html_frame
This procedure allows you to build frames in your HTML application. Frames
are fairly easy to construct, but this procedure will do it automatically so you don't
have to worry about how it's actually done. create procedure sp_html_frame
( @BUTTON varchar(92) = NULL -- NULL or name of frame to build.
, @PROCNAME varchar(92) = NULL -- Name of procedure.
, @VERSION varchar(60) = NULL -- Version of procedure.
, @TITLE varchar(92) = NULL -- Title on North frame.
, @NORTH varchar(10) = "70" -- Size of north frame.
, @CENTER varchar(10) = NULL -- Size of center frame.
, @WEST varchar(10) = NULL -- Size of west frame.
, @EAST varchar(10) = NULL -- Size of east frame.
, @SOUTH varchar(10) = NULL -- Size of south frame.
, @onLoad varchar(255)= NULL -- JavaScript onLoad event.
, @BORDER varchar(10) = "1" -- Size of border around each frame.
)
BUTTON is the single most important parameter passed to sp_html_frame because
it lies at the heart of how it and your application work together. You will pass values for
BUTTON to sp_html_frame and sp_html_frame will pass values back to your
application; for example, to create the frames, a value of NULL is passed.
Example 1
Although sp_html_frame builds the frames, it is up to your application to populate those
frames (except the NORTH frame, of course). And like sp_html_frame
the prototype for your application will declare BUTTON. /******************************************************************************/
/* */
/* PATCH 001 Initial release (08/01/1999) */
/* */
/******************************************************************************/
create procedure sp_example_1
(
@BUTTON varchar(30) = NULL
)
as
declare
@PROCID int -- @@procid
, @PROCNAME varchar(92) -- db_name().owner.name.
, @TITLE varchar(64) -- Report title.
, @VERSION varchar(16) -- Report version.
/*
** Initialize...
*/
select @PROCID = @@procid
exec sp_getProcname @PROCID, @PROCNAME output
select @VERSION = "Version 1.01"
select @TITLE = DESCRIPTION
from http..HTTP_REGISTER
where PROCNAME = @PROCNAME
if @BUTTON is NULL
begin
/*
** Tell sp_html_frame to build the frames.
*/
exec sp_html_frame
@BUTTON = NULL
, @PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @SOUTH = "*"
return 0
end
if @BUTTON = "SOUTH"
begin
/*
** sp_html_frame is telling me to populate the south frame.
*/
select '<HTML>'
, '<BODY BGCOLOR=WHITE>'
, '<CENTER>'
, replicate('<BR>',20)
, 'South'
, '</CENTER>'
, '</BODY>'
, '</HTML>'
return 0
end
Example 1 - explained
The call to sp_getProcname returns the name of your stored procedure, including the
database it belongs to and its owner. You'll avoid yourself a lot of head-aches if
you always refer to @PROCNAME instead of using a literal string. select @PROCID = @@procid
exec sp_getProcname @PROCID, @PROCNAME output
And besides, if you misspell @PROCNAME, you'll get a syntax error.
If you misspell something inside of a string, it will compile just fine.
VERSION is useful too, and like PROCNAME it is
also displayed on the NORTH frame. It's suppose to be incremented
after each change to your application. select @VERSION = "Version 1.01"
Six months from now you might have to debug this application. If the version displayed by the
application is different from the source code you are looking at, you may be well on your
way to discovering the problem.
In the Naked Gun series staring Leslie Neilson, one of the funnier bits was at the
beginning of the show when the announcer would tell you the name of the episode
while the name was printed at the bottom of the screen. The two were never the same,
you see. select @TITLE = DESCRIPTION
from http..HTTP_REGISTER
where PROCNAME = @PROCNAME
Instead of hard-wiring your application's title inside of the application, why not
pick it up from the http register so that the two are always the same?
In this application we are using only two frames: NORTH and SOUTH.
The remaining frames can be passed as NULL or omitted from the call to
sp_html_frame. exec sp_html_frame
@BUTTON = NULL
, @PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @SOUTH = "*"
The frame names are in upper-case, so if you are running this on a case-sensitive server, you
will want to make sure case them correctly. The expression
@SOUTH = "*"
is telling sp_html_frame that you want a SOUTH frame and that it should
occupy the remaining space on your browser's window, after the NORTH frame
has been defined. if @BUTTON = "SOUTH"
begin
/*
** sp_html_frame is telling me to populate the south frame.
*/
end
Obviously, this is where things start to get interesting. This is where you might create your
form screen or generate your report if no user input is required.Example 1 - illustrated
If you compile and execute the above procedure, the results should look like this:
sp_example_1
Version 1.0
Frame Example 1
Example 2
The next example will explore more deeply how BUTTON is used to control
state information. It will create a simple form screen for looking up employees. When the
employee number changes, an onChange event will cause the application to look up this
number and fill in the remaining fields. It does this without redrawing the form screen: /******************************************************************************/
/* */
/* PATCH 001 Initial release (08/01/1999) */
/* PATCH 002 Add form screen and JavaScript to look up employees (08/02/1999) */
/* */
/******************************************************************************/
create procedure sp_example_2
(
@BUTTON varchar(30) = NULL -- State of procedure.
, @employeenumber varchar(5) = NULL -- employee number.
)
as
declare
@PROCID int -- @@procid
, @PROCNAME varchar(92) -- db_name().owner.name.
, @TITLE varchar(64) -- Report title.
, @VERSION varchar(11) -- Report version.
, @onLoad varchar(255) -- JavaScript onLoad event.
select @PROCID = @@procid
exec sp_getProcname @PROCID, @PROCNAME output
select @VERSION = "Version 1.02"
select @TITLE = DESCRIPTION
from http..HTTP_REGISTER
where PROCNAME = @PROCNAME
if @BUTTON is NULL
begin
exec sp_html_frame
@PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @SOUTH = "*"
return 0
end
if @BUTTON = "SOUTH"
begin
/*
** Build the Center frame.
*/
select '<HTML>'
, '<BODY BGCOLOR=WHITE onLoad="window.document.FORM.employeenumber.focus();window.document.FORM.employeenumber.select();">'
, '<CENTER>'
, replicate('<BR>',2)
, '<FONT SIZE=5 COLOR=NAVY><B><I>' + @TITLE + '</I></B></FONT>'
, replicate('<BR>',2)
exec sp_html_form
@NAME = "FORM"
, @PROCNAME = @PROCNAME
, @FORMAT = "SUPPRESSED"
, @METHOD = "POST"
, @TARGET = "NORTH"
exec sp_html_input
@TYPE = "HIDDEN"
, @NAME = "BUTTON"
, @VALUE = "LOOKUP"
select '<TABLE BORDER=4 BGCOLOR=LIGHTGREY CELLPADDING=10 CELLSPACING=1>'
, '<TR>'
, '<TD>'
, '<TABLE BORDER=0 WIDTH=100%>'
, '<TR>'
, '<TD>EMPLID:</TD>'
, '<TD>'
exec sp_html_input
@TYPE = "TEXT"
, @NAME = "employeenumber"
, @SIZE = "5"
, @MAXLENGTH = "5"
, @onChange = "this.form.submit();"
select '</TD></TR><TR><TD>NAME:</TD><TD>'
exec sp_html_input
@TYPE = "TEXT"
, @NAME = "cn"
, @SIZE = "30"
select '</TD></TR><TR><TD>TITLE:</TD><TD>'
exec sp_html_input
@TYPE = "TEXT"
, @NAME = "title"
, @SIZE = "30"
select '</TD></TR><TR><TD>E-MAIL ADDRESS:</TD><TD>'
exec sp_html_input
@TYPE = "TEXT"
, @NAME = "mail"
, @SIZE = "30"
select '</TD></TR></TABLE>'
, '</TD></TR></TABLE>'
, '<P>'
, replicate('<BR>',2)
, '<FONT COLOR=NAVY>Enter an employee number and press the TAB key</FONT>'
, '</CENTER>'
exec sp_html_form
select '</BODY>'
, '</HTML>'
return 0
end
if @BUTTON = "LOOKUP"
begin
exec sp_html_frame
@PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @WEST = NULL
, @BUTTON = "NORTH"
select '<SCRIPT>'
, 'parent.SOUTH.document.FORM.cn.value="'
, cn
, '";'
, 'parent.SOUTH.document.FORM.title.value="'
, title
, '";'
, 'parent.SOUTH.document.FORM.mail.value="'
, mail
, '";'
, 'parent.SOUTH.document.FORM.employeenumber.focus();'
, 'parent.SOUTH.document.FORM.employeenumber.select();'
, '</SCRIPT>'
from http..ldif_view
where employeenumber = @employeenumber
if ( @@rowcount = 0 )
select '<SCRIPT>'
, 'parent.SOUTH.document.FORM.cn.value="";'
, 'parent.SOUTH.document.FORM.title.value="";'
, 'parent.SOUTH.document.FORM.mail.value="";'
, 'parent.SOUTH.document.FORM.employeenumber.focus();'
, 'parent.SOUTH.document.FORM.employeenumber.select();'
, '</SCRIPT>'
return 0
end
Example 2 - explained
Our form screen is built once. From then on out we'll use JavaScript to
populate the fields on this form. We can do this because the TARGET
for our form is set to NORTH. exec sp_html_form
@NAME = "FORM"
, @PROCNAME = @PROCNAME
, @FORMAT = "SUPPRESSED"
, @METHOD = "POST"
, @TARGET = "NORTH"
The other important bit is that we set the value of BUTTON to
"LOOKUP" when the form is submitted: exec sp_html_input
@TYPE = "HIDDEN"
, @NAME = "BUTTON"
, @VALUE = "LOOKUP"
Although the entire form is submitted, only the value for employee number is
required. Many times you don't want to submit the entire form because that
might be reserved for something else, like updating this record. To get around
this our onChange code could have instead copied the employee number to another
form and submit that instead. <SCRIPT>
parent.SOUTH.document.FORM.cn.value="Mary Smith";
</SCRIPT>
If the employee number doesn't exist, all the other fields are erased. We could
have displayed an alert instead. The cleaniest way to do this, however, is by
passing the onLoad code to sp_html_frame: exec sp_html_frame
@PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @WEST = NULL
, @BUTTON = "NORTH"
, @onLoad = "alert('Oops!\n \nEmployee number not found.');"
Many times when you are calling sp_html_frame to rebuild the NORTH
frame, you will want to use this feature. It may be nothing more than an alert to
confirm that that an update was successful or unsuccessful, but I might also use it
to ask the user a question before comitting their request: exec sp_html_frame
@PROCNAME = @PROCNAME
, @VERSION = @VERSION
, @TITLE = @TITLE
, @WEST = NULL
, @BUTTON = "NORTH"
, @onLoad = "if (confirm('Are you sure?')) window.document.FORM.submit();"
where window.document.FORM contains everything needed to perform this action.Example 2 - illustrated
Sybernet is a trademark of SRI International.
Copyright © 1996-1999 SRI International. All Rights Reserved.
Denis D. Workman / http://Sybernet.sri.com/