Managing page data
Displaying
Web content dynamically (in response to a user’s actions)
enhances the user experience at your Web site. Passing data from
one page to another or sharing data among pages lets you generate
the dynamic content for your site. When a user moves from one page
to another, server scripts interpret the values of parameters and
variables to define the content sent to the user’s browser.
When discussing data transfer between Web pages:
- The linking page is the page on which a user action initiates a move (redirect)
to another page - The target page is the destination page of a move from a linking page
About page parameters and variables
Parameters and variables let you share page
data in different ways. Basically you define page parameters for
information that will be passed to your page; you define page variables
to contain values internal to the page.
Parameters
A page parameter is a named value that you can pass from one page to another.
Usually a page parameter is appended to a URL as a query string
or is submitted with a form. After the value is passed from a page,
a server script can access the value and use it as needed in generating
the target page.
Variables
A page variable is a temporary value that can be saved and made accessible to
other pages, including the page where the variable is set. A page
variable is available as long as a page is active.
A session variable is like a page variable, but with a longer life-span. A session
variable is available for the length of the user’s browser
session. You use a session variable to make the user’s
information available to many pages.
Variables and login data Variables, either page or session, can be used to store login
information for a user’s site visit. This lets that person
visit a number of pages without needing to log on again.
4GL Web pages
4GL Web pages give you a straightforward way to define and
keep track of parameters (and variables) during development. The
Web Target object model manages the parameters and variables when
the page is processed by PowerDynamo.
For information about 4GL Web pages, see Chapter 8, “Developing 4GL Web Pages”. For information on
referring to parameters and variables in scripts on 4GL Web pages,
see “Adding scripts to 4GL Web
pages”.
Using page parameters in server scripts
If you
are not using the 4GL interface to manage your page parameters,
you can access parameters submitted to a page by writing server
scripts.
Non-4GL pages
To make full use of the page parameters, you can have the
server script generate a client script. This server-side script
generates a client-side script that sets a textbox value (on a Web
page that is not 4GL enabled) to the id
parameter:
|
1 |
psDocument.WriteLn("<script>");<br /> psDocument.WriteLn("function setValues()");<br /> psDocument.WriteLn("{");<br /> psDocument.WriteLn("myForm.sle_1.value=" +<br /> psDocument.GetParam("id"));<br /> psDocument.WriteLn("}");<br /> psDocument.WriteLn("</script>"); |
You can then code a client-side event (such as an onclick
event for a button or the onload event for the page) to call the
setValues function in the generated client-side script.
Passing a parameter in an anchor element
Passing page parameters from one page to another requires
identifying the parameter (of the target page) on the linking page,
then accessing the value in a server script on the target page.
You can set up an anchor element or a form on the linking page to
link to the page parameter of the target page.
On the linking page, create an anchor element (<A>).
In the HREF attribute, specify the target URL with a query string
appended to it. The query string can have one or more name-value
pairs. A question mark separates the query string from the URL and
an ampersand separates each name-value pair. The format is:
|
1 |
url?name1=value1&name2=value |
Example: passing data in a query string Here a link on the linking page goes to the target page nextpage.htm.
There are two values passed in the query string: Data and Name.
On the target page, the page parameter names are called Data and
Name and their values are 1 and Jane. Note that parameter names
are case-sensitive.
|
1 |
<A HREF="nextpage.htm?Data=1&Name=Jane">Jane's data</A> |
Passing a parameter in a form
On the linking page, create a form for which the action is
the URL of the target page. When the user submits the form, the
form field names and values are passed to the target page as page
parameters. Depending on the form method (GET or POST), the parameters
are formatted as a query string or sent separately. No matter which
method you use, server scripts on the target page see the values
as page parameters.
Example: passing data from a form Here a form on the linking page asks the user to specify a
name and a number. On the target page, nextpage.htm,
the page parameters are called Name and Data and their values are
whatever the user entered in the form fields.
|
1 |
<FORM id=FORM1 name=NameAndData action="nextpage.htm" method=post> |
|
1 |
|
1 |
User Name: <INPUT id=INPUT1 name="Name" type="TEXT"> |
|
1 |
Number of requests: <INPUT id=INPUT2 |
|
1 |
name="Data" type="TEXT"> |
|
1 |
<INPUT id=INPUT3 name="Submit" type=submit> |
|
1 |
|
1 |
</FORM> |
Accessing the value of a page parameter
In a server script on the target page, you can get the value
of page parameters with the GetParam method.
Example Here the script gets the value of
|
1 |
Name |
and
|
1 |
Data |
.
|
1 |
username = psDocument.GetParam("Name"); |
|
1 |
userdata = psDocument.GetParam("Data"); |
Using session variables in server scripts
The psSession
object allows you to keep track of user login information and other
data that you want to make available to all the pages in your Web application
during a user’s browser
session. The psSession object also keeps track of user activity
so that a user’s session can be terminated if it becomes inactive.
The actual behavior of the session object depends on its implementation
on each application server, but typically a session object is instantiated
only if you try to access it. Session variables are properties of
the psSession object. You create properties as you need them simply
by setting them in a server script. For complete information about
session objects, see the documentation for your application server.
Setting the length of a session
The psSession object handles the lifespan of the session as
well as session variables. When the user does not access the server
for a specified number of minutes, the session times out. If you
use the psSession object to manage user login information, the login
information disappears when the user is inactive for the specified
amount of time.
Ending a session One way to implement a timeout is by destroying the psSession
object on the application server so that the psSession object and
the properties do not exist
until you set new
properties. If you query a property after the session ends, the
GetValue method returns null. Pages that rely on shared information
must handle the disappearance of that information. If your page
gets values of psSession properties, your code should check for
null and handle the situation of an expired session.
Changing the length of a session You can change the length of a session, either in the server
configuration or dynamically in a script. The server’s
own session object stores the session length in its timeout property.
You can change the lifespan of a session by:
- Setting
the server’s timeout property using a psSession object. - Writing code that uses the correct property name
for the server. - Writing conditional code tailored to each server
you want to support.
Creating and setting the value of a session variable
You create
a session variable with the SetValue method. This method creates the
variable, if necessary, and sets the variable’s value.
If the psSession object does not exist, calling this method instantiates
it. Creating the psSession object triggers timeout management.
Example: creating a session variable This script sets the value of the userid and password session
variables:
|
1 |
psSession.SetValue("Userid", "jdoe"); psSession.SetValue("password", "mydogsname"); |
You can also set the timeout property, but the case-sensitive
code you use depends on your deployment platform.
Example: specifying the application server This code uses the ObjectModelType method to determine the
current application server and sets the timeout property as named
on that server:
|
1 |
if (psServer.ObjectModelType() == "ASP")<br /> {<br /> psSession.SetValue("Timeout", 30);<br /> }<br /> else if (psServer.ObjectModelType() == "Dynamo") <br /> {<br /> psSession.SetValue("timeOut", 30);<br /> } |
Getting the value of a session variable
The GetValue method gets a value from a property of the psSession
object. If the property doesn’t exist, GetValue returns
null. The property does not exist if the session has timed out.
Example: getting a session variable This code gets the user’s ID. If the ID does not
exist, the user is redirected to the login.htm page.
In a real application, you would want to explain to the user
what happened.
|
1 |
curruser = psSession.GetValue("Userid");<br /> if (curruser == null) <br /> {<br /> psDocument.Redirect("login.htm");<br /> } |
Samples for retrieving and displaying data
This section presents
separate examples to illustrate the objects and methods you use
to:
- Get the value of a page parameter
- Establish a database connection and handle database
errors - Create a SQL query and use the page parameter in
the WHERE clause - Display the query results in a table with link formatting
In these examples, the target page receives the value of a
department passed from a link on another page to a target page parameter.
It then retrieves the names and IDs of employees who work in that
department.
The employee names are then displayed in a table with a link
to an employee detail page. The employee ID is in a query string
of the link so that it can be used in another query on the detail
page.
The complete source for these examples is provided at the
end of this section.
Getting the value of a page parameter
The GetParam method for the psDocument object accesses the
value of a page parameter. You can assign the value to a variable
and use that variable in other scripts on the page.
Example: getting the value of a page parameter This script would appear after the first heading in the file.
It assigns the page parameter value to the variable curr_dept.
It also writes the department name on the page:
|
1 |
curr_dept = psDocument.GetParam("Dept"); |
|
1 |
psDocument.Write("<P>Employees for department <B>"); |
|
1 |
psDocument.Write(curr_dept + "</B></P>"); |
Establishing a database connection
The psServer instance
is automatically instantiated in your Web target and is available
to server scripts on every page. Using psServer methods, you can define
new connections at execution time or you can access connections
you defined in PowerBuilder. (When you deploy a Web target, the connection information
is made available to the application server.)
Example: connecting to a database Here the GetConnection method for psServer instantiates a
PSConnectionClass object using the connection profile Employees.
If an error occurs, the code calls a WriteError function to display error
information:
|
1 |
conn = psServer.GetConnection("Employees"); |
|
1 |
rows = 0; |
|
1 |
if ( conn.GetError() != null ) |
|
1 |
{ |
|
1 |
WriteError( "GetConnection", conn ); |
|
1 |
return; |
|
1 |
} |
The script that defines the WriteError function is in the
Head section of the document. The arguments for WriteError are:
- The method that caused the error
- The instance of the PSConnectionClass object
The function calls the GetError method for the connection
object to get the first instance of the PSErrorClass object. An
error object is available only if an error has occurred; otherwise,
GetError returns null.
Handling database errors
After getting
error information, the GetError function writes the connection name,
error code, error message, and the name of the function that failed
in the document. The GetCode and GetMessage methods for PSErrorClass
get the error code and message.
Example: handling database errors This is the code for the WriteError function:
|
1 |
function WriteError( function_called, connName ) |
|
1 |
{ |
|
1 |
errobj = connName.GetError(); |
|
1 |
str = errobj.GetCode() + " " + errobj.GetMessage(); |
|
1 |
psDocument.Write("<P>Error: " ); |
|
1 |
psDocument.Write ( function_called + " " + str ); |
|
1 |
psDocument.Write("</P>"); |
|
1 |
return; |
|
1 |
} |
Using the page parameter in a SQL query
After you establish
a connection, you can retrieve data with a SQL statement and store
the result set in a PSCursorClass object. To retrieve data, this
code:
- Builds a string that is the SQL statement.
The curr_dept variable, which holds
the page parameter value, is incorporated into the WHERE clause. - Uses the string with the SQL statement as an argument
for the CreateCursor method. This method belongs to the PSConnectionClass object. - Assigns the returned result set to the newly instantiated
PSCursorClass object called mycursor. - Checks whether a database error occurred and calls
the WriteError function if necessary.
Example: retrieving and storing data The code that creates the cursor and retrieves data looks
like this:
|
1 |
//build a SQL statement |
|
1 |
sqlquery = " SELECT "employees"."fname" , " |
|
1 |
+ " "employees"."lname" , " |
|
1 |
+ " "employees"."empid" " |
|
1 |
+ " FROM "employees" " |
|
1 |
+ " WHERE "employees"."deptid" = " |
|
1 |
+ "'" + curr_dept + "'"; |
|
1 |
// Do the query and assign the result set to mycursor |
|
1 |
mycursor = conn.CreateCursor(sqlquery); |
|
1 |
if ( conn.GetError() != null ) |
|
1 |
{ |
|
1 |
WriteError( "CreateCursor", conn ); |
|
1 |
return; |
|
1 |
} |
Displaying the query results in a table with link
formatting
After
the rows are retrieved, methods for the PSCursorClass object provide access
to the data. Code that writes HTML for displaying data is mixed
with method calls that get the data from the PSCursorClass object.
This code:
- Calls GetRowCount, a method of the
PSCursorClass object, to find out how many rows are in the result
set. - Writes HTML for the Table element.
- Writes HTML to close the Table element.
- Loops through the rows in the result set.
For each row in the result set, the code:
- Writes
HTML for a table row with one cell. - Writes an anchor element (<A>)
tag with a query string using data from the second column (empid).
The GetValue method for the PSCursorClass object gets the data. - Writes text inside the anchor element, using GetValue
to get the employee first name from the first column (0) and the
last name from the second column (1). Column numbers start with
0 and correspond to the columns in the SQL SELECT statement. - Writes HTML that closes the A, TD, and TR elements.
- Calls the MoveNext method for the PSCursorClass
object to go to the next row in the result set.
Example: processing rows The code that processes the rows looks like this:
|
1 |
rows = mycursor.GetRowCount(); |
|
1 |
// Write Table start tag |
|
1 |
psDocument.Write("<TABLE BORDER=1>"); |
|
1 |
// Loop over retrieved rows |
|
1 |
// where rows variable is the row count |
|
1 |
for (var i=0; i < rows; i++ ) |
|
1 |
{ |
|
1 |
|
1 |
// Write TR and TD start tags |
|
1 |
psDocument.Write("<TR><TD>"); |
|
1 |
// Write A element with employee ID in query string |
|
1 |
psDocument.Write( "<A HREF="detail.htm?Key="); |
|
1 |
psDocument.Write( mycursor.GetValue(2) + "">"); |
|
1 |
// Write first and last names |
|
1 |
psDocument.Write( mycursor.GetValue(0) + " "); |
|
1 |
psDocument.Write( mycursor.GetValue(1)); |
|
1 |
// Write A, TD, and TR end tags |
|
1 |
psDocument.Write("</A><TD><TR>"); |
|
1 |
// Go to next row in result set |
|
1 |
mycursor.MoveNext(); |
|
1 |
} |
|
1 |
// Write Table end tag |
|
1 |
psDocument.Write("</TABLE>"); |
Complete example
The complete page looks like this in Source view:
|
1 |
<HTML> |
|
1 |
<HEAD> |
|
1 |
<% |
|
1 |
// function for displaying error information |
|
1 |
function WriteError( function_called, connName ) |
|
1 |
{ |
|
1 |
errobj = connName.GetError(); |
|
1 |
str = errobj.GetCode() + " " + errobj.GetMessage(); |
|
1 |
psDocument.Write("<P>Error: " ); |
|
1 |
psDocument.Write ( function_called + " " + str ); |
|
1 |
psDocument.Write("</P>"); |
|
1 |
return; |
|
1 |
} |
|
1 |
%> |
|
1 |
</HEAD> |
|
1 |
<BODY> |
|
1 |
<H1>Employees</H1> |
|
1 |
<P> |
|
1 |
<% // Get page parameter and write value in document |
|
1 |
curr_dept = psDocument.GetParam("Dept"); |
|
1 |
psDocument.Write("<P>Employees for department <B>"); |
|
1 |
psDocument.Write(curr_dept + "</B></P>"); |
|
1 |
%> |
|
1 |
</P> |
|
1 |
<P> |
|
1 |
<% // Get a connection |
|
1 |
conn = psServer.GetConnection("Employees"); |
|
1 |
rows = 0; |
|
1 |
if ( conn.GetError() != null ) |
|
1 |
{ |
|
1 |
WriteError( "GetConnection", conn ); |
|
1 |
return; |
|
1 |
} |
|
1 |
// Construct the SQL statement |
|
1 |
sqlquery = " SELECT "employees"."fname" , " |
|
1 |
+ " "employees"."lname" , " |
|
1 |
+ " "employees"."empid" " |
|
1 |
+ " FROM "employees" " |
|
1 |
+ " WHERE "employees"."deptid" = " |
|
1 |
+ "'" + curr_dept + "'"; |
|
1 |
// Retrieve the data |
|
1 |
mycursor = conn.CreateCursor(sqlquery); |
|
1 |
if ( conn.GetError() != null ) |
|
1 |
{ |
|
1 |
WriteError( "CreateCursor", conn ); |
|
1 |
return; |
|
1 |
} |
|
1 |
// Get the number of rows retrieved |
|
1 |
rows = mycursor.GetRowCount(); |
|
1 |
psDocument.Write("<TABLE BORDER=1>"); |
|
1 |
for (var i=0; i < rows; i++ ) |
|
1 |
{ |
|
1 |
// Write TR and TD start tags |
|
1 |
psDocument.Write("<TR><TD>"); |
|
1 |
|
1 |
// Write A element with employee ID in query string |
|
1 |
psDocument.Write( "<A HREF="detail.htm?Key="); |
|
1 |
psDocument.Write( mycursor.GetValue(2) + "">"); |
|
1 |
// Write first and last names |
|
1 |
psDocument.Write( mycursor.GetValue(0) + " "); |
|
1 |
psDocument.Write( mycursor.GetValue(1)); |
|
1 |
psDocument.Write("</A><TD><TR>"); |
|
1 |
mycursor.MoveNext(); |
|
1 |
} |
|
1 |
psDocument.Write("</TABLE>"); |
|
1 |
%> |
|
1 |
</BODY> |
|
1 |
</HTML> |