Skip to main content

Web clients fatten up with OpenLaszlo

Build Flash widgets with XML and JavaScript

Joshua M. Woods (joswoods@us.ibm.com), Software Engineer, IBM
An Extreme Blue alumnus, Joshua Woods has extensive development experience, much of which has recently been geared towards emerging technologies. He works for IBM as a software engineer primarily in the areas of collaboration and grid computing. Joshua has recently been developing a variety of Ajax and OpenLaszlo components to showcase the new advancements in technology.

Summary:  OpenLaszlo is a rich client application architecture that uses Macromedia Flash as a deployment vehicle. Declarative in design, OpenLaszlo relies upon JavaScript for logic and offers advantages over traditional Flash development, including an advanced UI constraints system, an object-oriented design methodology, and built-in support for Web services and a variety of flavors of Remote Procedure Call (RPC). This article details the basic concepts of OpenLaszlo, and gives examples of situations in which an OpenLaszlo solution might be beneficial.

Date:  21 Feb 2006
Level:  Introductory
Activity:  6035 views
Comments:  

A recent focus in Web development is to bring a rich client experience to the Web. Asynchronous JavaScript and XML (Ajax) has broadened the way developers and users alike look at the Web, transforming it into what is quickly becoming a replacement for a standard desktop rich client. However, Ajax (and current browser technology) fall short in a few areas:

  • Providing user interfaces that have heavy animation
  • Easily guaranteeing a standard presentation across various browsers, including older browsers
  • Easily implementing certain classes of applications, including applications that draw on the fly

These, however, are just some of the areas in which OpenLaszlo excels. Before I dig into the architecture, let's spend a little time discussing what OpenLaszlo is.

Laszlo, the language that OpenLaszlo utilizes, is a declarative approach to creating widgets or entire applications with XML and JavaScript. This melding of a markup language and a scripting language is similar to the current HTML/JavaScript combination. Rather than interpret the language on the client side with a browser, Laszlo is transformed on the server side into Macromedia's Flash format. This provides for virtually automatic cross-browser support, since Flash provides a standard runtime. As the Flash format is vector based, it also allows for very flexible and fluid user interface components, which can be reused in a broad sense.

However, this is not the sum total of OpenLaszlo. OpenLaszlo is backed by an optional server-side container, the OpenLaszlo Server, which provides extended integration and support for remote procedure calls, Web services, and transcoding services (which help to do things like stream lengthy MP3 files to the user). Laszlo as a language also employs exciting concepts and design methodologies that allow you to create truly reusable components in minutes. The components you make will also be extremely visually appealing and familiar to users. Figure 1 provides an example in the form of a UI for a stock ticker application created in OpenLaszlo.


Figure 1. A sample OpenLaszlo UI
A sample OpenLaszlo UI

A knowledge of Flash is not a prerequisite for reading this article; however, you should have a basic understanding of JavaScript and how it differs from a traditional object-oriented programming languages. Additionally, the article will be more useful if you have an understanding of the fundamentals of object-oriented programming as well as traditional user interface development --Swing, Standard Widget Toolkit (SWT), Microsoft Foundation Classes (MFC), and so on.

Components: Flexible and extensible

Currently, the burden of building extensible and flexible user interface components for the Web falls upon the developer. Many technologies (custom tag libraries, PHP abstractions, and so on) exist to combat a common problem: often, a developer must combine many HTML tags to create the complex components required for today's Web applications. It is no secret that object-oriented approaches are valuable, and the Laszlo language includes many object-oriented paradigms. Take a look at some of the basic core components that are available to you.

Every Laszlo application is made up of XML files [that contain declarative user interface (UI) information and JavaScript] as well as resource files (images, embedded Flash content, and audio) that OpenLaszlo combines to create the final content. The root container is the <canvas> tag. <canvas> is in some ways similar to the <body> tag of an HTML document. It can include a number of attributes, including width, height, and background color. <canvas> in the source file is just an XML tag, but every tag is a component, or a class, which means that it can have associated methods, animations, and so on. I'll talk more about the features of components later; for now, you can use this tag and the <statictext> item in a declarative way to create the canonical "Hello, World!" example, shown in Listing 1.


Listing 1. "Hello, World!" example in Laszlo

<canvas width="300" height="200" bgcolor="white">
   <statictext>Hello, World!</statictext>
</canvas>

Components utilize Flash

For now, I'll skip the details of how this is transformed and deployed in Flash format, but it suffices to say that OpenLaszlo does all of the heavy lifting. The next important thing you need to know about OpenLaszlo components is that they are usually backed by Flash resources. This means that they can be vector based and, therefore, you can provide a common component that can be used at a variety of resolutions. Many base components are available right out of the box. Items such as <button>, <checkbox>, <list>, <menu>, and <tree> are familiar to anyone who does graphical user interface (GUI) work.

As you might expect, you can also provide your own visual resources for many of these basic components. An example of this is to use the standard <basebutton> component, which defines events such as onmouseover, to create your own custom button. To create a simple roll-over, you can just use PNGs or JPGs, though that really isn't so interesting. The exciting part is that you can use any Flash file as a resource, and that in doing so you can create buttons that are scalable as well as animated. As a result, no logic (for example, ActionScript) is placed in the Flash resource, but you can utilize all of Flash's animation concepts. Previously, you would need to be familiar with a lot of programmatic aspects to create rich applications with Flash; if you're developing in OpenLaszlo, this is no longer the case. Of course, the OpenLaszlo system takes care of merging all of your resource Flash files into a single Flash file for deployment; I will discuss this in more detail later, in "Deployment: Proxied versus SOLO applications."

Events and inheritance

Like any good object-oriented components, OpenLaszlo components handle events (such as onmouseover) that can be declared inline (such as <button onclick="buttonClicked()">); alternately, you can define method event handlers on a particular component or instance of a component, as in Listing 2. This allows you to group code naturally and brings the concept of anonymous inner functions to OpenLaszlo development. The technique becomes extremely powerful when coupled with the fact that any component is extensible, and therefore customizable.


Listing 2. An event defined on an instance of <view>

<canvas>
   <view bgcolor="0xcccccc" width="50" height="50">
      <method event="onmouseover">
         // Keyword this is used in the familiar JavaScript sense. 
         // Most of JavaScripts scoping
         // concepts apply directly to Laszlo
         this.setAttribute('bgcolor', 0x000000);	
      </method>

      <method event="onmouseout">
         this.setAttribute('bgcolor', 0xcccccc);
      </method>
   </view>
</canvas>

The coding in Listing 2 might be handy in a few cases, where no re-use is needed, but what about the rest of the time? Luckily, you can extend any other existing component to make a new component. All you have to do is use the <class> tag to define a new class, like so:

<class name="customView" extends="view">

By default, all custom classes extend <view>, which is very similar to an HTML <span> in the sense that it serves primarily as a container. Even simple extension can prove useful, as you can use the attributes to customize a component for particular needs; some basic examples are almost CSS-like in nature, providing default sizes, background colors, and so on. Of course, the fun doesn't stop there: you can include methods, animations, constructor properties, and much more in components. Imagine blending a fully object-oriented UI approach, such as Swing, with the ease and rapid development features of HTML.


Constraints: Powerful interaction

One major concern for a rich user interface is layout management. Laszlo supports (through layout components) many standard approaches. For example, you can use the <simplelayout> element, which has two major attributes. The axis attribute allows you to specify the layout orientation, either along the x-axis or the y-axis, while the spacing attribute allows you to control the spacing between components. You can declare multiple layouts for a container, so as to combine both vertical and horizontal spacing. Like everything in Laszlo, this is a simple concept, but well-executed. Laszlo also contains grid layouts as well as layouts that wrap to fit a region, but this is not what excites me about Laszlo. The exciting feature is the Laszlo constraint model, and how elegant it can make UI control as well as animation effects.

A replacement for most events

Every time an attribute is changed within a Laszlo component, an event is fired. These events can then be listened to, as described above in "Events and inheritance." This is a nice feature -- it eliminates the need for adding listeners and so on for every attribute -- but still leads to a lot of redundant code. Wouldn't it be nice if elements could use these attribute changes in a more convenient fashion, just as dependencies in a spreadsheet are applied? With constraints, you can do just this. For any attribute in Laszlo, you can assign a constraint expression instead of a standard value. Constraint expressions begin with a dollar sign, and have the following format:

$when{ConstrainedExpression}

Here, when is one of always, once, or immediately. If when is omitted, then the value defaults to always, which implies that every time a dependency of ContrainedExpression changes, the constraint will be reevaluated. Setting the value to once is useful if a constraint is static once initialized, as it will then only be evaluated once and increase efficiency. The other value, immediately, can be used to evaluate the constraint when the enclosing element is defined and the constraint does not depend on other objects.

Let's start with a simple example. What if you wanted an item that was resizable, but always had another item positioned in the center of it? Listing 3 shows how to accomplish this. It uses the standard Laszlo component slider to control the size of the bounding rectangle.


Listing 3. A slider that controls the size of a rectangle, which affects the size of an inner rectangle

<canvas>
   <slider id="sliderItem" y="20" x="10" minvalue="50" maxvalue="300" 
           value="50"/>

   <view y="$once{sliderItem.y + sliderItem.height + 5}" 
       x="$once{sliderItem.x}" bgcolor="0xff0000" 
       width="${sliderItem.value}" height="${width}">
		
      <view bgcolor="0x0000ff" 
         width="${parent.width / 5}" height="${width}"
         x="${(parent.width / 2) - (width / 2)}"
         y="${(parent.height / 2) - (height / 2)}"/>
   </view>
</canvas>

As you can see, since x is just an attribute of <view>, you can set the value using a constraint. Laszlo uses a hierarchical approach to identifying items, with the parent object always referring to the containing control. Using this syntax, you can go all the way up the structure, but you can also specify name andid attributes. The difference between the two is that id identifies a specific item (and therefore can only be used once in a document), which allows it to be used globally (as in Listing 3, where I used an id for the slider control and then used that id in the constraint: ${sliderItem.value}).

In this example, note the use of the once option for the constraints that specify the x and y positions of the colored rectangle. Figure 2 illustrates the output of the code in Listing 3.


Figure 2. The output of Listing 3
The output of Listing 3: A slider that controls the size and position of a view with constraints

Advanced constraints

Constraints are great for replacing simple events as well as for modeling layout constraints, but they offer many more features. Since you can set any arbitrary attribute value (and yes, that includes values that you define) to a constraint expression or use it in a constraint, there are a lot of possibilities. In the next section, you'll use constraints in combination with Laszlo's animation system to produce powerful results that are elegant and easy.


Animation and drawing

One of the more critical presentation details in modern interface design is animation. Animation provides flair as well as visual cues to the user of the interface. It is also a huge strength of Macromedia Flash and, by extension, of OpenLaszlo. Animation is also one of the few things that cannot be currently accomplished efficiently across browsers without using special extensions.

The animation tags

Laszlo comes with two elements to help accelerate animation development: The <animator> element is the basic building block of all animations, while the <animatorgroup> is a container for <animator> items. In Laszlo, animation is nothing more than the ability to change the value of attributes over a specified period of time and in complex combinations. Using these simple concepts and building blocks, almost anything is possible.

The <animator> element has a required attribute named (what else?) attribute. This specifies the attribute on which the animator will operate. It also has a required attribute named to that accepts a numerical value and represents the final value of the attribute being animated. The final required attribute is duration, which specifies the time for this animation step in milliseconds. For convenience, the <animator> element also has an optional from attribute, which sets the starting point for the attribute value. Using just these attributes, you can construct a simple program that animates changes to the width of a view, as in Listing 4.


Listing 4. A simple animation example: Change the width of a view

<canvas>
   <view bgcolor="#ff0000" width="50" height="${width}">
      <animator attribute="width" to="200" duration="1000"/>
   </view>
</canvas>

In this example, a red square will appear and expand to 200 by 200 pixels over the course of one second. If you try this example, you might notice that the motion is not linear. That is because the default value for the attribute motion is easeboth. Using easein, easeout, or easeboth will result in the motion being slower at the beginning, end, and beginning and end of the animation, respectively. The final value that motion can take is linear, which keeps animation speed constant. Also notice that the animation begins right away; you can alter this with the start attribute, which defaults to true. Finally, a few other attributes are available, including one to control the number of times this step is repeated (repeat), as well as various events -- such as onstart, onfinish, and so on -- to support the ability to add custom logic after a step has completed.

Complex animations with <animatorgroup>

As mentioned before, an <animatorgroup> is nothing more than a container for <animator> elements and other <animatorgroup> elements. However, adding this container type definitely opens up a lot of possibilities. An <animatorgroup> can define all of the same attributes that an <animator> can, as well as a new attribute: process. Any of the previously mentioned attributes will cascade if applied to an <animatorgroup>. The new attribute, process, controls the order in which the children of the grouping are executed. If its value is sequential, the items will be executed one after the next until the group is complete. The other option is simultaneous.

With these two options, very cool and interesting effects are possible. You might have an item that moves around the screen and changes size at the same time, for instance. And since a group can contain other groups, you can really start to define a nice structure and order for your animations.

Constraints and custom attributes for impressive results

After reading the outline above, the animation process might seem fairly simplistic and limiting. You might wonder how to perform animations that require more complex calculations. Often, the answer is to utilize custom properties and constraints. As an example, say you have an item that you want to move in a circular orbit around the screen. Naturally, you cannot animate the x and y attributes in this way. What you can do is to constrain the x and y positions to be a function of a custom attribute, which you animate over a range. As you can see in Listing 5, making a view orbit around in a circular path is very easy if you utilize constraints.


Listing 5. Using constraints and animation together

<canvas>
   <view bgcolor="#ff0000" width="20" height="$once{width}"
      x="${radius + (radius * Math.cos(animCnt))}"
      y="${radius + (radius * Math.sin(animCnt))}">

      <attribute name="animCnt"/>
      <attribute name="radius" value="30"/>

      <animator attribute="animCnt" from="0" to="$once{Math.PI * -2}" 
            duration="1000" motion="linear" repeat="Infinity"/>
   </view>
</canvas>

Using these techniques, you can create very impressive animations. You never have to worry about frame rate and other such calculations, because all of these details are abstracted away for you. In addition, since constraints can involve multiple components, the animation of one component can alter the state of another.

Custom drawing

A huge advantage of OpenLaszlo is the ability to draw custom shapes easily. These shapes can be either static or dynamic, allowing you to respond to user interaction or even create graphics applications. You can perform custom drawings on the <drawview> component, which acts as a canvas. Even though drawing can be declarative, it is still very procedural in nature. Once you master drawing, it is obvious how you might apply this to either dynamic or static use cases.

The <drawview> element actually has just four custom attributes. These attributes are global, controlling the default properties of segments drawn onto the canvas, including: fillStyle, globalAlpha, lineWidth, and strokeStyle. You can modify all of these attributes by the ten custom procedures that are specific to a <drawview>.

Drawing procedures

The drawing interface is defined by ten procedures. These procedures move the pen, which ultimately creates the path that can then be stroked or filled (when it is closed) with gradients and colors.

The pen begins at the point 0,0. Using the moveTo(x, y) method, the pen can be moved to a new position. This method also creates a new path. A path is nothing more than a series of points that can later be stroked or filled. You can also use the lineTo(x, y) method to add a subpath to the current path, and position the pen at the specified position. There is also a similar quadraticCurveTo(cpx, cpy, x, y) method that takes a coordinate and a curve control point coordinate, but otherwise behaves similarly to lineTo().

Once you build a path, you must stroke it or fill it before it becomes visible. Calling the stroke() method uses the current attribute value of strokeStyle (a color in hexadecimal format, such as 0x000000) as well as lineWidth to determine how to stroke the path. The fill() method closes any subpaths and then fills each subpath in turn using fillStyle (which can be a color, or, as discussed later, a gradient object) to determine how to draw the fill. Listing 6 demonstrates a simple example in which a few squares are stroked and filled in various ways.


Listing 6. Simple drawing example

<canvas width="115" height="95">
   <drawview width="200" height="200" x="5" y="5">
      <method event="oninit">
         // Draw a black square
         this.strokeStyle = 0x000000;
         this.moveTo(0, 0);
         this.lineTo(25, 0);
         this.lineTo(25, 25);
         this.lineTo(0, 25);
         this.closePath();

         this.stroke();

         // Reset the path and draw a square with red fill 
         // and a black outline
         this.beginPath();
         this.fillStyle = 0xff0000;
         this.moveTo(40, 0);
         this.lineTo(65, 0);
         this.lineTo(65, 25);
         this.lineTo(40, 25);
         this.closePath();

         this.fill();

         // Draw a square with a square filled with a gradient 
         // from white to gray
         this.beginPath();

         // Create the gradient, adding color 'stops' (where 
         // the color shifts)
         var gradient = this.createLinearGradient(80, 0, 105, 25);
         gradient.addColorStop(0, 0xffffff);
         gradient.addColorStop(1, 0x000000);
         this.fillStyle = gradient;

         this.moveTo(80, 0);
         this.lineTo(105, 0);
         this.lineTo(105, 25);
         this.lineTo(80, 25);
         this.closePath();

         this.fill();
         this.stroke();
   </method>
   </drawview>
</canvas>

Figure 3 illustrates what the output of Listing 6 will look like in your browser window:


Figure 3. The output from Listing 6
A sample OpenLaszlo UI

This sample makes use of the oninit() method, which is available for all objects. It introduces the beginPath() and closePath() methods, which can be used for path management. It also introduces gradients, which come in two forms in Laszlo: linear and radial. Each gradient is mapped to the coordinate space as a rectangle or a circle. To set the colors, you use the addColorStop() method, which allows you to place colors on the continuum from 0 to 1. The color at stop 0 will be at the origin of the gradient, while 1 places it at the furthest edge. Before you set the stop colors, you can also alter the globalAlpha property to allow partially opaque gradient colors.

Combining drawing and animation

That takes care of all of the basic drawing facilities that OpenLaszlo provides for you. You might wonder how you can use the animation facilities outlined in "Animation and drawing" with this procedural-style drawing API. One way is to add custom attributes to a <drawview>. For instance, if you want to have a circle that is drawn dynamically and you want to animate the size of the radius, you might create an attribute radius and then animate the property (in the usual way), then define an event handler for the radius change event (<method event="onradius">) that re-draws the element. With this strategy, almost anything is possible.


Deployment: Proxied versus SOLO applications

The impatient among you might have already skipped to Resources to see what kind of OpenLaszlo applications are available. For those of you who have made it this far without doing so, I imagine that you are curious about how to convert your Laszlo files into something that is deployable on the Web. This section covers that topic, and also addresses concerns over which deployment model might work best for you, proxied or SOLO.

SOLO deployment

SOLO deployment (which stands for standalone OpenLaszlo output) is supported on any Web server that can serve Flash files. To convert your Laszlo application into an Flash file, you invoke the compiler (for example, lzc file.lzx -- .lzx is the extension for Laszlo files) to produce an output file that is playable by anyone with the required minimum version of Flash. This is easy enough: place the generated file on your Web server and include it in the body of an HTML document, and you are ready to go. The OpenLaszlo compiler takes care of all of the dirty work (resource combining, code generation, and so on) for you. There are limits to what is possible with a SOLO deployment, though, and some of the features not available in SOLO deployment (Web service calls, RPC, and certain types of media streaming, for instance) are very powerful.

Proxied deployment: All the features

With proxied deployment, you get all that the OpenLaszlo system has to offer. There is one catch, though: you have to have an OpenLaszlo Server environment installed on your server to use this deployment model. The server environment is a Web application that sits on top of a J2EE application server or servlet container and processes all requests for .lzx files. One of the cool features of the OpenLaszlo Server is that by simply placing a Laszlo file on a server with the OpenLaszlo Server component, you are able to browse to the page and see the result, because it is compiled and cached on the fly by the server. The other big advantage of the OpenLaszlo Server is that it sits between your deployed application and other resources it may need to access, performing any conversions needed. This allows Laszlo to support (when proxied) things like XML-RPC.

For a lot of users, installing the OpenLaszlo Server will be a snap, as it comes bundled with Tomcat in an easy-to-install package. For those using IBM WebSphere® or other J2EE application servers, a Web application archive file is available in Resources, as well as instructions on how to set up the environment. While administration is outside the scope of this article, you'll find a number of resources for that in Resources.

When to use proxied deployment

Because media requests are not proxied in SOLO deployment, only Flash, JPG, and MP3 media types are supported by SOLO applications. Also, because there is no proxying of data, items like RPC, SOAP, and persistent connections to the server are not supported in SOLO deployment.

Although this article has only offered a brief overview of proxied and SOLO deployment, it should give you enough insight to see the power of the OpenLaszlo Server. In the final section, I'll look at that data binding and RPC features that Laszlo supports, some of which depend on or behave differently when deployed in proxied mode.


Data binding features and RPC

When it comes to displaying large quantities of data in Laszlo, the language's data binding features are very convenient. Data binding allows you to map specific component values to an existing data structure, without the need for extra programming. Data binding is primarily used to create form-based layouts, where you have a large number of items that need to be inserted into a visual template. You can bind your UI's text fields and other content to external data stores, and can use that data to populate widgets like list boxes and checkboxes.

The data source is usually an XML document, either statically compiled into the OpenLaszlo application or fetched dynamically. Options also exist for you to develop more manual solutions using an XMLHttpRequest-like API, but using data binding will decrease your development time. In OpenLaszlo, you specify the elements in the XML document that should be bound by adding XPath in the datapath attribute. Listing 7 shows a simple example of binding some contact information to some text regions.


Listing 7. Simple data binding of contact information
	
<canvas>
   <dataset name="contactInfo">
      <contacts>
         <contact>
            <name>John Doe</name>
            <phone>555-2000</phone>
            <DOB>16-01-1973</DOB>
            <role>Developer</role>
         </contact>
         <contact>
            <name>Jane Doe</name>
            <phone>555-3000</phone>
            <DOB>27-02-1974</DOB>
            <role>Manager</role>
         </contact>
      </contacts>
   </dataset>

   <view datapath="contactInfo:/contacts/">
      <simplelayout axis="y" />

      <view datapath="contact/">
         <simplelayout axis="x" />

         <text datapath="name/text()" />
         <text datapath="phone/text()" />
         <text datapath="DOB/text()" />
         <text datapath="role/text()" />
      </view>
   </view>
</canvas>


The above example introduces another important concept in data binding: XPath inheritance. As you can see, the outer view binds to the root node of the XML document (<contacts>), while the nested view binds to an individual <contact> node. The other interesting thing to note is that both entries are displayed, as you can see in Figure 4.


Figure 4. The output from Listing 7
The output from Listing 7

This is the default behavior, unless you specify a specific contact node (e.g., datapath="contact[1]"). Using this default behavior, the LzReplicationManager replicates the corresponding <view> items as needed.

Data binding can do a lot more, though, as <dataset> objects can be defined to be remote. In addition, they can be updated dynamically, with the data binding layer doing all of the heavy lifting. Of course, as is the case with most of the features of Laszlo, you can use data binding in numerous ways. The applyData() method can be overridden on items declaring a datapath attribute to do custom formatting of the data. The ondata event of a <dataset> can similarly be used to do other custom updating. Beyond these simple overrides, Laszlo includes many more complex interfaces and objects (including <datapointer> elements) that may be of interest to the more advanced Laszlo developer.

RPC options

While a complete description of how RPC works is outside the scope of this article, I feel it is important to mention the ways in which OpenLaszlo supports it. In proxied deployment, OpenLaszlo supports three types of RPC: JavaRPC, SOAP, and XML-RPC. All of these methods have specific components related to them, but inherit from the OpenLaszlo RPC component <rpc>. Again, the OpenLaszlo Server is required for RPC. It handles the marshalling of the data and proxies requests to remote servers.

By utilizing JavaRPC (or any other RPC method), you don't have to modify existing server-side logic to be compatible with OpenLaszlo. This is a benefit over Ajax-based solutions, which often require custom or third-party software to map Ajax-style requests to a JavaRPC model. Additionally, because OpenLaszlo creates proxy stubs for you (which use Laszlo Delegates), the developer becomes much less burdened. As the RPC methods available in OpenLaszlo are very similar to their more traditional counterparts, those familiar with RPC should be able to dive right in. Those unfamiliar should rest assured that RPC support allows very tight coupling with server-side logic in an intuitive manner.

In conclusion

As you can see, OpenLaszlo has a lot of nice features. It provides an elegant and complete solution to address many of tomorrow's concerns. Hopefully, this article has provided a brief glimpse at some of these unique features, as well as enough basic information to get you ready to use OpenLaszlo for a development project. I encourage you to dive in to the documentation and examples listed in the Resources section of the article. Once you get the hang of it, I think you will find that OpenLaszlo development is very rapid and rewarding.



Download

DescriptionNameSizeDownload method
Code samples from this articlewa-laszlo_samples.zip3KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

  • The OpenLaszlo Weblog includes news, as well as tips and tricks for Laszlo development.

  • The OpenLaszlo Wiki contains a lot of general information, as well as links to a lot of useful content.

  • developerWorks bloggers have their fingers on the pulse of technology industry.

About the author

An Extreme Blue alumnus, Joshua Woods has extensive development experience, much of which has recently been geared towards emerging technologies. He works for IBM as a software engineer primarily in the areas of collaboration and grid computing. Joshua has recently been developing a variety of Ajax and OpenLaszlo components to showcase the new advancements in technology.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, XML
ArticleID=104052
ArticleTitle=Web clients fatten up with OpenLaszlo
publish-date=02212006
author1-email=joswoods@us.ibm.com
author1-email-cc=htc@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers