Table of Contents
In LZX, the concepts of methods, events, handlers and attributes are related to each other in a braid-like way. In this chapter we'll show you how they weave together.
Attributes, events, methods and handlers are all properties of classes that define how instances of the class behave. Attributes represent the state of the instance. Events are signifiers that communicate with the rest of the application when something about the instance changes. Methods are blocks of JavaScript that are executed when the method is invoked by name. Handlers are a special kind of method, each specifically tied to an event.
When an event occurs, any handler associated with that event gets called. Events may have any number of handlers, and handlers can be used to glue events from one instance to methods in another.
Because LZX allows you to add properties to instances, you can add attributes, events, methods and handlers to any instance. (In the terms of other object oriented languages such as Java, effectively LZX allows you to define a class of which there is exactly one instance with the new properties.)
 In LZX you use attributes, events, and handlers to describe how your application
                        responds to user input or other changes. In general, and to a first approximation, when an
                           attribute changes value, it can generate an event . (See below for an qualification of when setting an
                        attribute's value does and does not cause and event to be sent.) You can additionally
                        declare events with an <event>
                         tag. Your application's response to that event is determined by
                        the associated event handler, which is defined in a <handler>
                         tag. 
            
Methods, events and attributes are the only concepts you need for many kinds of applications. Certain kinds of more subtle event-driven situations require a fourth concept, delegates, which are described in Chapter 30, Delegates.
 In the discussion below we'll assume a commonsense understanding of the meaning of <attribute>
                         . Attributes are examined more thoroughly at the end of this
                        chapter. 
            
 A <method>
                         is an 'action', expressed in JavaScript you can perform on an
                        instance. You can call it from any script. 
            
 Methods may be defined inside any <node>
                         or <view>
                         (or classes derived from them). When defining a method, you must
                        specify a value for the name attribute. The value of the name attribute represents the name by
                        which you will call this method in script. When you call the method, you use its name
                        followed by open and close parentheses -- any arguments to the method would be placed
                        within the parentheses. 
            
 You cannot include a <method> within a dataset --
                        if you do it will be considered data, not an operation to be performed. 
            
 In the following example, the myMethod() method is defined in the only node in the
                        example. It is called by the line in the script myNode.myMethod(). (By
                        using the ID, the node can be referenced from anywhere in the program, including this
                        script block). 
            
Example 29.1. Defining a method
<canvas height="30" width="100%">
  <text id="message"> 
    <method name="myMethod">
      this.setAttribute('text', 'Nice day if it doesn\'t rain.');         
    </method>
  </text> 
  <script>
    message.myMethod()
  </script>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  Choose method names carefully. Names should be descriptive, to help you and other readers of your code understand what they do. You need also to keep in mind that when you extend a class, your new class inherits the methods of the class from which it was extended. If you give a new method the name of already existing method, the original method will be overridden. To avoid such "naming collisions" you should consult the LZX Reference, which lists all methods for all Laszlo Foundation Classes (LFC).
When you create a class by extending another one, the new class inherits all the methods of the original. You can then give a new definition to any of the inherited methods; this is called overriding. See Chapter 33, Extending Classes for a complete discussion.
 The method attribute 'args' is used to pass arguments to a
                              method. The value of the 'args' attribute is a string containing variable names
                              separated by commas. In the following example, two arguments 'a' and 'b' are declared in
                              the args attribute of the method named 'add'. To call this method in script to add the
                              number 1 to the number 2, you would write myNode.add(1, 2);
                           
               
Example 29.2. Defining a method with arguments
<canvas height="50" width="100%">
  <text id="message">
    <method name="add" args="a,b">
      var sum = a + b;
      this.setAttribute('text', ('a + b = ' + sum));          
    </method>
  </text>
  <script>
    message.add(4,9)
  </script>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      Sometimes when you write a method, you want the result to be returned to the calling
                              script for further processing. In the following example, returnsum()
                              method uses the 'return' keyword. In the script block, this value is used in turn to
                              compute another. 
               
Example 29.3. Returning data from a method
<canvas height="50" width="100%">
  <text id="message" multiline="true">
    <method name="returnsum" args="a,b">
      var sum = 3 + 4;
      this.setAttribute('text', ('a + b = ' + sum));          
      return sum;
    </method>
  </text>
  <script>
    var x = 5;
    var y = message.returnsum();
    var z = x + y;
    message.addText('\nz equals ' +  z)
  </script>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.             *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                     In LZX, changes in the status of objects are communicated through events. Events can be used to trigger the execution of script. The script to be executed can be contained in an event handler, as explained in this chapter, or in a method that is invoked by a delegate as explained in Chapter 30, Delegates.
 Events can be defined either implicitly or explicitly. Implicit events are associated
                        with attributes. Explicit events are declared with the <event>
                         tag. 
            
 In addition to the events that you define, there are also events that are built into
                        the LFC but which are not associated with any attribute. Examples include onclick and onfocus. 
            
Unlike events in similar systems, OpenLaszlo's events are point-to-point, meaning that there is no general broadcast mechanism for events, and events do not trickle up or down the instance hierarchy. Declaring an event that no handler (or delegate) is listening for has no effect. This allows objects to publish many more events than they actually need to create at runtime; this allows you flexibility in prototyping.
 Any defined attribute has an associated event called "on" plus the name of the
                              attribute. Whenever the value of any attribute is updated using the setAttribute(), its associated "on" event is
                              generated. For example, the height attribute of a
                              view has an associated onheight event that is
                              generated whenever the view's height changes. These events are implicit in the sense
                              that they are built into the system — you don't have to declare them or send them. 
               
 Said another way, the default behavior of the setAttribute() method is to set the named property
                              and send the event. For instance, when a view changes its x position, it sends the event onx with the new value for its x
                              property. 
               
 In addition to the implicit event associated with each named attribute, LFC classes
                              have a variety of additional events associated with them. For example, the <view> tag has an onclick event that is generated
                              whenever the user clicks the mouse while the cursor is positioned over the view— even
                              though there is no attribute named "click". See the LZX Reference Manual
                              for a complete list of events associated with LFC classes. 
               
 In addition to built-in and implicit events, you can explicitly declare events with
                              the <event>
                               tag. 
               
 Note that in 3.n and earlier releases, you can send events that have not been
                              explicitly declared. However, this is not a good practice, and applications that rely on
                              this will break with release 4.0. Therefore, it's good to get in the habit of declaring
                              any events that you know you will send by calling sendEvent(). 
               
 When you create an event using the <event>, you are creating
                              an instance of the class called LzEvent. You can then call the sendEvent() on this class to explicitly cause the
                              event to be sent. 
               
Example 29.4. sendEvent
<button name="framitzbutton" onclick="sendframitz()">
     Send framitz event
     <event name="framitz"/>
     <method name="sendframitz">
      framitz.sendEvent()
     </method>
 </button>
 You shouldn't send an event for which no handler has been defined. That is to say,
                              it is fine to define an event (using the <event> tag) for which no
                              handler exists. This is often useful to to in prototyping. But don't send it unless you
                              know that there is a handler for it. 
               
Note that there is virtually never any reason to create an event in script by creating a new LzEvent. Likewise, there is virtually never any reason for you to use any method on this event other than sendEvent. Other methods are used internally within the Laszlo Foundation Classes; they are not intended for user code.
An event handler is the code that is executed when an event is received. An event can have zero or more handlers.
There are two syntaxes that you can use to define handlers:
 For convenience, you can use the onevent syntax for short handlers for some kinds of
                        events, such as onclick, as explained below. For readability, however, the <handler> syntax is often
                        better. 
            
 The "onevent" syntax is available for attributes that correspond to the CSS event
                              model—onclick, onmouseover, and so forth. For such events, the simplest way to declare
                              an event handler is simply to include it in the definition tag of the node that contains
                              the attribute. This syntax does not work for other events generated by class attributes;
                              for those you must use the <handler> syntax. 
               
In the example below, the event handler for the event generated by the user mouse click changes the views's color from red to blue.
Example 29.5. Event handler defined in opening tag
<canvas height="50" width="100%">
   <view height="30" width="30" bgcolor="red" onclick="setAttribute('bgcolor', 'blue')"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007-2009 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                     The <handler>
                               tag defines how an instance responds to an event. A handler
                              can either specify the code to handle an event or it can specify a method that should be
                              invoked to handle the event. Any event can have an unlimited number of handlers
                              associated with it. 
               
 The <handler> tag defines
                                    code that is executed when an event that has the name of the handler is fired. The
                                    name of the handler is the same as the name of the event with which it is associated.
                                    For example, the "onclick" event is handled by a handler also named "onclick". Event
                                    handlers defined in this way are executed whenever their associated event occurs. 
                  
The following example shows how you might handle a button click:
Example 29.6. A simple handler
<canvas height="40" width="100%">
  <button text="not clicked">
    <handler name="onclick">
      this.setAttribute('text', 'clicked'); 
    </handler>
  </button>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        An event can have associated with it any number of handlers. When that event is sent, all handlers associated with it are executed.
Example 29.7. Multiple handlers for single events
<canvas height="100" width="100%">
   <text y="20" id="message" multiline="true"/>
   <button>
      Howdy!
      <handler name="onclick">
         message.addText("\nhandler one")
      </handler>
      <handler name="onclick">
         message.addText("\nhandler two")
      </handler>
      <handler name="onclick">
         message.addText("\nhandler three")
      </handler>
   </button>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      A handler may include JavaScript code to be executed when the associated event
                              occurs, or it may reference a method that contains the code to be executed. To reference
                              another method, use the method attribute of the <handler> tag.
               
Example 29.8. Calling a method from a handler
<canvas height="50" width="100%">
  <simplelayout/>
  <view name="myview" height="30" width="30" bgcolor="blue"/>
  <button>
    Make red the blue box!
    <handler name="onclick" method="redify"/>
    <method name="redify" args="v">
      parent.myview.setAttribute("bgcolor", "red")
    </method>
  </button>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                     A handler is not overridable in a subclass, so you can add as many handlers as you like to an event and they will all fire.
If you want a subclass to be able to override the handling of an event in a superclass, the superclass would associate a method with the event by:
<handler name="eventName" method="methodName" />
 And the subclass would overrride methodName. 
               
Recall that a method is an 'action' you can perform on an instance, and that you can call it from any script. You could call it from a handler. For example, the usage above can be written longhand as:
<handler name="eventName"> this.methodName(); </handler>
If you want the superclass to define a handler that the subclass can override, you would have the handler point to a method, and in the subclass you just override the method. Let's repeat that to make it clear: when you want the subclass to have a different behavior than the superclass, don't attempt to override the handler in the subclass, and don't create a new handler in the subclass. Instead, have the handler in the superclass call a method, and then in the subclass, override that method. Try this example, which hopefully makes all clear:
Example 29.9. Overriding an event-handler method in a subclass
<canvas height="200" width="100%">
  <class name="base" extends="button">
    <handler name="onclick" method="handleonclick"/>
    <method name="handleonclick" args="v">
      message.addText("\nbase click");
    </method>
  </class>
  
  <class name="subaccumulate" extends="base">
    <handler name="onclick">
      message.addText("\nsubaccumulate click");
    </handler>
  </class>
  
  <class name="suboverride" extends="base">
    <method name="handleonclick" args="v">
      message.addText("\nsuboverride click");
    </method>
  </class>
  <subaccumulate>accumulate</subaccumulate>
  <suboverride>override</suboverride>
  <text id="message" multiline="true"/>
  <simplelayout/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                     Here is the same example with instances:
Example 29.10. Overriding an event-handling method in an instance
<canvas height="200" width="100%">
  <class name="base" extends="button">
    <handler name="onclick" method="handleonclick"/>
    <method name="handleonclick" args="v">
      message.addText("\nbase click");
    </method>
  </class> 
  <base text="Accumulate">
    <handler name="onclick">
      message.addText("\nsubaccumulate click");
    </handler>
  </base> 
  <base text="Override">
    <method name="handleonclick" args="v">
      message.addText("\nsuboverride click");
    </method>
  </base>
  <text id="message" multiline="true"/>
  <simplelayout/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
  * Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
  * Use is subject to license terms.                                            *
  * X_LZ_COPYRIGHT_END ****************************************************** -->
                      Suppose you want to handle, in one class, an event from some other object? In that
                              case, you would use the reference attribute: 
               
<handler name="onclick" reference="yours">
  Debug.debug("Someone is pushing your button");
</handler>
 Here's an example using <text>:
               
Example 29.11. Referencing an event in another object
<canvas height="200" width="100%">
  <class name="base" extends="button">
    <handler name="onclick" method="handleonclick"/>
    <method name="handleonclick" args="v">
      Debug.debug("base click");
    </method>
  </class>
  <simplelayout/>
  <base id="yours" text="Yours">
    <handler name="onclick">
      message.addText("\nYour click");
    </handler>
  </base>  
  <base text="Mine">
    <method name="handleonclick" args="v">
      message.addText("\nMy click");
    </method>
    <handler name="onclick" reference="yours">
      message.addText("\nSomeone is pushing your buttons.");
    </handler>
  </base> 
  <text id="message" y="40" multiline="true"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                     Note that Mine handles a click on Yours. Even though the handler is in Mine, it only runs when you click Yours.
 As has been discussed above, you can cause an event to be sent explicitly, by
                              defining the event and then calling the sendEvent() on it. Or, you can use the setAttribute() method to implicitly define and send
                              an event. A third way of defining events, using delegates, is explained in Chapter 30, Delegates. 
               
Example 29.12. Different ways to send events
<canvas width="100%" debug="true">  
    <class name="myclass_with_handler">
        <event name="myevent"/>
        <handler name="myevent" args="myargs">
            Debug.debug("%#w handling myevent, myargs = %w", this, myargs);
        </handler>       
        <attribute name="season" type="string" value="spring"/>
        <event name="onseason"/>
        <handler name="onseason" args="s">
            Debug.debug("got season of %w, season is %w", s, season);
        </handler>
    </class>   
    <myclass_with_handler id="foo"/>
    <simplelayout axis="x" spacing="5"/>
    <button onclick="foo.myevent.sendEvent(12)" text="send the event"/>
    <button onclick="foo.setAttribute('season', 'fall')" text="autumn"/>
    
    <!-- Don't do this! Setting an attribute directly with '=' shortcuts around
        the event system. This is not right; use setAttribute instead -->
    <button onclick="foo.season='winter'" text="evil"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.             *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      As is explained in Chapter 30, Delegates, an event doesn't really exist unless
                              and until there is a delegate registered to receive it. In code that was written before
                              the <event> tag became part of
                              the language, before sending an event it was necessary to test whether the receiving
                              delegate existed; otherwise an error resulted. In order to create your own event, you
                              needed to create an attribute like this:
               
<attribute name="onsomeevent" value="null"/>
 Then, you had to check to see if it was a valid LzEvent before calling sendEvent() on it. Ways of making
                              that test look like this:
               
    if ( onsomeevent instanceof LzEvent) {
       onsomeevent.sendEvent();
    }
or like this:
    if (classroot.onactivate) {
       classroot.onactivate.sendEvent();
    }
 If you use the <event> and <handler> syntax, you do
                              not have to worry about such tests. (The delegates are handled for you by the runtime.) 
               
Attributes define properties of instances of classes. For example, consider the <view> element. It has more than forty defined attributes, such as x, y, and bgcolor. Some of these attributes are defined on <view>, and others are inherited from <node> from which it derives. These attributes are specified in the schema that defines the LZX tags. Each attribute has a type,
               for example: number, boolean, and string.
            
 Once an attribute has been defined, you can use it in the open tag for that class. For
                        example, name is a defined attribute of view, so
                        you can write 
            
<view name="charlie"/>
 But, for example, framitz is not a defined attribute of
                           <view>, so this would generate an error: 
            
<view framitz="whatnot"/>.
 You can define new attributes using the <attribute>
                        tag, for example: 
            
<view name="bob"> <attribute name="framitz"/> </view>
An attribute can be an element of a tag or a property of a JavaScript class. Attributes are declared and set in tags, but they can also be set and read in script. Not all attributes can be set in script, similarly not all attributes can be in tags. Attributes are characterized based on this behavior into four categories, described in Section 5.1, “Categories of Attributes”.
An attribute can be declared in a tag header as follows:
Example 29.13. Setting an attribute value in the tag header
<canvas height="20" width="100%">
  <view width="20" height="20" bgcolor="red"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  An alternative (although more verbose) way to set the attribute is using the
                           <attribute> tag as a child of the tag whose attribute
                        is being set:
            
Example 29.14. Using the attribute element to set an attribute value
<canvas height="20" width="100%">
  <view>
    <attribute name="width" value="20"/>
    <attribute name="height" value="20"/>
    <attribute name="bgcolor" type="color" value="red"/>
  </view>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  This second example is the same as saying <view width="20" height="20"
                           bgcolor="red"/>. The <attribute> tag is useful for
                        writing classes as well as for performing complicated constraints of existing attributes.
            
In script, the values of most attributes can be retrieved using dot syntax:
Example 29.15. Using dot syntax to retrieve an attribute value
<canvas height="40">
  <simplelayout/>
  <view name="myView" width="20" height="20" bgcolor="red"/> 
  <text oninit="this.format('myView.width = %d', myView.width)"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  All attributes that are settable in script (see below) can be set using  
                              setAttribute():
            
Example 29.16. Using setAttribute() to set an attribute value
<canvas height="20" width="100%">
  <view width="20" height="20" bgcolor="red" oninit="this.setAttribute('width', 50);"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  Attributes can be placed into four categories according to how they are set, read, and modified.
read/write attributes
                        
event-handler attributes
                        
initialize-only attributes
                        
read-only attributes
                        
These are described briefly in the following sections.
read/write attributes may be modified at runtime and be the
                                    target of a constraint expression. When setAttribute() is called
                                    the value of the attribute will be updated, along with any constraints that depend on
                                    the attribute. The value of an attribute can be retrieved through script using dot
                                    syntax, (for example, myView.opacity).
                  
For example:
Example 29.17. read/write attributes
<canvas height="20">
    <view id="myView" onclick="setAttribute('opacity', 1.5 - this.opacity)" bgcolor="red">
        <text text="${'My opacity is ' + myView.opacity + '. Click to change it.'}"/>
    </view>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        event-handler attributes are instructions for what to perform
                                    when a particular event happens. They always contain script, and cannot be changed at
                                    run-time (that is, from script). Their values cannot (and do not need to) be
                                    retrieved from script.
                  
Example 29.18. event-handler attributes
<canvas height="150" debug="true">
    <view width="50" height="50" bgcolor="red" onclick="Debug.write('Hello, World!');"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        There is a long-hand version for event-handler attributes, just
                                    like normal attributes:
                  
Example 29.19. long-hand version for event-handler attributes
<canvas height="40">
    <text>
        Click me!
        <handler name="onclick">
            this.setAttribute('text', 'Hello World!');
        </handler>
    </text>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        initialize-only attributes are declared and set in the tag, but
                                    cannot be changed in using script. Good examples of
                                    initialize-only attributes are name and
                                       id. They can be read from script using dot syntax.
                  
Example 29.20. initialize-only attributes
<canvas height="40">
    <text id="myID">
        Click me!
        <handler name="onclick">
            this.setAttribute('text', this.id);
        </handler>
    </text>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        read-only attributes, sometimes called
                                    fields, are only accessible using script. Since they are
                                       read-only, they cannot be set in a <tag>. Their
                                    values can be retrieved using dot syntax.
                  
Example 29.21. read-only attributes
<canvas height="130" debug="true">
    <debug y="30"/>
    <text id="myID">
        Click me!
        <handler name="onclick">
            Debug.format("canvas.subviews: %w", canvas.subviews);
        </handler>
    </text>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 - 2009 Laszlo Systems, Inc.  All Rights Reserved.            *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                        The <attribute> tag has two uses.
            
In a class definition, the <attribute>
                         tag defines attributes that can be set in instances of the
                        class. For example:
            
Example 29.22. Defining an attribute in a class
<canvas height="36" width="100%">
  <class name="diamond" width="${this.size}" height="${this.size}" rotation="45">
    <attribute name="size" type="number"/>
  </class>
  <diamond size="25" x="36" bgcolor="red"/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                  You can also use an instance to extend a class, just like a new class would (but without defining the class, if you only need one instance). So, just as in a class, the attribute element can be used to define an additional attribute.
In an instance, the <attribute> element sets the
                        attribute of the object that it is attached to. In this use, the <attribute> element is
                        equivalent to the use of an attribute in a tag header. For example, the following program
                        uses a tag element to set the width of the view, and an <attribute> tag to set its
                        height.
            
Example 29.23. Defining an attribute in a view
<canvas height="25" width="100%">
  <view width="25" bgcolor="red">
    <attribute name="height" value="25"/>
  </view>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                   In the example above the width is set in the tag header and the height is set using the <attribute> tag. These
                        syntaxes are functionally equivalent for attributes that are defined in the LZX schema—that
                        is, attributes that are part of LZX. As we will show later, using the <attribute> can increase
                        readability. 
            
 You can also define new attributes. For these you must use the <attribute> tag.
            
Attributes can be constrained to the value of other attributes. See the Chapter 27, Constraints for details.
 By default, attributes are of the JavaScript expression type, but in some cases the
                              default declaration doesn't give enough instruction to achieve the desired result. In
                              this example, the labels are undefined, so undefined is displayed in
                              the boxes: 
               
Example 29.24. Incorrect attribute has no effect
<canvas height="300" width="100%">
    <simplelayout spacing="5"/>
    <class name="box" height="100" width="100" bgcolor="red">
       <attribute name="label" value="Label"/>
       <text text="${parent.label}"/>
    </class>
    <box label="Box1"/>
    <box/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      To make sure attributes do what you want them to do, assign a
                              type to your attributes when you declare them: 
               
Example 29.25. Declaring attribute type
<canvas height="300" width="100%">
    <simplelayout spacing="5"/>
    <class name="box" height="100" width="100" bgcolor="red">
       <attribute name="label" value="Label" type="string"/>
       <text text="${parent.label}"/>
    </class>
    <box label="Box1"/>
    <box/>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      The type attribute specifies the type of the
                                       <attribute>'s value and affects how a value
                                    expression will be parsed: 
                  
Table 29.1. Using the type attribute
| Value | Definition | 
|---|---|
| string | An ECMAScript Stringin ECMAScript String literal syntax.
                                                               To assign the value of an expression
                                                               that yields a ECMAScriptString, usevalue="${. | 
| color | A colorLiteral(see Section 6.2.2, “Summary of color literals”). To assign the value of a JavaScript expression, usevalue="${. The
                                                               expression must yield a numeric color value. | 
| boolean | "true" or "false" | 
| expression | An ECMAScript expression | 
| number | A numberLiteral, or an
                                                               ${expression} which evaluates to a number. | 
| size | A sizeLiteral, or an
                                                               ${expression} which evaluates to a non-negative
                                                            number | 
| text | XML content | 
| html | XML content | 
 All other types (boolean, expression,
                                       number, size, text) are
                                    parsed as expressions of the specified type. 
                  
 Note that in XML, types are specified in lower case, e.g.,
                                    string. In JavaScript, types are capitalized, e.g.,
                                       String . The two types are equivalent in LZX, but you must use
                                    the XML name in XML constructs and the JavaScript name in JavaScript constructs. 
                  
Colors can have the following values:
A color of the form #hhh, #hhhhhh,
                                                         rgb(rv, gv, bv) or a CSS color name, where
                                                      h is a hexadecimal digit, rv,
                                                         gv, and bv are numbers between 0.0
                                                      and 1.0 inclusive, and the CSS color names are defined in
                                                      lz.colors.
                           
Table 29.2. CSS color names
| CSS Name | Hex Value | 
|---|---|
| black | 000000 | 
| green | 008000 | 
| silver | C0C0C0 | 
| lime | 00FF00 | 
| gray | 808080 | 
| olive | 808000 | 
| white | FFFFFF | 
| yellow | FFFF00 | 
| maroon | 800000 | 
| navy | 000080 | 
| red | FF0000 | 
| blue | 0000FF | 
| purple | 800080 | 
| teal | 008080 | 
| fuchsia | FF00FF | 
| aqua | 00FFFF | 
JavaScript types start with a capital letter. These may be one of the JavaScript types, listed below or an LZX class.
Table 29.3. Native JavaScript types
| Type | Legal Values | 
|---|---|
| Boolean | true or false | 
| String | single or double quotes may be used to specify a sequence of characters (e.g. var s = 'test' or var s = "test") | 
| Number | used to specify simple values (e.g. var n = 4 or var n=4.2). Number type is also commonly used to specify a color, for which it is often convenient to use hexadecimal notation (e.g. var c = 0xFFFFFF for white, or 0x0099BB for turquoise) | 
| Array | an ordered list of elements. The elements may be of any type and need not be of the same type. | 
Table 29.4. Notes on Documentation
| Symbol | Notes | 
|---|---|
| [LzNode] | An LZX class enclosed in brackets indicates an Array of these types | 
| dictionary | Also known as a hash, or JavaScript Object, the dictionary type indicates an unordered collection of name-value pairs. For Example: {width:100, height:50, title:"my title"} | 
| any | JavaScript APIs wil ofter allow a parameter of any type. This is indicated by the word "any" in the type column | 
 The value of an attribute, whether set in an attribute element or start tag, is
                              evaluated according to the attribute when option.
                              when can be one of the following: 
               
immediately
                                           initializes the attribute to the value of the expression when the enclosing
                                                element is defined. The value must be a constant expression and cannot depend
                                                on any other objects. immediately is currently the default
                                                value for when, but will be deprecated in a future release.
                                             
                        
once 
                                           initializes the attribute to the value of the expression when the enclosing
                                                element is initialized. The expression cannot depend on the value of any other
                                                property of the element, nor can it depend on being evaluated in any particular
                                                order with respect to any other attributes: use an init
                                                method if ordered evaluation is required. 
                        
always
                                          updates the attribute any time the value of the expression changes: the attribute is constrained to follow the value of the expression.
 The declared evaluation time of an attribute can be overridden when assigning a
                              value by using
                              value="$ (or
                              in a start tag by when{expression}"<),
                              where tag
                                    attribute="$when{expression}">when is one of the possible when options. If
                              omitted, when defaults to always. 
               
                              when is a declaration and applies to any setting of the tag, not just
                              the initial one. For example, the width and height
                              attributes of view are declared when="always": any
                              time you set width or height, it creates a constraint, even if you don't say
                                    ${. (The compiler is optimized to
                              evaluate constant constraints only once). 
               expression}
                              ${ can be used to override the
                              declaration at any site where you are setting the value of an attribute. For example,
                              the expression}title attribute of view is declared
                                 when="once", so if you want to have a dynamically updating title,
                              you need to say title=${ to
                              constrain it to follow some.reference}some.reference. 
               
 Note that an attribute that is not given an initial value will not be created in the
                              element by default: it should either be initialized in the init
                              method using
                              this. or
                              made a required attribute using the attrName=expressionrequired="true" option. 
               
 Attributes can normally be referred to in class methods and expressions by their
                              name except when being initialized as above, in which case they must be referred to
                              using this., in order to create the attribute in the element. 
               
For example:
Example 29.26. attribute for internal flags
<class name="myclass">
  <!-- 'foo' has an initial value of 1 -->
  <attribute name="foo" value="1"/>
  <!-- 'thing' is always four more than 'foo' -->
  <attribute name="thing" value="foo + 4" when="always"/>
  <!-- 'bar' is only declared, initialized below -->
  <attribute name="bar"/>
  <handler name="oninit">
    <!--
      the attribute 'bar' will be created in the instance
      sets its value to true
      is appropriate for internal script flags
    -->
    this.bar= true; 
    <!-- 
      probably a mistake...
      sets the value of attribute 'foo' to 4,
      but does not update the constraint on 'thing'
      use setAttribute, as below
    -->
    this.foo = 4;            
  </handler>
  <method name="dothis">
    if (bar) {
      <!--
        sets the value of 'foo' to 6             
        sends the event 'onfoo'
        (which causes dependent constraints to be evaluated)
        as a result 'thing' will equal 10
      -->
      this.setAttribute("foo", 6);
    }                
  </method>
</class>
 In many cases, specific code operations need to take place when an attribute is set.
                              For example, when the width attribute of a <view> is set, the view
                              needs to update the width of the parent view if clipping is set to false. Though it is
                              very convenient to simply handle the onwidth event to execute the required code, there is no
                              guarantee as to order events will be called. This task is instead accomplished best
                              using the setAttribute() method of <view>, to set the width
                              attribute. 
               
 In the following example, the time between clicks is shown on a button. For every
                              click, the current time in milliseconds is stored in the time attribute. The custom
                              setter, setTime(), has been defined for the time attribute. 
               
 Normally, when an attribute is set by invoking setAttribute(), setAttribute() handles the tasks of setting the
                              value of the attribute, and sending the onattribute event. You can
                              change this behavior by using the setter attribute on the <attribute> tag. You would
                              then define a method that has the name of the setter. 
               
 When defining a custom setter for an attribute, you are responsible for setting the
                              value and sending the onattribute event, as shown in the
                              example below. If the on event isn't sent
                              in the custom defined settter, registered
                              attributeon events will not fire, and constraints
                              tied to the attribute will not be updated when the value of the attribute is changed. 
               attribute
Example 29.27. Defining an explicit setter method
<canvas height="40" width="100%">
  <button text="click me">
    <attribute name="time" setter="setTime(time)"/> 
    <attribute name="ontime" value="null"/> 
    <handler name="onclick"> 
      Debug.debug('inited: %w', this.isinited); 
      var now = (new Date()).getTime();
      this.setAttribute("time", now); 
    </handler> 
    <method name="setTime" args="t"> 
      if (!this.isinited) {                                          //catch the case where this.time is being 
        this.time = t;                                               //initialized during object instantiation
        return;
      } 
      if (typeof this.time == "undefined" || this.time == null) {    //handle first set of time
        this.setAttribute("text", "first click registered");
      } 
      else {
        var diff = t - this.time;                                    //handle any additional setting of time
        this.setAttribute("text", diff + " milliseconds between clicks");             
      } 
      this.time = t;                                                 //as this is the declared setter for 
                                                                     //this.time, we have to set it
      if (ontime)                                                    //required to update constraints and 
        this.ontime.sendEvent();                                     //fire ontime event 
    </method> 
  </button> 
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      Instances and subclasses of LzNode, including LzView and classes defined using <class>
                               , have both an init() method and an oninit event. Since you do not have control over the
                              order that events are fired, you should put all initialization code in the init() method (and not, for example, in a handler
                              for oninit). 
               
 If you declare an init() method in a view or class, you are
                              effectively overriding the init() method in that object's super class. The <view> tag and all its
                              subclasses have important initialization code in the init method, and it is essential
                              that this code is executed when overriding init(). This is accomplished by using the
                                 super keyword, which is a reference to the superclass. In the
                              example below, we override the init method in the button class. Notice the call to
                                 super.init(), which executes initialization code for the button.
                              The init() method for button subsequently invokes
                              super.init on basebutton, and so on up to the execution of LzNode.init(). 
               
Example 29.28. init() method vs oninit event
<canvas height="40" width="100%">
  <button>
    <method name="init">
      super.init(); //best practice to always call super.init() when declaring 
                    //an init method
      //do some init code here
    </method>
    
    <handler name="oninit">
      //this isn't fired in any particular order 
      //use the init method instead
    </handler>
  </button>
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      When setting variables local to the current class, node, or view, always refer to
                              those variables using the keyword this. 
               
Example 29.29. Using "this" keyword
<canvas height="50" width="100%">
   <view x="10" height="30" width="30" bgcolor="red" onclick="this.bringToFront()"/>
   <view height="30" width="30" bgcolor="blue" onclick="this.bringToFront()"/> 
</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.                   *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
                      Not using this can result in unpredictable results. 
               
There are four ways of getting and setting attributes in LZX, each with benefits and drawbacks:
Using setAttribute() and the . operator
                        
Using predefined "setters" for certain attributes, such as onx() and ony()
using custom getter and setter methods, as explained above
Reading and writing attributes directly: that is, without using a setter or getter method
 The only reliable way to set attributes is by invoking
                                       setAttribute() on the view, class, or node that contains the
                                    target attribute. Invoking setAttribute() automatically fires the
                                    associated 'on' event for the attribute in question. Having the associated event fire
                                    is required for constraints tied to the attribute in question to function correctly. 
                  
The only time you would set an attribute using `.` would be if you were the
                                          "owner" of the attribute (it is in a class or instance that you are writing). If
                                          the attribute is from a class that you are using or sub-classing, or an instance
                                          that is from code that you did not write (built-in, library, etc.) you
                                             must use setAttribute() to set the
                                          value or you will surely break things.
                     
Copyright © 2002-2010 Laszlo Systems, Inc. All Rights Reserved. Unauthorized use, duplication or distribution is strictly prohibited. This is the proprietary information of Laszlo Systems, Inc. Use is subject to license terms.