Saturday, April 11, 2009

[ICS 499] OpenLaszlo...simply wow

It looks and feels like Flash, but its not necessarily that. OpenLaszlo is a Rich Internet Application (RIA) platform targeted for building desktop-like web applications. Its component based syntax for declarative programming provides an array of supported outputs, such as Flash, and recently, DHTML. In this entry, I'll give what seems to be a very clear cut example of a simple OLZ application.

Please note that this application is a derivative of Adam Wolff's screencast for OpenLaszlo 4 programming.

Defining and porting our data...
Laszlo follows the strong standard XPath data-binding API's, as well as components to facilitate communication with the back-end. XML is used as the standard representation format of every LZX application file. Any data source that negotiates with Laszlo applications are quite capable of generating XML dynamically. Such sources may include: JavaServer Pages, Servlets, Microsoft Active Server Pages, ColdFusion pages, CGI applications, PHP scripts, etc. To keep things simple for this example, I'll provide the raw XML file for my LZX application.

Here's my XML file, called places.xml:
<places>
<place street="750 Keeaumoku St" description="Walmart store"
name="Walmart" city="Honolulu, HI 96814"/>

<place street="1450 Ala Moana Blvd" description="Ala Moana Shopping Center"
name="Ala Moana Center" city="Honolulu, HI 96814"/>

<place street="1527 Keeaumoku St" description="Makiki District Park"
name="Makiki Park" city="Honolulu, HI 96822"/>
</places>
Creating an LZX application file:
Simply create a file and name it with the extension of ".lzx", then place the following inside it:
<canvas></canvas>
There you have it, your very first Laszlo application! I know it's not very impressive, but it only gets better.

Data source retrieval in LZX app:
<canvas>
<dataset src="places.xml" name="dsPlaces">
<window title="Places" width="200" height="250">
<simplelayout/>
<view>
<text>
<datapath xpath="dsPlaces:/places/place/@name" replication="lazy"/>
</text>
</view>
</window>
</canvas>
In this bit of code, I introduced a data set tag referencing to my local "places.xml" file, with a name tag of "dsPlaces." Next, "window" is a simple way of creating a draggable window panel with an optional fixed width and height. The window is the container object for our data set output. By following standard XPath for XML styled notation (/places/...), we can simply list all the names of places from the xml file. Also a special note on "lazy" replication: It simply is built into the OLZ runtime and acts as a catalyst for retrieving data faster and efficiently (similar to Google Maps rendering).
<canvas>
<dataset src="places.xml" name="dsPlaces">
<window name="main" title="Places" width="200" height="250" resizable="true">
<simplelayout/>
<view>
<text onmouseover="this.setBGColor(0xDDDDFF)"
onmouseout="this.setBGColor(null)>

<datapath xpath="dsPlaces:/places/place/@name" replication="lazy"/>
<handler name="onClick">
details.datapath.setFromPointer(this.datapath)
<handler>

</text>
</view>
<scrollbar/>
</window>
<window name="details" title="$path{'@name'}" x="${main.x + main.width}" width="400" height="250">
<datapath/&gt
<text datapath="@description" fontsize="14" width="100%" multiline="true"/>
</window>

</canvas>
Added a little OLZ syntactic sugar for Javascript to allow mouse over effects to the text data.
Created a handler for when a user clicks on a data text --the data set that was clicked on would sync with the details window.

Defining your own window class:
<canvas>
<dataset src="places.xml" name="dsPlaces">
<window name="main" title="Places" width="200" height="250" resizable="true">
<simplelayout/>
<view>
<text onmouseover="this.setBGColor(0xDDDDFF)"
onmouseout="this.setBGColor(null)>
<datapath xpath="dsPlaces:/places/place/@name" replication="lazy"/>
<handler name="onClick">
var details = new detailswindow(canvas);
details.datapath.setFromPointer(this.datapath);
<handler>
</text>
</view>
<scrollbar/>
</window>
<class name="detailswindow" extends="window" title="$path{'@name'}"
x="${main.x + main.width}" width="400" height="250" closeable="true">
<datapath/&gt
<method name="close">
putAway.doStart();
</method>
<animatorgroup name="putAway" process="sequential" duration='300' start="false">
<animator attribute="height" to="50"/><animator attribute="y" to="-50"/>
</animatorgroup>
<text datapath="@description" fontsize="14" width="100%" multiline="true"/>
</class>

</canvas>
Added extensible window class, called "detailswindow."
Demonstrated a named method handler for closing a window (animator).

Marketing this app by embedding a Google map via the GoogleMaps API:
<canvas>
<href="htmlview.lzx"/>
<dataset src="places.xml" name="dsPlaces">
<window name="main" title="Places" width="200" height="250" resizable="true">
<simplelayout/>
<view>
<text onmouseover="this.setBGColor(0xDDDDFF)"
onmouseout="this.setBGColor(null)>
<datapath xpath="dsPlaces:/places/place/@name" replication="lazy"/>
<handler name="onClick">
var details = new detailswindow(canvas);
details.datapath.setFromPointer(this.datapath);
<handler>
</text>
</view>
<scrollbar/>
</window>
<class name="detailswindow" extends="window" title="$path{'@name'}"
x="${main.x + main.width}" width="400" height="250" closeable="true">
<datapath/&gt
<method name="close">
putAway.doStart();
</method>
<animatorgroup name="putAway" process="sequential" duration='300' start="false">
<animator attribute="height" to="50"/><animator attribute="y" to="-50"/>
</animatorgroup>

<text datapath="@description" fontsize="14" width="100%" multiline="true"/>
<handler name="ondata">
var fullAddress = datapath.xpathQuery('@street');
fullAddress += ", " + datapath.xpathQuery('@city');
map.setSrc("map.html?addr=" + fullAddress);
</hander>
<htmlview name="map" width="100%"/>
</class>
</canvas>
Here's a sample of an htmlview.lzx:
<canvas>
<window width="600" height="600" resizable="true" oninit="this.htmlview.setSrc('http://maps.google.com')">
<html name="htmlview" xoffset="8" yoffset="25" widthoffset="-20" heightoffset="-45"
oninit="this.bringToFront()"/>
</window>
</canvas>
This displays a map beneath the selected address of interest.

So as you can see, OpenLaszlo gives new meaning to web "mashups" by inherently being able to consume all sorts of data sources. RIAs do a very good job at utilizing an intuitive standard, like XML to bring many of these hierarchical components to life. Tomorrow, I plan on testing out yet another RIA platform, which went open source back in 2007, known as Adobe's Flex.

No comments: