Chapter 6 Writing DynaScripts


Script tutorials

This section presents some simple scripts that introduce you to DynaScript.

Embedding a Script in HTML

Writing HTML with scripts

The following example shows how to embed a script into an HTML template. This script simply writes Hello world to the HTML document that is generated for the Web client.

Steps To create this script:

  1. In Sybase Central, connect to a Web site.

  2. In the left pane, click the Site folder (inside the site database).

  3. In the right panel, double-click Add Template.

  4. On the first page of the wizard, enter the template name as

    first_template


    Click Next.

  5. Enter a description if you wish. For example:

    A test template containing a simple script


    Click Next.

  6. Do not enter anything on the Add SQL Query page; click Next to move to the next page.

  7. Select <default> from the list of supplied formats.

  8. Click Finish.

    This adds first_template.stm to the Web site.

  9. Double-click the template to open it in the code editor It should look like this:

    <HTML>
    <TITLE>first_template</TITLE>
    <BODY>
    <H1>A test template containing a simple script</H1>
    </BODY>
    </HTML>


  10. After the <BODY> tag, enter:

    <!--SCRIPT
    document.Write( "Hello world" );
    -->


  11. Click File-> Save Script. This saves your updated template in the Dynamo site.


Steps To display the source code of this script:

  1. In the right pane, right-click first_template and click Open in the pop-up menu. As a shortcut, you can double-click the script icon instead.


Steps To execute the script against the application server:

  1. In the right pane, right-click first_template and click View Output in the pop-up menu.

    You see:

    <HTML>
    <TITLE>first_template</TITLE>
    <BODY>
    Hello world
    </BODY>
    </HTML>



When this script is executed from the Web site, the Web server returns this to the Web client, which in turn interprets the HTML for the user:

Hello world

Scripts are embedded in HTML templates

The script is embedded as a comment in the body of a minimal HTML document. An HTML comment is marked by a tag like this:

<!-- anything in here is a comment -->

DynaScript is comments use the SCRIPT tag, so that the application server can recognize it:

<!--SCRIPT insert script comment here
-->

Note  

JavaScript vs. Dynamo
Be careful not to confuse JavaScript SCRIPT tags with DynaScript SCRIPT tags; the syntax is very similar.

JavaScript uses this syntax:

<SCRIPT LANGUAGE="JavaScript">

DynaScript uses this syntax:

<!--SCRIPT Comments can be included here -->

The parts of the script

The body of the script consists of a single instruction:

document.Write( "Hello world" );

Here, document is a predefined object that refers to the HTML document being executed.

The statement optionally ends with a semicolon.

Objects have methods associated with them. A method is a function that carries out actions on an object. Write is a method of the document object.

An object method can take arguments and carries out actions, like a function or subroutine in other programming languages. In this case, the argument to the method is the character string "Hello world" . The Write method inserts this string into the HTML document that is sent to the client when the template is requested.

Using variables and expressions

The following example script illustrates how scripts use variables and how expressions are evaluated and assigned to variables:

<!--SCRIPT
quote = "Colorless green ideas" ;
quote = quote + " sleep furiously" ;
document.Write(quote) ;
-->

To try this script out, you can use the Sybase Central editor to replace the script in the template you created in the previous section.

The output from this script is:

Colorless green ideas sleep furiously

Declaration and assignment of variable values

You do not have to declare variables (although it is good practice to declare them anyway). Note how the first line of this script creates a variable called quote and assigns it the value of the string "Colorless green ideas" .

The + operator concatenates the two strings, and the resulting expression is assigned to the variable quote . The last line sends the value of the variable as a string to the HTML output.

Variable types and operators

Unlike variables in many compiled programming languages, Dynascript variables do not have fixed datatypes. The datatype of a variable is set whenever the variable is assigned a value. You can change the datatype of a variable by assigning it an expression of a different type.

While this is convenient for small scripts, it does require that you take care when working with variables.

The same applies to operators. For example, the meaning of the + operator depends on the expressions it is operating on. In the previous example + was used to concatenate two strings, but if it is operating on integer expressions rather than string expressions, it adds rather than concatenates the expressions. Consider the following script:

<!--SCRIPT
sum = 123 ;
sum = sum + 456 ;
document.Write(sum) ;
-->

The output from this script is the following HTML string:

579

The value of sum is set to the integer 123 in the first line. In the second line the + operator acts on the two integers, and so adds them to produce the value 579 . In the final line, this integer is converted to a string for output.

Using control statements

You can use the following control statements to allow looping or conditional execution of statements:

These statements use standard C syntax.

A script using the while statement

The following example illustrates the use of the while statement:

<!--SCRIPT
var i = 0;
while ( i < 3 ) {
svar = "This is paragraph " ;
svar += (i + 1) + "<P>" ;
document.WriteLn(svar) ;
i++ ;
}
-->

This script prints the following HTML:

This is paragraph 1<P>
This is paragraph 2<P>
This is paragraph 3<P>

Notes

Notice the way that the + operator acts in this script:

Using functions

You can define and use functions in scripts, which allows you to encapsulate a set of instructions once in a document, and use it several times throughout the document.

The following example shows how to provide consistent custom formatting across headings in an HTML document:

<HTML>
<TITLE>Function testing</TITLE>

<BODY>
<!--SCRIPT

function h1( headingString) {
heading = "<H1><FONT SIZE=5><FONT COLOR='000080'>" + headingString + "</FONT></H1>" ;
document.Write( heading ) ;
}

h1( "This heading formatted by a script" ) ;
-->
</BODY>
</HTML>

Notes

Note the following in this example:

Using simple objects

DynaScript is object-oriented. An object can have properties (data) associated with it, as well as methods (functions that act on the properties). You can use the predefined objects included with Dynamo, or create your own custom objects.

For example, you could create a class of object called product . You can add properties to store all the information about a product (such as the product ID, name, color, size, description, price, and quantity in stock). You can also add methods that carry out typical actions on the product, such as ordering a certain quantity.

Using an object

There are two steps to using an object:

  1. Declare the structure of the object using a function or class statement.
    This defines the name of the class, and its properties and methods. Inside the class definition, the properties and methods identify themselves as class members by using the prefix this .
  2. Create an instance of the class using the new operator.

For example, the following class statement defines the product class:

class product(id, name, size, color,
quantity, price) {
this.id = id ;
this.name = name ;
this.size = size ;
this.color = color ;
this.quantity = quantity ;
this.price = price ;
}

To create currentProduct , which is an actual object (or instance) of the product class, use new with the appropriate property values:

var currentProduct = new product(600, "Sweatshirt",
"Large", "Green", 39, 24.00 ) ;

Note  

Using objects In practice, you could have an application that takes an ID from an HTML form filled out at a Web client, and use that ID together with a SQL query to fill out the properties of the currentProduct object. Combining scripts with SQL queries and responding to user input are discussed in later sections.

Defining methods for an object

So far, the product class has properties, but no methods to act on those properties. To add a method to an object, you must:

  1. Define a function that carries out the actions you want.
    You can define the function inside the class definition, or as a global definition (outside the class definition).
  2. Assign the function to the class.

For example, you could define an order method for the product class, which carries out the proper actions when a product is ordered:

function order ( orderQuantity ) {
// order returns true if the order is successful,
// false if stock is too low
if ( this.quantity >= orderQuantity ) {
this.quantity -= orderQuantity ;
return ( true ) ;
} else {
return ( false ) ;
}
}

Since we've declared order as a global function in our script, its definition must precede the definition of the product class. We can then make the order function a method of product by adding a line to the class definition:

class product( id, name, size, color,
quantity, price ) {
this.id = id ;
this.name = name ;
this.size = size ;
this.color = color ;
this.quantity = quantity ;
this.price = price ;
this.order = order ;
}

Since we haven't added any new properties, creating a new instance of the product class is the same as it was before:

var currentProduct = new product(600, "Sweatshirt",
"Large", "Green", 39, 24.00 ) ;

You could then use the order method in a template as follows:

<!--SCRIPT
var orderQuantity = 20 ;
status = currentProduct.order( orderQuantity ) ;
if (status) {
document.WriteLn( "Your order for " +
orderQuantity + " " + currentProduct.name
+ "s succeeded.") ;
document.WriteLn( "Now in stock: " +
currentProduct.quantity + ".") ;
} else {
document.WriteLn( "Your order for " +
orderQuantity + " " + currentProduct.name
+ "s failed.") ;
document.WriteLn( "We only have " +
currentProduct.quantity + " in stock.") ;
}
-->

Using arrays

Arrays are useful for keeping track of a collection of objects. Typically, you index a variable using integers, as in this example of three prices:

price = new Array(3);
price[0] = 19.95;
price[1] = 42.99;
price[2] = 0.02;

A common programming construct is a loop that performs some action on each element of an array. The loop variable iterates over the index of the array, as in the following example:

for ( i = 0 ; i < price.length; i++ ) {
document.WriteLn("Price of item #" +
i + " = " + price[ i ] );
}

This produces the following output:

Price of item #0 = 19.95
Price of item #1 = 42.99
Price of item #2 = 0.02

Passing variables from one document to another

Some functions must be able to receive and act on user input from the Web client. This information is sent by the Web client when a form is filled out as part of the Uniform Resource Locator (URL) that retrieves the form.

For example, suppose the Web client displays a form containing a list box, a text box, and an Order button. The user selects a particular product from the list, enters the desired quantity in the text box, then clicks the button to order the product.

The Order button points to an order-processing template that has a URL of http://www.sybase.com/products/order.html. When the Order button is clicked, the Web client sends the URL along with arguments that specify the order information. For example, if the user orders 25 of product #600, the complete URL would be:

http://www.sybase.com/products/order.html?id=600&quantity=25

The question mark separates the address of the document from the arguments supplied to the document. An ampersand separates each of the arguments in the list. In this example, the two arguments id and quantity are sent, with values 600 and 25 respectively.

Referring to arguments in the document

You can fill in the value of a supplied argument in the HTML part of a document by preceding the value with a dollar sign. For example:

<HTML>
<TITLE>Displaying variables</TITLE>
<BODY>
The value of argument quantity is $quantity.
</BODY>
</HTML>

If this template is called with this URL:

http://address?quantity=25

the following HTML is returned to the Web client:

<HTML>
<TITLE>Displaying variables</TITLE>
<BODY>
The value of argument quantity is 25.
</BODY>
</HTML>

Using arguments in scripts

You can also use arguments inside scripts. The argument is a property of the document, which is a predefined object. The actual value of an argument named quantity can be accessed inside a script as:

document.value.quantity

The following script responds to user input for an order:

<!--SCRIPT
var currentProduct = new product(600, "Sweatshirt",
"Large", "Green", 39, 24.00 ) ;
var orderQuantity = document.value.quantity ;
var retval = currentProduct.order(orderQuantity) ;
if (retval) {
document.WriteLn( "Your order for " +
orderQuantity + " " + currentProduct.name +
"s succeeded.") ;
document.WriteLn( "Now in stock: " +
currentProduct.quantity + ".") ;
} else {
document.WriteLn( "Your order for " +
orderQuantity +
" " + currentProduct.name + "s failed.") ;
document.WriteLn( "We have only " +
currentProduct.quantity + " in stock.") ;
}
-->

For information on passing values of a multiple selection list see "value property" in PowerDynamo Reference.

Using object inheritance

DynaScript extends JavaScript to include inheritance, which is the ability to create a new class of object that extends an existing class. The new class inherits all of the properties and methods of the parent class, and adds its own properties and methods.

This is tremendously useful when you are dealing with objects that share characteristics. Instead of defining each object separately, you can identify the information and behavior that is common to them, then define the objects themselves as extensions of the common material.

Without inheritance

For example, suppose that Acme Widgets has some employees that are paid a salary, while others are paid by the hour. You could define two separate classes, salariedEmployee and hourlyEmployee , with their own sets of properties and methods. Here's a simple version:

class salariedEmployee(name, title, managerName,
salary)
this.name = name;
this.title = title;
this.managerName = managerName;
this.salary = salary;
function PrintNameAndTitle() {
document.WriteLn("Name, title: " + this.name
+ ", " + this.title); }
this.PrintNameAndTitle = PrintNameAndTitle;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
document.WriteLn("Salary: " + this.salary); }
this.PrintAllInfo = PrintAllInfo;
}
class hourlyEmployee(name, title, managerName, wage)
this.name = name;
this.title = title;
this.managerName = managerName;
this.wage = wage;
function PrintNameAndTitle() {
document.WriteLn("Name, title: " + this.name
+ ", " + this.title); }
this.PrintNameAndTitle = PrintNameAndTitle;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
document.WriteLn("Hourly wage: " + this.wage); }
this.PrintAllInfo = PrintAllInfo;
}

With inheritance

Because there is a lot of duplication between the two classes of employees, you'll be maintaining two nearly identical sets of code. Suppose instead that we take the common items (name , title , managerName , and PrintNameAndTitle ) and move them into a new generic class called employee :

class employee(name, title, managerName) {
this.name = name;
this.title = title;
this.managerName = managerName;
function PrintNameAndTitle() {
document.WriteLn("Name, title: " + this.name
+ ", " + this.title); }
this.PrintNameAndTitle = PrintNameAndTitle;
}

We can then change salariedEmployee and hourlyEmployee to use this new employee class as their common parent. To do this, we use the extends clause of the class statement:

class salariedEmployee(name, title, managerName, salary)
extends employee(name, title, managerName) {
this.salary = salary;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
document.WriteLn("Salary: " + this.salary);
}
this.PrintAllInfo = PrintAllInfo;
}
class hourlyEmployee(name, title, managerName, wage)
extends employee(name, title, managerName) {
this.wage = wage;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
document.WriteLn("Hourly wage: " +
this.wage);
}
this.PrintAllInfo = PrintAllInfo;
}

We can then try out the redefined classes by creating salaried and hourly employees, then printing their information:

var salaryEmp = new salariedEmployee("Ned Simpson", "Technical Writer", "Barney Burns", 80000);
salaryEmp.PrintNameAndTitle();
salaryEmp.PrintAllInfo();
document.WriteLn("");
var hourlyEmp = new hourlyEmployee("Marge Flanders", "Contractor", "Barney Burns", 25);
hourlyEmp.PrintNameAndTitle();
hourlyEmp.PrintAllInfo();

This produces the following output:

Name, title: Ned Simpson, Technical Writer
Name: Ned Simpson
Title: Technical Writer
Reports to: Barney Burns
Salary: 80000
Name, title: Marge Flanders, Contractor
Name: Marge Flanders
Title: Contractor
Reports to: Barney Burns
Hourly wage: 25

There are several things to note here:

 


Copyright © 1999 Sybase, Inc. All rights reserved.