Navigation

RSS 2.0 New Entries Syndication Feed Atom 0.3 New Entries Syndication Feed

Show blog menu v

 

General

Use it

Documentation

Support

Sibling projects

RIFE powered

Valid XHTML 1.0 Transitional

Valid CSS!

Blogs : Archives

< Introducing RIFE LiveGuide   RIFE at JavaPolis 2005 >
OpenLaszlo 3.1 released, it's AJAX now!

Last week, OpenLaszlo 3.1 has been released without much noise.

Ajax-flavoured

I'll talk more about the new features below, but one stands out in particular: they added a XMLHttpRequest class.

This is interesting, since it blurs the line between Ajax applications even more. Considering that the recently released ZK framework is called an Ajax/Xul framework, I'd say that with the introduction of this class, OpenLaszlo is now 'worthy' of the Ajax label too.

The funny part is that this new XMLHttpRequest really is more of a publicity stunt than anything else. It is less powerful than Laszlo's standard asynchronous datasets approach, as is gently suggested in the release notes:

For AJAX style applications, there now is an XMLHttpRequest class. This class implements XMLHttpRequest as specified by the WHATWG consortium.

XMLHttpRequest() implements the functionality of the <dataset> tag in a syntax that is more familiar to people with AJAX programming experience. If you are comfortable using datasets there is no reason to use this class.

Now let's summarize some of the other features that I find interesting:

Rich Text Class

I'm really happy that this class finally makes its appearance. This means that it's a lot more feasible to provide rich WYSIWYM editing capabilities to administration interfaces. Since I'm currently considering building a CMS with an OpenLaszlo interface, I'm very excited about this new capability.

The formatting capabilities include:

  • Text style of bold, underline, or italics
  • Font type and size
  • Text color
  • Hyperlink creation, specifying a URL, and choosing a target type
  • Paragraph alignment: left, right, center
  • Block indent/outdent

While this is a good start, I think this class will only really become useful if it supports lists (ordered and unordered), images and tables. Making it possible to toggle one of a pre-defined set of CSS styles would also be welcome.

My major pet-peeve with this class is that it suffers from the same flaw as most text input classes that OpenLaszlo provides: there has been little thought about how people would use it by default. To set it up with scroll-bars is extremely tedious, difficult and requires a lot of lines of code. There is also no undo/redo support. While I understand that this class (just as the inputtext class) is useful as a single-line input field, I think it's important that OpenLaszlo's text classes adapt their lay-out to their multiline attribute. If it's present, scroll-bars should be added automatically since this is what users expect in 99.99% of the cases.

The documentation for this class is also lacking and it took me a great deal of searching to throw an example together.

Here it is:

I also included the code, so that other people don't have to go through the same odyssey.

<canvas bgcolor="white" proxied="false">
    
<class name="toggleformatbutton" extends="button">
        
<attribute name="format" value="" type="string"/>
        
<attribute name="_size" value="-1" type="number"/>
        
<attribute name="_pos" value="-1" type="number"/>
        
<method event="onmouseover">
            this._size = content.getSelectionSize()
            this._position = content.getSelectionPosition()
        
</method>
        
<method event="onmouseout">
            this._size = -1
            this._position = -1
        
</method>
        
<method event="onclick">
            if (this._size != -1) {
                content.toggleFormat(this.format, this._position, this._position+this._size);
                content.setSelection(this._position, this._position+this._size);
            }
        
</method>
    
</class>
    
<vbox width="${parent.width}" height="${parent.height}">
        
<hbox>
            
<toggleformatbutton format="bold">B</toggleformatbutton>
            
<toggleformatbutton format="italic">I</toggleformatbutton>
            
<toggleformatbutton format="underline">U</toggleformatbutton>
        
</hbox>
        
<view bgcolor="gray" width="300" height="100">
            
<richinputtext bgcolor="white" id="content" multiline="true"
                          
x="1" y="1" width="${parent.width-2}" height="${parent.height-2}">
                
<![CDATA[
                <b>default</b> text goes here<br />
                <i>default</i> text goes here<br />
                <u>default</u> text goes here
                ]]>
            
</richinputtext>
        
</view>
    
</vbox>
</canvas>

Charting components

Being able to display statistics easily in a graphical fashion can be very useful, just look at Google Analytics, their graphs are all done in Flash.

It's clearly stated in the release notes that the charting features are of beta quality, so don't expect them to be very polished. The demos inside the reference documentation don't work, I suspect they use an outdated version of the API.

The documentation is very terse and you don't get more than a raw API overview. Initially I was completely put off since I couldn't get anything working properly, then I found the lps/components/charts/test/integral/ directory in the distribution. It contains fully working demonstrations of how to use most features. Sadly, they look very bad and it seems the authors went overboard in demonstrating how ugly you can make the charting styles. The demos also contain a number of bugs.

Again, the default styles look like crap. You really have to spend a long time customizing until your charts look somewhat professional. I think it's very important that the default looks are top-notch and that you can quickly create some generic-looking charts without much effort. This needs quite some improvement.

To really evaluate the feature, I customized one of the demos until I obtain something that I found acceptable. Notice how you can select a rectangular area to zoom in, very slick!

This is the result:

For the interested few, here's the code:

<canvas width="400" height="460" debug="false" proxied="false">
    
<include href="charts/addon/zoomarea.lzx"/>
    
<include href="charts/addon/slider/slider.lzx"/>

    
<simplelayout axis="y" spacing="10"/>

    
<!-- the toolbar at the top -->
    
<hbox spacing="10">
        
<button>undo
            
<method event="onclick">
                chart1.undo(500);
            
</method>
        
</button>
        
<button x="100">show all points
            
<method event="onclick">
                chart1.changeBound(chart1.defaultminx, chart1.defaultminy,
                chart1.defaultmaxx,chart1.defaultmaxy, 1000, true);
            
</method>
        
</button>

        
<rangeslider x="100" id="slider" minlimit="0" maxlimit="18"
                     
startlabel="2004" endlabel="1987">
            
<method event="onminvalue">
                if(chart1.initdone)
                {
                    chart1.changeBound(chart1.minx, this.minvalue, chart1.maxx, this.maxvalue);
                }
            
</method>
            
<method event="onmaxvalue">
                if(chart1.initdone)
                {
                    chart1.changeBound(chart1.minx, this.minvalue, chart1.maxx, this.maxvalue);
                }
            
</method>
        
</rangeslider>
        
        
<legend name="legendbox" legendborder="false" chart="${chart1}">
            
<method event="onitemmouseclick" args="item">
                var topseries = this.chart.getDataSeries();
                topseries.getDataSeries(item.identifier).enabled = item.linevisible;
                this.chart.renderPlotArea();
                item.linevisible = !item.linevisible;
            
</method>
        
</legend>
    
</hbox>

    
<!-- the barchart itself -->
    
<barchart id="chart1" width="400" height="400" datatipEnabled="true" datatipColumn="tooltip"
              
style="custombarstyle" datalabelEnabled="true" datalabelColumn="datalabel">

        
<dataseries datapath="baseball:/records">
            
<datacolumn name="y" columndatapath="record/@year" datatype="number"/>

            
<dataseries label="wins">
                
<datacolumn name="x" columndatapath="record/@wins" datatype="number"/>
                
<datacolumn name="datalabel" columndatapath="record/@wins"/>
                
<datacolumn name="tooltip" columndatapath="record">
                    
<method name="processData" args="v">
                        return "year: " + v.attributes.year + " wins: " + v.attributes.wins;
                    
</method>
                
</datacolumn>
            
</dataseries>

            
<dataseries label="losses">
                
<datacolumn name="x" columndatapath="record/@losses" datatype="number"/>
                
<datacolumn name="datalabel" columndatapath="record/@losses"/>
                
<datacolumn name="tooltip" columndatapath="record">
                    
<method name="processData" args="v">
                        return "year: " + v.attributes.year + " losses: " + v.attributes.losses;
                    
</method>
                
</datacolumn>
            
</dataseries>
        
</dataseries>

        
<barchartplotarea name="plotarea"/>

        
<horizontalaxis name="haxis" title="Values" type="linear" interval="3"
            
columnName="x" titleLocation="low"/>
        
<verticalaxis name="vaxis" title="Years" type="categorical"
            
columnName="y" titleX="-30" titleY="${(chart1.height)/2}"/>
        
<zoomarea/>
    
</barchart>

    
<!-- the style of the chart -->
    
<font name="myverity" src="verity/verityplus11.ttf"/>
    
    
<chartstyle name="custombarstyle">
        
<plotstyle name="plot" linesize="0" opacity="0"/>
        
<chartbgstyle name="chartbgstyle">
            
<linestyle name="line" size="2" color="gray"/>
            
<regionstyle name="region" color="white" opacity="1"/>
        
</chartbgstyle>
        
<axisstyle name="haxisstyle">
            
<labelstyle name="label" font="myverity" fontsize="8" fontcolor="0xff0000"/>
        
</axisstyle>
        
<axisstyle name="vaxisstyle">
            
<labelstyle name="label" font="myverity" fontsize="8" fontcolor="0xff0000" fontangle="90"/>
        
</axisstyle>
        
<datastylelist name="datastyles">
            
<datastyle>
                
<pointstyle name="point" width="10" height="10"/>
                
<linestyle name="line"/>
                
<regionstyle name="region" color="0x00cc00"/>
                
<labelstyle name="label" font="serif" fontsize="10" fontcolor="0xffffff" linecolor="0x000000" fillcolor="0x00aa00" linesize="1"/>
                
<labelstyle name="tip" font="serif" fontsize="10" fontcolor="0xffffff" opacity="0.8" linecolor="0x008800" fillcolor="0x00aa00" linesize="1"/>
            
</datastyle>
            
<datastyle>
                
<pointstyle name="point" width="10" height="10"/>
                
<linestyle name="line"/>
                
<regionstyle name="region" color="0x0ff3300"/>
                
<labelstyle name="label" font="serif" fontsize="10" fontcolor="0xffffff" linecolor="0x000000" fillcolor="0xff3300" linesize="1"/>
                
<labelstyle name="tip" font="serif" fontsize="10" fontcolor="0xffffff" opacity="0.8" linecolor="0x993399" fillcolor="0xff3300" linesize="1"/>
            
</datastyle>
        
</datastylelist>
    
</chartstyle>

    
<!-- the dataset that i used to populate the chart, can be fetched remotely -->
    
<dataset name="baseball">
        
<records>
            
<record year="2004" league="AL East" wins="98" losses="64" finish="WS,2" stadium="Fenway Park II"/>
            
<record year="2003" league="AL East" wins="95" losses="67" finish="WC,2" stadium="Fenway Park II"/>
            
<record year="2002" league="AL East" wins="93" losses="69" finish="2" stadium="Fenway Park II"/>
            
<record year="2001" league="AL East" wins="82" losses="79" finish="2" stadium="Fenway Park II"/>
            
<record year="2000" league="AL East" wins="85" losses="77" finish="2" stadium="Fenway Park II"/>
            
<record year="1999" league="AL East" wins="94" losses="68" finish="WC,2" stadium="Fenway Park II"/>
            
<record year="1998" league="AL East" wins="92" losses="70" finish="WC,2" stadium="Fenway Park II"/>
            
<record year="1997" league="AL East" wins="78" losses="84" finish="4" stadium="Fenway Park II"/>
            
<record year="1996" league="AL East" wins="85" losses="77" finish="3" stadium="Fenway Park II"/>
            
<record year="1995" league="AL East" wins="86" losses="58" finish="DIV,1" stadium="Fenway Park II"/>
            
<record year="1994" league="AL East" wins="54" losses="61" finish="4" stadium="Fenway Park II"/>
            
<record year="1993" league="AL East" wins="80" losses="82" finish="5" stadium="Fenway Park II"/>
            
<record year="1992" league="AL East" wins="73" losses="89" finish="7" stadium="Fenway Park II"/>
            
<record year="1991" league="AL East" wins="84" losses="78" finish="2" stadium="Fenway Park II"/>
            
<record year="1990" league="AL East" wins="88" losses="74" finish="DIV,1" stadium="Fenway Park II"/>
            
<record year="1989" league="AL East" wins="83" losses="79" finish="3" stadium="Fenway Park II"/>
            
<record year="1988" league="AL East" wins="89" losses="73" finish="DIV,1" stadium="Fenway Park II"/>
            
<record year="1987" league="AL East" wins="78" losses="84" finish="5" stadium="Fenway Park II"/>
            
<record year="1986" league="AL East" wins="95" losses="66" finish="AL,1" stadium="Fenway Park II"/>
        
</records>
    
</dataset>

</canvas>

Canvas improvements

The canvas can now add events to the browser history. I'm very excited about this feature, since it means that people can use the browser back and forward buttons to step through individual stages of an animated drawing.

The developer documentation has a completely new section that gives a great introduction about how to get started with the <drawview> API. Thanks!

For those that would like to see a simple example of what the drawing API can do, take a look at this:

The code is very trivial:

<canvas width="200" height="200" debug="false" proxied="false">
    
<class name="circle" extends="drawview" >
        
<attribute name="circlecolor" value="white"/>
        
<attribute name="r" value="100"/>
        
<method event="oninit">this.redraw();</method>
        
<method event="onr"> this.redraw();</method>
        
<method name="redraw" ><![CDATA[
            this.clear();
            this.beginPath();
            this.moveTo(x+r, y);
            var a = Math.tan(22.5 * Math.PI/180);
            for (var angle = 45; angle<=360; angle += 45) {
                // endpoint:
                var endx = r*Math.cos(angle*Math.PI/180);
                var endy = r*Math.sin(angle*Math.PI/180);
                // control:
                // (angle-90 is used to give the correct sign)
                var cx =endx + r*a*Math.cos((angle-90)*Math.PI/180);
                var cy =endy + r*a*Math.sin((angle-90)*Math.PI/180);
                this.quadraticCurveTo(cx+x, cy+y, endx+x, endy+y);
            }
          
            var g = this.createLinearGradient(0, 0, 8, x+r, y+r, 0)
            this.globalAlpha = 1;
            g.addColorStop(0, 0xffffff);
            this.globalAlpha = 0;
            g.addColorStop(1, this.circlecolor);
            this.fillStyle = g;
            this.fill()
            this.globalAlpha = 1;
            this.linewidth= 5;
            this.stroke();
        ]]>
        
</method>
    
</class>

    
<circle r="50" x="50" y="50" circlecolor="blue"/>
    
<circle x="50" y="50" circlecolor="teal">
       
<animatorgroup process="sequential" repeat="Infinity">
        
<animator attribute="r" from="20" to="0" duration="3000"/>
        
<animator attribute="r" from="0" to="20" duration="3000"/>
      
</animatorgroup>
    
</circle>
     
</canvas>

Conclusion

OpenLaszlo 3.1 is a good minor release with some interesting new features.

However, I would have liked a stronger focus on making the existing components easier to work with when coming from another GUI background. I still think that the form and text components need work to be more similar to what people with a regular HTML background expect.

A number of important bugs have been fixed though. The fact that memory consumption should be lower, that some leaks have been fixed and that Flash 8 can be targeted is a step in the right direction to improve the performance of the applications.

posted by Geert Bevin in Laszlo on Nov 24, 2005 2:49 PM : 6 comments [permalink]
 

Comments

Re: OpenLaszlo 3.1 released, it's AJAX now!
great blog entry! OpenLaszlo really rocks and we will hear more from it in the future....
Re: OpenLaszlo 3.1 released, it's AJAX now!
Thank you for the thorough overview of the OpenLaszlo 3.1 release - along with the code samples, really helps in regards to understanding how OpenLaszlo could be used and where any potential pitfals might be.

Making the text components easier to use would definately be a welcome addition - but I'm wondering how much of that is in some ways actually the limitations of the Flash player itself? Working with text elements in Flash (especially html text) has always been a frustrating experience - as I believe lists and images have never really been supported.

That said, having a scroll bar automagically appear when needed (or as an option) would definately go a long way in the short term.
Re: OpenLaszlo 3.1 released, it's AJAX now!
Hi Bryan,

there is already a component in the OpenLaszlo incubator that let's a scrollbar appear automagically, I helped fine-tuning it. It has to be updated for the rich text component though.

Imho this shouldn't be a separate component though and supported in the default ones when the multiline attribute is set. I'll see if I can contribute that to the repository when I get some time for it.

Thanks for the nice words.
Re: OpenLaszlo 3.1 released, it's AJAX now!
:D
It's Great!
Thanks for your chart ex.!
Re: OpenLaszlo 3.1 released, it's AJAX now!
Hello Geert,

Thanks a lot for this helpful article. I am new to RIA and Laszlo as well as OOP. I would like to learn all these things well. I already installed OpenLaszlo 3.2 and the demos are amazing.

Can you suggest tutorials or demos of how to make or adapt a simple WYSIWYM editor including Images with upload capabilities to a single one directory of images, that can be used in text Area database fields with OpenLaszlo, any references are very welcome. I plan to use PHP and MySQL.

Thanks again for your excellent article.
Best regards
Joejac
Is OpenLaszlo the right platform?
I have a wild idea of making the mouse do lots more. I want an entire zoom world to be accessible by just mousing. Rollover into a contained zone written smaller auto-zooms into it exactly to where the text is the natural size that the viewer prefers. Recursively.

I'm thinking that if the contents of the zoom world are just text and images and maybe a video or two, then this is an almost trivial application of FlexibleRails or OpenLaszlo. I expect to pay for an answer, more for more detail about how and why.

Having the content in a database would seem to permit arbitrary rearrangement on the fly without changing the application a whit and thus needing nothing but new data. Each region has a natural screen size and contains deeper regions without limit. Zooming in and out is automatic. Just mousing does all navigation needed to see the whole site. Then we can add command gestures, and still no buttons or keys until you are filling in some form. Still nearly trivial to implement in FlexibleRails or OpenLaszlo. Right?

Is it possible that that is true? Or nearly true? On either platform?
Can I pay someone to answer questions like this?


Richard Karpinski, World Class Nitpicker
148 Sequoia Circle, Santa Rosa, CA 95401
dick@cfcl.com Home +1 707-546-6760 Cell +1 707-228-9716

ps Put (or leave) "nitpicker" in the subject line to get past my spam filters.

Add a new comment

Comments on this blog entry have been closed.

< Introducing RIFE LiveGuide   RIFE at JavaPolis 2005 >
 
 
 
Google
rifers.org web