Dynamic web pages with OpenLaszlo

Introduction

OpenLaszlo is a Java-based open-source alternative to Adobe Flex and Haxe to create Flash-based applications. Applications can be compiled either beforehand ("SOLO mode"), or on-the-fly ("proxied mode"); Both require running the OL compiler, but the latter requires installing the OL servlet on the server, so may not be a solution when using a shared host.

Pros

Cons

Temp

"OpenLaszlo applications can be deployed as traditional Java servlets, which are compiled and returned to the browser dynamically. This method requires that the web server be running the OpenLaszlo server.

Alternatively, Laszlo applications can be compiled from LZX into a binary SWF file, and loaded statically into an existing web page. This method is known as SOLO deployment. Applications deployed in the manner lack some functionality of servlet-contained files, such as the ability to consume SOAP web services and XML remote procedure calls.

LZX is an object oriented, tag-based language that uses XML and JavaScript syntax to create the presentation layer of rich internet applications.

It's important to understand, however, that the Flash Player is used only as an execution/rendering engine for the generated byte code, and there's nothing inherent in LZX that marries it to Flash. In particular, LZX does not employ or rely upon the Flash object model. As of release 3.1 you may compile for swf6, swf7, or swf8 output. The swf7 target is the default; applications compiled for swf7 and swf8 are entirely case-sensitive. Applications that work in swf6 may not work in swf7, and vice versa, for these reasons.

OpenLaszlo Server deployment requires a Java Application Server or servlet container. It provides additional capabilities dependent on the server, including support for SOAP, XML-RPC, Java-RPC and persistent connections. The OpenLaszlo Server is also required for applications that use some media formats that are not natively supported by the Flash Player. The OpenLaszlo Server transcodes these media files "on the fly" into formats supported by the Flash Player.

Applications compiled with LPS 2.2 (or earlier) require access to a running copy of the OpenLaszlo Server (called "LPS, for Laszlo Presentation Server, in earlier releases) in order to make data (XML over HTTP), media, SOAP, Java Direct, and XML-RPC requests. OpenLaszlo 3.0 removes this requirement for applications that make only certain kinds of data and media requests.

OpenLaszlo comes with the Tomcat servlet container included.

LZX programs themselves are valid XML documents; LZX programs that are not valid XML simply will not compile. Secondly, LZX programs only operate on data encapsulated in XML.

Unlike proxied applications, SOLO applications require URLs to be relative.

whenever an attribute is set by calling setAttribute('whatever', 4)  an onwhatever event is sent. Following the above example for the width attribute, an onwidth event is sent whether the attribute has been set with setAttribute, setWidth() or by another constraint. When you use a constraint expression, a function is automatically generated to set the value of the attribute. That function is then called whenever an event is triggered on which the constraint has a dependency.

Immediateparent.width is used instead of parent.width, because immediateparent, in this case, is the interior view of the window, while parent is the whole window."

Programming

Note: LZX treats HTTP URLs that omit the two slashes // after the colon (:) as being relative to the application, eg. http:../resources/logo.gif .

Hello, world!

<canvas height="40">
    <text>Hello, World!</text>
</canvas>

Handling events

Events are triggered either by changing one of an object's attributes (eg. the user moves an object on the screen, changing it's x attribute), or when calling one of its methods (eg. when clicking on a button, which triggers the onclick event.)

There are two types of events: Those built-in (onclick, onfocus, onheight, etc.) and those that you define yourself.

Handling stock events through embedded JavaScript

If the event can be handled in one line of JavaScript, it can be set in an on* attribute:

<button onclick="setAttribute('text', 'Clicked!')">Click me</button>

Handling stock events through <method>

If the event requires more than one line, put the code between Method tags:

<button text="Make red the blue box!" onclick="redify()">
    <method name="redify">
        parent.myview.setAttribute("bgcolor", red)
    </method>
</button>

Handling stock events through <handler>

An event can also be declared using an Handler tag. This is useful to keep things tidy when you want to handle more than a couple of events:

<button text="not clicked">
    <handler name="onclick">
        this.setAttribute('text', 'clicked');
    </handler>
</button>

Alternatively, you can combine a handler and a method if you prefer to use your own name for the method that handles an event:

<button>
    Make red the blue box!
    <handler name="onclick" method="redify"/>
    <method name="redify">
        parent.myview.setAttribute("bgcolor", red)
    </method>
</button>

... which could be rewritten more simply as:

<button text="Make red the blue box!" onclick="redify()">
    <method name="redify">
        parent.myview.setAttribute("bgcolor", red)
    </method>
</button>

Handling customized events through <event>

Here's an example on how to create your own event:

<class name="myclass_with_handler">
    <event name="myevent"/>
    <handler name="myevent" args="myargs">
        Debug.write(this, 'handling myevent, myargs=', myargs);
    </handler>
</class>
 
[...]
 
<button onclick="foo.myevent.sendEvent(12)" text="send the event" />

Remember that any attribute can be linked to a matching onattribute event:

<class name="myclass_with_handler">
    <attribute name="season" type="string" value="spring" />
    <event name="onseason" />
    <handler name="onseason" args="s">
        Debug.write("got season of ", s, ", season is ", season);
    </handler>
</class>
 
[...]
<button onclick="foo.setAttribute('season', 'fall')" text="autumn" />

Tips & Tricks

${} vs. ""?

How to hide a window?

Neither works:

<button onclick="mywnd.setVisible('false');">Close</button>
<button onclick="mywnd.setAttribute('visible','false');">Close</button>

A dataset must live outside a window:

<dataset name="weatherdata" request="true" src="grid.xml"/>
 
<window id="mywnd" title="My window" resizable="true" closeable="true">
    <simplelayout axis="y" spacing="20"/>
    <grid datapath="weatherdata:/weather" contentdatapath="forecast/day"/>          
    <button>Hello</button>
</window>

Creating objects dynamically

Make sure you load the required libraries. Otherwise, the widgets won't load:

<include href="lz/window.lzx" />
<include href="lz/grid.lzx" />
<include href="lz/gridtext.lzx" />

This is not needed when creating them statically, as OpenLaszlo will include the required libraries for you.

 

How to upload updates from grid into remote database, including when the table is a relation, and when the app is used by more than one user at once?

How to forbid users from saving the .SWF file locally?

How to check access to remote data?

How to authenticate users?

How to print grid contents?

How to check that remote data haven't been updated by another user while working on them locally?

<simplelayout spacing="3"/>

$once{parent.width} vs. ${parent.width}

  <view align="right" resource="sessad.gif"/>

  <view resource="sessad.gif" x="${parent.width - this.width}"/>

 

 <text text="${'Slider Value is '+parent.down.value+' nicely constrained'}"/>

        Test<br />

        <p>Test</p>

 

How to set a canvas' height to the browser's client area?

<canvas height="100%">

How to set a component's width to be 1/4 of the canvas?

<tabslider x="0" y="0" id="ts1" width="${canvas.width/4}" height="${canvas.height}">

parent <> immediateparent?

JavaScript ?s

parseInt()?

 

<attribute name="direction" value="'left'"/>

<attribute name="distance" value="'2'"/>

 

The Flash plug-in in FireFox 1.5.x prompted me to allow the .swf to fetch data from a remote site, while no such prompt was shown in FireFox 2.x

about:plugins

How to manage allowed/banned sites in the Flash plug-in?

Why does OL compiles SOLO apps to .swf and .lzx.swf?

"The file is called canvas.lzx.swf instead of canvas.swf to preserve OpenLaszlo "branding"—just as the presence of .php or .jsp in a URL is good for the awareness of PHP and Java, even though .htaccess can be configured not to require this filename extensions in the URL. This also makes it less likely that compiling an application (for example, logo.lzx) will overwrite a file that it includes (if logo.lzx includes logo.swf)."

How to set up a development host to compile apps in SOLO mode?

Here's for OL 3.3.3:

  1. Download and install Sun's latest JRE
  2. Download OpenLaszlo's 10MB .WAR Servlet
  3. Rename it as .ZIP, and unzip it into any folder, eg. C:\OL
  4. Edit C:\OL\WEB-INF\lps\server\bin\lzc.bat as such:

    set JAVA_HOME=C:\Program Files\Java\jre1.5.0_10
    set LPS_HOME=C:\OL            (no trailing backslash!)
    set JAVAEXTDIRS=%LPS_HOME%\3rd-party\jars\dev;%LPS_HOME%\WEB-INF\lib;%LPS_HOME%\WEB-INF\classes

    "%JAVA_HOME%\bin\java" %JAVA_OPTS% "-Djava.ext.dirs=%JAVAEXTDIRS%" "-DLPS_HOME=%LPS_HOME%" org.openlaszlo.compiler.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 %a%
     
  5. Run "lzc dummy.lzx" to generate dummy.swf, and open this output file into a browser

Here's for OL 4:

REM lzenv.bat
 
set LPS_HOME=C:\OL
set LZCP=%LPS_HOME%\WEB-INF\lps\server
for /f "usebackq delims=" %%d in (`dir /s /b "%LPS_HOME%\3rd-party\jars\dev\*.jar"`) do call :add %%~sd
for /f "usebackq delims=" %%d in (`dir /s /b "%LPS_HOME%\WEB-INF\lib\*.jar"`) do call :add %%~sd
 
set LZCP=%LZCP%;%LPS_HOME%\WEB-INF\classes
goto :EOF
 
:add
set LZCP=%LZCP%;%*
goto :EOF
 
REM lzc.bat
 
set LPS_HOME=C:\OL
call "%LPS_HOME%\WEB-INF\lps\server\bin\lzenv.bat"
 
set JAVA_HOME="C:\Program Files\Java\jre1.5.0_10"
set CLASSPATH_SAVE=%CLASSPATH%
set CLASSPATH=%LZCP%
%JAVA_HOME%\bin\java %JAVA_OPTS% -DLPS_HOME="%LPS_HOME%" org.openlaszlo.compiler.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
set CLASSPATH=%CLASSPATH_SAVE%

What are J2EE application server or servlet containers

Tomcat = servlet container

Why does the compiler create .swf and .lzx.swf?

Compiled file saved under two extensions?

My SOLO application fails getting data from a remote server

When running apps in SOLO mode, make sure you use <canvas proxied="false">. By default, proxied="true", which means that the Laszlo application expects the web server to connect to a OpenLaszlo Server.

I need to use reserved characters like & or <

When using reserved characters like & or <, make sure they're escaped with &amp; and &lt;, respectively.

Things to check

Resources