[Seaside] Creating a component that requires a callback:
philippe.marschall at gmail.com
Sun Nov 23 18:15:51 UTC 2008
2008/11/21 Gerardo Richarte <gera at corest.com>:
> Hi, I'm pretty new to seaside, and it's only parttime, but well, I'm anyway
> trying to implement some sort of AMChartsComponent (www.amcharts.com) (I
> find it nicer and better than PlotKit)
> It should't be tricky, however, two things are making my process very slow:
> call is a URL to an XML file. Maybe I can make this XML file be static, and
> then use AMChartsLibrary / #something, but maybe I need to dynamically
> create this XML, and hence I want to have some sort of callback: mechanism,
> so Seaside creates a dynamic URL, and the block answers with the XML. My
> question is, how do I create a component like this? suppose my
> renderContentOn: today looks something like:
> html script: 'doSomethingRequiringURL("http://localhost/seaside/blah");'
> I guess I could somehow turn it into:
> html script: 'doSomethingRequiringURL(', (AMChartLibrary / #lahpreparedXML)
> but I'd really like to do something more like
> html amchart
> settings: [:xml | xml blah...]
> for example.
> And then, inside this XML there is another URL, that points to the data
> source to plot. I'm still not sure how the interface to all this will look
> like, but I certainly want this URL to again, be generated dinamically.
> so, a couple of questions.
> . How do I create a component that uses something like the callback
> mechanism? (how do I get seaside to generate the URL for me and do all its
> . Do you have any design ideas on how I should better implement this? I
> guess I'll try to follow how PlotKit is used, so the interfaces to the two
> are somehow compatible.
> Right now I only want a quick hack, but eventually, if this finally works
> and I somehow like it, I'll contribute it... of course, if somebody has
> already done it, I'm more than willing to reuse :)
What you're about to do is pretty advanced in terms of Seaside use.
You'll be confronted with implementation details that the normal
component developer never comes in contact with.
You have more or less four choices what you can subclass: WAComponent,
WATask, WACompound or building your own factory like Scriptaculous (or
WACompound isn't really an official public class and is merely used
for implementation of WADateInput and WATimeInput. However if you want
your classes to be used through the html canvas you have to use
WACompound because WAComponent and WATask instances have to be
reachable through #children or #call:.
WAComponent and WATask have state that persists over multiple
requests. They can very well take a block and evaluate it at some
For building XML consider making your own canvas. Have a look at RSRSS
for an example.
A possible quick hack could look like this:
WAComponent subclass: #ChartComponent
settingsBlock := aNoArgumentBlock
callbackUrlFor: aNoArgumentBlock using: aCanvas
^aCanvas context actionUrl copy addParameter: (aCanvas
callbacks registerActionCallback: aNoArgumentBlock)
self session returnResponse: (WAResponse
document: (SettingsCanvas builder
html script: 'doSomethingRequiringURL(', self callbackUrlFor:
[ self settingsXml ]');'
While probably not the nicest implementation it should be enough to
get you started.
callbacks are made or supported. PlotKit also uses components and not
Other places where you can look for inspiration are Scriptaculous
(generates XML and JS dynamically for the client, can be used through
the html canvas) and Sextant (SVG with callbacks).
AFAIK DabbleDB uses flash for at least some of their charts so maybe
they can help you as well.
More information about the seaside