Print

Learning WML: Tasks and Events
Pages: 1, 2, 3, 4, 5, 6

Events

An event in WML is simply something that can happen to some element from time to time. For example, entering a <card> element triggers an event on the <card>, and selecting an <option> from a selection list triggers an event on the <option>.

You can harness these events by binding them to a task. The usual way of doing this is with the <onevent> element. As mentioned earlier in this chapter, for simple <go> tasks you can usually make use of a simpler form: this will be mentioned when when we discuss the elements in question.

For example, the <option> element (detailed in Chapter 4) declares an item in a list of selections. When this item is selected, it triggers an onpick event on the <option> element. Suppose the element were declared without an event handler, like this:

<option>
    Purple
</option>

In this case, the onpick event is ignored, since there is no handler. If, on the other hand, the option is declared as:

<option>
    <onevent type="onpick">
        <go href="#purple"/>
    </onevent>
 
    Purple
</option>

the onpick event is handled by executing the <go> task, sending the browser to a new card.

The <onevent> Element

The <onevent> element declares an event binding. It can't contain anything except a single task element that is performed when the event occurs. It may be present inside either an <option> element (see Chapter 4) or a <card> element (see Chapter 6). In either case, the <onevent> element (or elements) must be the first elements declared inside their enclosing element.

The <onevent> element takes only one attribute:

type (required string)
Gives the type of event to which the task should be bound. For example, use type="ontimer" to bind to the ontimer event of a <card> element.

Card Events

Sometimes, you may want to do something special when the user enters a particular card. For example, you may want to initialize the values of variables so that the display looks correct. Another thing you may want to do is to clear out some variables when the user returns to a particular card in the history stack.

To make this possible, WML defines two events, onenterforward and onenterbackward, which happen on a <card> element when the user enters it. Which event occurs depends on how the card was entered.

The onenterforward event

The onenterforward event occurs when a card is entered in the forward direction. Entering as a result of a <go> task, selecting a bookmark, or entering a URL directly are all in the forward direction. The most common use of this event is to initialize things that must be set up before the card is displayed, often by using a <refresh> task or by using a <go> task to run some WMLScript (see "Calling WMLScript from WML" in Chapter 13, WMLScript Functions).

Example 3-2 shows how this can be used. When the first card is entered forwards, the <refresh> task is performed, which initializes the state variable. This variable can then be updated by other WML pages and is passed through to the server by the <go> task.

Example 3-2: Initialization on Entry

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC
    "-//WAPFORUM//DTD WML 1.1//EN"
    "http://www.wapforum.org/DTD/wml_1.1.xml">
 
<wml>
    <card title="onenterforward example">
        <!-- Initialize state to zero on first entry. -->
        <onevent type="onenterforward">
            <refresh>
                <setvar name="state" value="0"/>
            </refresh>
        </onevent>
 
        <!-- Collect some information from the user. -->
        <p><input name="text"/></p>
 
        <!-- Send the text and the state to the server. -->
        <do type="accept">
            <go href="submit.cgi">
               <postfield name="s" value="$(state)"/>
               <postfield name="t" value="$(text)"/>
            </go>
        </do>
    </card>
</wml>

If the task bound to the onenterforward event is a simple <go> task without <setvar> or <postfield> elements, you can use the shorthand form introduced earlier in this chapter: just add an onenterforward attribute to the <card> element. The value of this attribute is the destination URL.

For example, the event binding:

<card title="example">
    <onevent type="onenterforward">
        <go href="#card2"/>
    <onevent>
 
    <!-- rest of card -->
</card>

is equivalent to the shorter form:

<card title="example" onenterforward="#card2">
    <!-- rest of card -->
</card>

It's your choice to use the shorthand form, but it means less typing and results in less data being sent to the browser.

WARNING:  

Be warned that not all tasks you can bind to the onenterforward event actually make sense. For example, the event binding:

<onevent type="onenterforward">
    <prev/>
</onevent>

makes it impossible for the user to enter the card at all: as soon as she went to the card, the browser would immediately return to the previous one!

To make matters worse, the event binding:

<card id="card1" onenterforward="#card1">

means that as soon as the browser entered the card, it would be immediately redirected to the same card, which would cause an immediate redirect to the same card, and again, and again. . . . Well-written browsers may notice this and signal an error, but not all browsers are well-written: many simply lock up or even crash.

The onenterbackward event

The onenterbackward event is the companion of the onenterforward event for the backward direction. This event is triggered when the card is returned to as the result of a <prev> task or some other action that navigates backwards in the history stack.

The most common use for the onenterbackward event is to reset state back to some initial value when returning to the beginning. Example 3-3 alters Example 3-1 to illustrate this: instead of an explicit reset button, the login and password are cleared when the user returns to this card via the history stack.

Example 3-3: Reset on Reentry

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC
    "-//WAPFORUM//DTD WML 1.1//EN"
    "http://www.wapforum.org/DTD/wml_1.1.xml">
 
<wml>
    <card title="Reset on reentry example">
        <!-- Reset fields when entered backwards. -->
        <onevent type="onenterbackward">
            <refresh>
                <setvar name="login" value=""/>
                <setvar name="password" value=""/>
            </refresh>
        </onevent>
 
        <!-- Read login and password from user. -->
        <p>Login:    <input name="login"/></p>
        <p>Password: <input name="password"/></p>
 
        <!-- Submit button sends data to server. -->
        <do type="accept" label="Submit">
            <go href="login.cgi" method="post">
                <postfield name="l" value="$(login)"/>
                <postfield name="p" value="$(password)"/>
            </go>
        </do>
    </card>
</wml>

Just as with the onenterforward event, onenterbackward also has a shorthand form in the case where the task is a simple form of <go>, meaning that the event binding:

<card title="example"> 
    <onevent type="onenterbackward">             
        <go href="foo.wml"/>  
    </onevent> 
  
    <!-- rest of card --> 
</card> 

is equivalent to:

<card title="example" onenterbackward="foo.wml"> 
    <!-- rest of card --> 
</card>

Martin Frost is the author of Learning WML & WMLScript


Return to the Wireless DevCenter.