PDA

View Full Version : Dynamically adding views using a dataset


jpan
04-14-2004, 07:38 AM
Hi,

Using the samples in Laslo-in-Ten-Minutes, I have this section of code:


<canvas>

<dataset name="dset">
<phonebook>
<employee>
<firstName>John</firstName>
<lastName>Smith</lastName>
<phone>617-536-7855</phone>
<x>100</x>
<y>0</y>
</employee>
<employee>
<firstName>Lisa</firstName>
<lastName>Jones</lastName>
<phone>617-536-5216</phone>
<x>0</x>
<y>100</y>
</employee>
</phonebook>
</dataset>

<simplelayout/>
<view datapath="dset:/phonebook/employee">
<view width="10" height="10" bgcolor="red" x="${x/text()}" y="${y/text()}" />
</view>

</canvas>


... which I thought would put two red squares in two different places, and that's not working out. What would be the correct way to do this?

In essence, I need to dynamically add views into another view based on some dataset, and the dataset contains GUI info, such as width, height, x, y, and maybe a resource field. How can I accomplish this?

Thank you!

antun
04-14-2004, 09:28 AM
I think it's the format of your constraints:


<view width="10" height="10" bgcolor="red" x="${x/text()}" y="${y/text()}" />


If you want to constrain something to a datapath, you want to use this syntax:


<view width="10" height="10" bgcolor="red" x="$path{'x/text()'}" y="$path{'y/text()'}" />


The syntax you used is for when you want to constrain to an expression or object attribute.

-Antun

jpan
04-14-2004, 09:54 AM
Hi,

So I made the changes you provided, and took out some other junk that I don't need for now... and here's the new code:


<canvas>
<dataset name="dset">
<phonebook>
<employee>
<x>100</x>
<y>0</y>
</employee>
<employee>
<x>50</x>
<y>100</y>
</employee>
</phonebook>
</dataset>
<view x="0" y="0" name="MobileUnitsLayer" height="300" width="400" datapath="dset:/phonebook/employee" bgcolor="red" >
<view resource="cd_cover.jpg" x="$path{'x/text()'}" y="$path{'y/text()'}" />
</view>
</canvas>


But it still doesn't work, and only one image is displayed... what am I doing wrong?

antun
04-14-2004, 10:03 AM
Here's what's happening:

When you set a views datapath to an XML node that matches more than once (dset:/phonebook/employee; there are two employee tags), that view gets cloned as many times as needed. So two copies of your big red view get created.

Unless otherwise specified, views get created at the origin of their parent (0,0), so both your big red views are sitting on top of one another, and you can't see the one below.

To see what's going on, try:


<canvas debug="true" height="800">
<dataset name="dset">
<phonebook>
<employee>
<x>100</x>
<y>0</y>
</employee>
<employee>
<x>50</x>
<y>100</y>
</employee>
</phonebook>
</dataset>

<simplelayout spacing="10" />

<view x="0" y="0" name="MobileUnitsLayer" height="300" width="400"
datapath="dset:/phonebook/employee" bgcolor="red" >
<view resource="cd_cover.jpg" x="$path{'x/text()'}"
y="$path{'y/text()'}" />
</view>
</canvas>


(Added simplelayout and made canvas taller).

If you wanted both cd covers to be in the same red view (which I think is what you're trying to do), then give the CD cover view the datapath that replicates:


<view x="0" y="0" name="MobileUnitsLayer" height="300" width="400"
datapath="dset:/phonebook" bgcolor="red" >
<view resource="cd_cover.jpg"
datapath="employee"
x="$path{'x/text()'}"
y="$path{'y/text()'}" />
</view>


-Antun

jpan
04-14-2004, 11:04 AM
Hi Antun!

It worked like a charm! Now another question;


<view x="0" y="0" name="MobileUnitsLayer" height="300" width="400"
datapath="dset:/phonebook" bgcolor="red" >
<view resource="cd_cover.jpg"
datapath="employee"
x="$path{'x/text()'}"
y="$path{'y/text()'}" />
</view>


Suppose in the XML dataset, x/y contained values that need to be converted to be displayed, how can I pass the values into another method?

e.g. I want to pass $path{'x/text()'} to another function that, say, doubles it.

<method name="double" args="value">
return value*2;
</method>


How can I incorporate the method "double" into the code above??

Thanks!

antun
04-14-2004, 11:27 AM
The path constraint syntax is really a convenience. If you want to get any deeper, I would suggest setting a method to go off when the view sends the ondata event.

So inside your view that's bound to the employee, you might add something like:

<method event="ondata">
var newX = 2 * this.datapath.xpathQuery('x/text()');
this.setX( newX );
</method>

That should work. Let me know if it does.

-Antun

jpan
04-14-2004, 01:10 PM
It worked great! Thank you very much Antun!