Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Server-Side JavaScript


Java Sourcebook 96: Server Side JavaScript

Server-Side JavaScript

Developing Netscape LiveWire applications

Sudhakar Ramkrishnan

Sudhakar is a software-development engineer for Informix Software's Advanced Technology Group. He can be contacted at [email protected] This article is adapted from an article in TechNotes, an internal Informix publication.


Java is an object-oriented programming language that can be used to write portable applications that are later compiled by the Java compiler. The Java compiler generates bytecodes for the Java Virtual Machine. An interpreter runs these Java applications using run-time support (the Java run-time environment is provided with the Netscape and other browsers). When a Java application is embedded within a web page, it is known as an "applet." Writing applets requires programming experience.

JavaScript, on the other hand, is an object-oriented scripting language that can be written within specified tags and embedded in an HTML document. It gives HTML authors the ability to write simple programs and scripts that interact with web-page objects like forms, frames, and applets. In short, JavaScript is neither a scaled-down version of Java nor a replacement for CGI scripts. It augments both.

JavaScript is interpreted by the browser from the source code. In contrast, Java applets must be precompiled into a class before use. JavaScript uses built-in extensible objects, but has no classes or inheritance. JavaScript data types are loosely typed; that is, you don't have to specify a type for a variable. Moreover, object references are checked at run time (dynamic binding).

Server-Side JavaScript

Understanding server-side JavaScript is central to developing JavaScript applications. Server-side JavaScript is a language for developing applications that execute on the server. The Netscape LiveWire development environment comes with server extensions designed to work with the Netscape Server API and to run as an integral part of Netscape servers. (This discussion is based on the Netscape LiveWire for Sun Solaris Beta1 documentation.) The server extensions provide the needed run-time interpreter to execute scripts on the server.

Server-side JavaScript augments CGI programming and maintains client information across transactions. A predefined set of objects is included for application development. Built-in functions are also provided to enhance features such as navigation and input/output. Server-side JavaScript statements are delimited by the <server> and </server> tags.

Example 1 is a server-side script that prints the message "hello world." To print, use a built-in print function on the server side to display values in an HTML format. The file "hello.html" illustrates the use of the print function.

Next, compile Example 1 into a web file and install the program on the server. Use the command-line compiler to compile and generate a binary file (a bytecode version of the script); for instance, lwcomp -v -o hello.web hello.html.

Finally, use the Application Manager (included with Netscape LiveWire) to install the web file so that it is identified by the server. Users can then access the application by providing the URL. The server extension dynamically creates HTML code based on the statement and sends the HTML to the client.

Figure 1 illustrates the steps required for server-side JavaScript to process a request from a client.

Maintaining Client Information Across Pages

JavaScript has an object framework that allows for the addition of simple, persistent states that can be shared across pages, applications, and servers--extending the capabilities of web-based, client-server applications. The advantage is that users no longer need to keep track of preferences; the application registers them.

There are a number of concepts central to the JavaScript programming model:

Objects. Objects are program constructs that have properties and methods. Every object has a name. Software objects are modeled after real-world objects in the sense that they have a state and behavior. A database programmer can consider the result of a query as a query object. Objects have relevance to the programmer's application domain.

Properties. Properties can be thought of as attributes that represent the state of objects, such as weight, color, taste, and so on.

Property values. Property values can be referred to using the syntax: object.property. For example, if the result of a database query is considered as an object result and one of the attributes in the object identifies the number of returned rows as returnedrows, you can access the value and use it for substitution into a page at a later time. The value returned is always a string. It is also possible to assign values to properties. For example, result.returnedrows=4;. Equivalently, it is possible to assign the values as result[0]=4;. The ordering of the defined properties corresponds to the array element order; see Figure 2.

Methods. Methods are functions associated with an object. A function init_name(name) can be written to initialize the name of the object associated with the name that is passed. A function definition consists of the function keyword, followed by the name of the function, a list of arguments separated by commas and enclosed within parentheses, and finally, the JavaScript statements enclosed in curly braces; see Example 2(a). To convert the function into a method, associate the function with an object, as in Example 2(b). A method can be invoked on an object; see Example 2(c). Invoking a method is akin to sending a message to the object.

LiveWire Object Framework

Netscape's LiveWire object framework provides the predefined objects Request, Client, Project, and Server for application development. While some of these objects contain predefined data provided by LiveWire, you retain the flexibility to define properties. These properties maintain application data; for example, the object can hold the customer number or user ID and transport these items across pages. The key difference between these objects is the lifetime during which they are accessible. Table 1 lists all the predefined objects and some of the accessible default properties. Note that LiveWire objects can be accessed in functions by passing the above objects as parameters.

Request objects are created by the server for each client request. When users click on the Submit button or request a URL, the transaction is considered a request. The request object has the shortest lifetime. The advantage of the request object is that its properties are initialized with some of the default properties and with parameters such as form variables and URL-encoded variables. The properties of the request object can be referred to from the moment that the request object is created. After the server has finished responding to the request, the request object is destroyed.

Consider an HTML form called "new.html," which takes certain attributes about a defect from the user as input; for example, the priority level of the defect (either 1, 2, or 3). The user clicks on the appropriate level and then clicks the Submit button. The action part of the form dictates the page that will process the input. The name of each input element in an HTML form corresponds to a request property. The name of each request is the name of the field on the associated form. When using CGI as a way to process the form element, you obtain the parameters from the URL (using the GET method or environment variable QUERY_STRING), or from the standard input via the POST method. By using the request object, it is possible to obtain the parameter values in a uniform way. Assume that new.html contains Example 3(a). The file insert.html can refer to user input in the priority field by using request.priority; see Example 3(b).

The default properties of the request object are

  • agent, the name and version information of the client's software.
  • ip, a property that provides the IP address of the client.
  • method, the HTTP protocol method associated with the request (GET, POST, or HEAD).
  • protocol, the HTTP protocol level supported by the client's software.

The request object is automatically initialized with the values for the default properties.

It is possible to pass request variables to the URL by appending a question mark. For example, in the issue-tracking tool application (to be discussed later), this facility helps determine the sorting order for the defects (priority, issueid, status, and so on).

The ordering is achieved by manually encoding request variables as follows: First, a question mark is appended, then the variable, equal sign, and the value. Multiple variables can be passed by separating the variables using the "&" sign. The variables that are encoded as a part of the URL appear as request properties, initialized with values that have been passed.

For example, in the HTML file view.html, hyperlinks enable users to sort defects in the database. The request.choice value will be "bypriority" when the request object is created for the URL request <A HREF="view.html?choice=bypriority">Priority</A>.

When an application is accessed by many clients, it is necessary to deal with each client individually, since the state of each client may be different. In a shopping-cart example, each client can have different sets of items stacked in a cart. It is also necessary to maintain these client objects between transactions. The object framework provides a choice of different techniques to deploy an application. The client object is alive for each subsequent request. Additionally, the client object can be explicitly destroyed.

Often, multiple clients use a common pool of data. The project object provides a means to share an object among them. When a new application is started, a new project object is created. Correspondingly, when the application is stopped, the project object is destroyed.

To ensure that multiple clients do not modify shared data at the same time, a locking facility is provided. This locking provision ensures that only one client may modify a project object at a given time. Other clients must wait until the client releases the lock. Consider a project involving the creation of a defect-tracking tool. One of the tool's subcomponents adds newly discovered defects. Each defect has an ID by which it can be uniquely identified. When multiple clients try to log a new defect, it is first necessary to ascertain that each defect has a unique key, namely, the ID.

Using a project object and locks, it is possible to ensure that only one client at a time can increment this ID. To obtain the last issueid in the database, the HTML file new.html makes use of a feature of server-side JavaScript called "cursors." Setting the issueid in ascending order helps ensure that the lastId is the largest. The project object is locked, and incremented by 1. The property newissueid of the client object is initialized to contain the new value used while logging the new defect and issue. Example 4 illustrates the use of the project object.

Server objects contain global data for the entire server. When multiple applications must share information, the server is indispensible. The server object provides the following default properties:

  • agent, which provides the name and version of the server software.
  • protocol, which refers to the HTTP protocol level.

Server-Side Functions

Server-side JavaScript provides functions for use in an application; some of these are used in the sample application included with this article. You can also create your own functions in a separate file and include them with any applications to be deployed. Example 5(a) can be used to define a function, while Example 5(b) can be used to find a maximum of three numbers and return the values.

A detailed description of server-side JavaScript's syntax and statement makeup is provided in the reference manuals for JavaScript.

Managing Applications

Netscape's LiveWire comes with an Application Manager that can be used to install your application using these steps:

1.Complete the application using JavaScript embedded in HTML files.

2. Use the command-line compiler or the Site Manager tool to compile the LiveWire application and link it on the server. A single output binary file is produced with a .web extension.

3. Install the application using the Application Manager. If an existing application is modified, it may be necessary to restart it. The Application Manager adds a URL prefix to reference the application, the path to the compiled binary file (.web), and the method used to maintain the client state. (You can also remove an application using the delete option.)

LiveWire provides techniques to maintain the client object on either the client or the server. The technique you use depends on the needs of the application and environment. Techniques to maintain the client object solely on the client include client cookies, and client URL encoding. Techniques to maintain the client object solely on the server include ipaddress, short cookies, and short URL encoding.

Run the application by specifying the URL to access the server with the prefix (as determined during the installation process). Trace the application execution by loading and appending the trace to the URL. The trace feature helps display the properties of the various objects.

Example Application of Server-Side JavaScript

Figure 3 shows the issue-tracking tool created using JavaScript. This tool was made with the built-in object framework and was designed to work with Informix-OnLine Dynamic Server. It is based on the Web Integrated Software Environment (WISE) project sponsored through a cooperative agreement between the NASA Software IV&V Facility in Fairmont, West Virginia, and the Concurrent Engineering Research Center (CERC) at West Virginia University. (For more information, see http://research.ivv.nasa.gov/projects/WISE/wise.html.)

Listing One is the HTML file tool.html, which contains the script required to open a connection to the database. The user is informed of any errors in connection. Netscape Navigator supports frames, a tool that can be used to create multiple scrollable regions. Each region can be assigned an individual URL and can load information independent of the other frames on the page. The main purpose of this file is to divide the web page into five frames, one each for action buttons, metrics buttons, the title, viewing all issues, and a console window to display error messages.

Listing Two is view.html, which contains the JavaScript statements necessary to print all defects and issues in the database. By default, the sorting of defects and issues is assumed to be by an ID (a unique numerical identifier).

The client object has a property choice, which is initialized by default to byid if the requested object does not have a property choice defined. A database cursor is returned as a consequence of the SELECT statement. Different types of database objects can be created depending upon the value of the client object's choice property. A table of all defects and issues is printed with a header displaying the titles for each of the columns. The cursor is used to retrieve all rows in the database that satisfy the query. Once the answer set is printed, the cursor is closed.

You should provide the flexibility to view defects and issues sorted in different orders: by choice, by status, by priority, and by category. Note the way that encoded variables have been added. When a user clicks on any hyperlinks, the requested object is created with a property choice that is initialized by either bystatus, bypriority, bycategory, or byid.

Listing Three (new.html) contains JavaScript statements that enable a client to add a new defect or issue to the database. A project object is used to update the unique ID among multiple clients. Since every defect and issue has a unique ID, it is necessary to ensure that each new issue is also assigned a unique ID or key for general referencing purposes. A lock is put on the project object whenever a client logs a new issue; other clients must wait until a unique key is assigned for their defects. A few statements are added to iterate through the database and to find the largest ID used (in this article's example, they're stored in ascending order). The ID is incremented and the clients' newissueid properties are initialized.

In most cases, it is useful to have metrics associated with an issue- or defect-tracking tool. Metrics help clients view the number of defects yet to be resolved, providing an idea of the process state. Listing Four (ovc.html) queries the database for the number of open and closed issues and prints the output. The file contains two SELECT statements, which define two cursors. Iteration is through the cursor. The variables open and closed keep track of the number of open and closed issues. The print function is used to print output in HTML format.

The new.html file (Listing Five) uses HTML to provide a fill-in form in which the user can enter data relevant to a particular defect. This file contains all the statements required to service the request from the form in new.html. When a user clicks the Submit button to submit a new issue, a new request object is created and all named elements of the form are transformed to the request object's properties. The issue is inserted using the database.execute statement.

When clients view an issue, a hyperlink reference is provided (as an action button) to remove the issue (see remove.html, Listing Six). This delete feature can be restricted to authorized users only. The encoded variables of this hyperlink contain the issue ID. A request object property is used to selectively remove the issue from the database. Once the defect and issue are deleted, control is redirected to the view.html page. Listing Seven (title.html) initializes the title of the application.

Listing Eight (action.html) targets the appropriate frame, which will display an HTML file. This file contains the necessary action buttons to view, enter a new issue, or provide online help.

Listing Nine (detail.html) prints the detail pertaining to each issue in HTML format. When view.html processes a request and displays the defects in the database, each issue's ID is displayed as a hyperlink. The hyperlink in view.html that is associated with each issue's ID has encoded variables that indicate the issue/ defect ID. Thus, when users click on the link, the request object's id property is initialized to its uniqueid, as stored in the database. The uniqueid is used to reference the issue selected by the client. Using the requestid, Listing Nine contains statements that declare a cursor; that cursor then returns an answer set with a matching ID. Subsequently, details of the issue are printed.

Finally, Listing Ten is used to compile all HTML files containing JavaScript statements into bytecode. This program must be installed using the LiveWire Application Manager.

Table 1: LiveWire object framework.

 
Object Type   Default Property   Methods               Features
           
Request       agent ip                                 Shortest lifetime. New request 
              protocol method                          created for each client 
              (from Form                               request. Destroyed when server
              Elements or                              has finished responding to 
              URLs)                                    request.
              
Client        No predefined      expiration(seconds)   All requests by the same
              property           destroy()             client will share the
                                                       same client object. Server
                                                       creates new client object
                                                       each time a new client
                                                       accesses the application.

Project       No predefined      lock ()               Contains global data
              property           unlock ()             for the entire
                                                       application.
                                                       Project object is
                                                       automatically destroyed
                                                       when the application is
                                                       stopped.

Server        agent              lock ()               Contains global data for
              protocol           unlock ()             the entire server.
              host                                     Server object is destroyed
              port                                     when the server is
              hostname                                 stopped.

Example 1: Typical server-side script.

<html>
<head> <title> Print hello program </title> </head>
<body>
<server> print("hello world"); </server>
</body>
</html>

Example 2: (a) Function definition; (b) converting a function into a method; (c) invoking a method on an object.

(a)
function init_name(name) {
    this.name = name;
}

(b)
<b>Syntax: <I>object.MethodName = FunctionName;</I></b>
cust.init_name = init_name;

(c)
<B>Syntax:<I> object.MethodName(arguments)</B></I>
cust.init_name("charles");

Example 3: (a) The new.html file; (b) using insert.html to refer to user input.

(a)
<FORM METHOD="post" ACTION="insert.html">
Priority:
<input type=radio name=priority value=1 checked>Level1
<input type=radio name=priority value=2>Level2
<input type=radio name=priority value=3>Level3
<input type=submit value=insert>
</FORM>

(b)
<server>
database.execute("insert into issue(priority)
 values ("+ request.priority "')");
</server>

Example 4: Using the project object.

<server>
project.lock();
project.lastIssueID = 0;
/* using aggregate functions to get last issue id */
cursor = database.cursor("select ID from issue");
while(cursor.next())
{
  project.lastIssueID = cursor.id;
}
cursor.close();
project.lastIssueID = 1 + project.lastIssueID;
client.newissueID = project.lastIssueID;
project.unlock();
</server>

Example 5: (a) Defining a function; (b) finding the maximum of three numbers and returning the value.

(a) function name ([param [,param......] ]) {
//server side JavaScript statements
}

(b) function max(a ,b, c) {
      var max = a;
      if (b > c ){
          if (max < b){
             max = b;
          }
      else if (max < c) {
          max = c;
      }
      return max;
    }

Figure 1: Steps required to process a request from a client.

Figure 2: Object properties.

Figure 3: An issue-tracking tool.

Listing One


<HEAD>
<TITLE> Demonstration of JavaScript Server Side Feature</TITLE>
</HEAD>
<BODY>
<! try to connect to Informix Online 7.1 >
<server>
/* Trying to connect to test database */
if(!database.connected())
{
database.connect("INFORMIX", "sumapaz_ol1shm", "", "", "test");
}
/* Print error message */
if (!database.connected())
{
print("Error: Unable to connect to database.");
}
</server>
<! create the screen dump for showing the issues using frames>
<FRAMESET ROWS="10%,75%,15%">
<NOFRAMES>
<h1 align=center><blink>Frame ALERT!</blink></h1>
<p>
This document is designed to be viewed using <b>Netscape 2.0</b>'s
Frame features. If you are seeing this message, you are using
a frame <i>challenged</i> browser.
</p>
<p>
A <b>Frame-capable</b> browser can be gotten from
<a href=http://home.netscape.com/>Netscape
Communications</a>.
</p>
</NOFRAMES>
<! assign a region for the title window >
<FRAME SRC="title.html" NAME=title MARGINWIDTH=5
MARGINHEIGHT=5 SCROLLING=NO>
<! assign a region for displaying action buttons >
<FRAMESET COLS="25%,75%">
<FRAME SRC="action.html" NAME=action MARGINWIDTH=5 MARGINHEIGHT=5 SCROLLING=NO>
<!assign a region for displaying the issues in the database>
<FRAME SRC="view.html" NAME="view" MARGINWIDTH="5"
MARGINHEIGHT="5" SCROLLING="YES" >
</FRAMESET>
<FRAMESET COLS="70%,30%">
<!region to hold action buttons for metrics>
<FRAME SRC="metrics.html" NAME=metrics SCROLLING=NO>
<!assign region for error message display>
<FRAME SRC="console.html" NAME=console SCROLLING=NO>
</FRAMESET>
</FRAMESET>
</BODY>
</HTML>


Listing Two


<html>
<head>
<title> Customer Database </title>
</head>
<body>
<server>
/*test to see if the choice property is defined */
if( request.choice != null)
{
client.choice = request.choice;
}
else
{
/*make byid the default ordering choice for viewing issues */
client.choice = "byid";
}
/*create database object based on the ordering requested*/
if (client.choice == "byid"){
cursor = database.cursor("select * from issue order by ID");
}
else
if (client.choice == "bystatus"){
cursor = database.cursor("select * from issue order by status");
}
else if (client.choice == "bypriority"){
cursor = database.cursor("select * from issue order by priority");
}
else if (client.choice == "bycategory"){
cursor = database.cursor("select * from issue order by category");
}
</server>
<!create table headers with URLs that have order choice encoded>
<TABLE BORDER>
<TR>
<TD><A HREF="view.html?choice=byid">Issue No</A></TD>
<TD COLSPAN=4><A HREF="view.html">Abstract</A></TD>
<TD><A HREF="view.html?choice=bystatus">Status</A></TD>
<TD><A HREF="view.html?choice=bypriority">Priority</A></TD>
<TD><A
HREF="view.html?choice=bycategory">Category</A></TD>
</TR>
<!Iterate through cursor and print individual records>
<server>
while(cursor.next()) {
</server>
<tr>
<td> <a
href=`"detail.html?ID="+cursor.id`><server>print(cursor.id);
</server></a></td>
<td colspan=4> <server>print(cursor.summary);</server></td>
<td> <server>print(cursor.status);</server></td>
<td> <server>print(cursor.priority);</server></td>
<td> <server>print(cursor.category);</server></td>
</tr>
<server>
}
/*close the cursor */
cursor.close();
</server>
</table>
</BODY>
</HTML>


Listing Three


<html>
<head>
<title> Creating new issue </title>
</head>
<body>
<server>
/*obtain lock on the project object*/
project.lock();
project.lastIssueID = 0;
/* using aggregate functions to get last issue id */
cursor = database.cursor("select ID from issue");
while(cursor.next())
{
project.lastIssueID = cursor.id;
}
cursor.close();
/*get unique id */
project.lastIssueID = 1 + project.lastIssueID;
client.newissueID = project.lastIssueID;
/*release lock*/
project.unlock();
</server>
<!create an input entry form for logging a new issue>
<h1> NEW ISSUE: <server> print(project.lastIssueID);
</server> </h1>
<FORM METHOD="post" ACTION="insert.html">
<table cellspacing=2 margin=3 border>
<tr><td>IssueID:</td><td>
<server>print(project.lastIssueID)</server></td>
</tr>
<input type="hidden" name="ID" value=`project.lastIssueID`
size="4"><br>
<tr>
<td>Category</td> <td>
<select name="category">
<option> error <option> change request <option> unclassified
</select> </td>
</tr>
<tr>
<td> Priority </td> <td>
<input type=radio name=priority value=1 checked>Level1
<input type=radio name=priority value=2>Level2
<input type=radio name=priority value=3>Level3
<tr>
<td>Abstract:</td>
<td><textarea rows=4 cols=50 name=summary></textarea></td>
</td>
<tr>
<td> Status: </td><td>Open </td>
<input type="hidden" name="status" value=open ><br>
</tr>
</table>
<input type="submit" value="submit Issue!">
<input type="reset" value="Reset">
</FORM>
</BODY>
</HTML>


Listing Four


<html>
<head>
<title> Customer Database </title>
</head>
<body>
<server>
/*query for number of open issues*/
var open = 0. closed =0;
cursor = database.cursor("select * from issue i where
i.status = 'open'");
while(cursor.next())
{
open = open +1;
}
cursor.close();
/*query for number of closed issues*/
cursor = database.cursor("select * from issue i where
i.status = 'close'");
while(cursor.next())
{
closed = closed +1;
}
cursor.close();
print("<h1>CURRENT STATE:</h1>");
print("<hr># of open issues:");
print(open);
print("<hr># of closed issues:");
print(closed);
</server>
</BODY>
</HTML>


Listing Five


<html>
<head>
<title> Customer Added </title>
</head>
<body>
<server>
/*insert the issue into database using the request object*/
database.execute("insert into
issue(id,summary,priority,status,category) value
s (" +
request.ID + ",'" +
request.summary + "'," +
request.priority + ",'" +
request.status + "','" +
request.category + "')");
/*
database.execute("insert into issue(id) values (" +
request.ID + ")");
*/
redirect("view.html");
</server>
</body>
</html>



Listing Six


<html>
<head>
<title> Issue Removed </title>
</head>
<body>
<server>
/*delete issue from database*/
if(request.ID != null)
{
database.execute("delete from issue where issue.id = " + request.ID)
}
redirect("view.html");
</server>
</body>
</html>


Listing Seven



<HTML>
<BODY BACKGROUND="http:/images/gray_rock.gif"
BODY TEXT="#FFFFFF"
BODY LINK="#FFFF00" VLINK="0FFFFF" ALINK="FF0000">
<PRE>
<H2> <IMG ALIGN=middle WIDTH=125 HEIGHT=20
SRC="http:/images/informix.gif">
Issue Tracking Tool </h2> (For Demo Purpose) Demonstration of JavaScript 
Server side feature, January 1996. [email protected] </PRE>
</BODY>
</HTML>


Listing Eight


<HTML>
<BODY BACKGROUND="http:/images/chalk.jpg">
<h3> ACTION BUTTONS </h3>
<P>
<IMG ALIGN=MIDDLE SRC="http:/images/tombullet.gif"><A
HREF="new.html"
TARGET="view" >New Issue</A>
<P>
<IMG ALIGN=MIDDLE SRC="http:/images/tombullet.gif">
<A HREF="help.html" TARGET="view">Help</A> <P>
<P>
<IMG ALIGN=MIDDLE SRC="http:/images/tombullet.gif">
<A HREF="view.html" TARGET="view" >Show List</A> <P>
</BODY>
</HTML>


Listing Nine


<html>
<head>
<title> Issue Details </title>
</head>
<body>
<server>
/*get details of issue matching requestID property of request object*/
if(request.ID != null)
{
client.isd = request.ID;
cursor = database.cursor("select * from issue r where r.id = " + request.ID);
}
while(cursor.next()) {
</server>
<!print the respective fields of the issue>
<h1>ISSUE NO: <server> print(cursor.id) </server></h1>
<table border>
<tr> <td>Abstract</td><td>
<server>print(cursor.summary)</server> </td></tr>
<tr> <td>Status</td><td>
<server>print(cursor.status)</server> </td></tr>
<tr> <td>Priority</td><td>
<server>print(cursor.priority)</server> </td></tr>
<tr><td>Category</td><td>
<server>print(cursor.category)</server> </td></tr>
</table>
<server>
}
cursor.close();
</server>
<hr>
<IMG SRC="http:/images/redball.gif">
<A HREF=`"remove.html?ID="+client.isd`>Delete this issue</a>
</body>
</html>


Listing Ten


 ../../bin/lwcomp -v -o tool.web tool.html new.html
   insert.html view.html remove
   .html detail.html ovc.html

	
		

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.