PDA

View Full Version : Tree issues


rufiao
12-18-2004, 01:53 PM
I've been trying to implement some extended functionalities in the tree component, and I have found some odd issues in the coding of the basetree component. It seems it is quite dependent on the 'isleaf' attribute, which makes matters complex for whoever wants to maintain a dynamic tree (one that, after initilized, has its nodes added/removed at runtime by modifying a bound dataset). Changing that doesn't seem to be trivial. Besides, I couldn't make an xpath expression to evaluate if a given node has subnodes or not in a dataset:

<tree datapath="ancestors:/" showroot="false">
<tree datapath="*" text="$path{'@name'}" isleaf="$path{'count(//)=0'} />
</tree>

On another issue, I'm trying to make a tree which can accept nodes to be 'links' to other nodes, thus inheriting all subnodes from the 'target' node automatically. Any ideas on how to do this?

Any help is greatly appreciated.

metasarah
12-20-2004, 05:08 AM
I don't think that xpath expression is supported. The list of supported xpath expressions is here: http://www.laszlosystems.com/lps-2.2/docs/guide/data-structures.html#data-structures.xpathnodes

I think you could do something like this:

<tree datapath="ancestors:/" showroot="false">
<tree datapath="*" text="$path{'@name'}" isleaf="this.subnodecount == '0'" subnodecount="$path{'/*/count()'}"/>
</tree>

Note: path expressions evaluate to strings.

Sarah

pablo
12-20-2004, 02:19 PM
Hi rufiao,

Here's the best workaround I could come up with:
<canvas>

<include href="lz/tree.lzx"/>

<dataset name="ancestors">
<node name="one">
<node name="a1"/>
<node name="b1" />
<node name="c1"/>
</node>
<node name="two">
<a name="a2"/>
<b name="b2"/>
<c name="c2"/>
</node>
<node name="three"/>
</dataset>

<tree x="20" y="20" datapath="ancestors:/" showroot="false">
<tree datapath="*" text="$path{'@name'}">
<!-- count() not working as expected so using '.' xpath to get current node -->
<attribute name="isleaf" value="$path{'.'}" setter="_setIsLeaf(isleaf)" />

<!-- The leaf argument can be a boolean or datapath. A datapath
will return an LzDataElement if it's a node, or a string if
it's a value. -->
<method name="_setIsLeaf" args="leaf">
if (leaf instanceof LzDataElement) {
if (leaf['childNodes']) {
leaf = (leaf.childNodes.length == 0)
} else {
// childNodes is undefined
leaf = true;
}
}
super._setIsLeaf(leaf);
</method>
</tree>
</tree>

</canvas>I couldn't get the count() xpath expression to work. I've filed a bug on this.On another issue, I'm trying to make a tree which can accept nodes to be 'links' to other nodes, thus inheriting all subnodes from the 'target' node automatically. Any ideas on how to do this?Here's an example on how to inherit subnodes from another dataset:
<canvas>

<include href="lz/tree.lzx"/>

<dataset name="ancestors">
<node name="one">
<node name="a1"/>
<node name="b1" />
<node name="c1"/>
</node>
<node name="two">
<a name="a2"/>
<b name="b2"/>
<c name="c2"/>
</node>
<node name="three"/>
</dataset>

<dataset name="moredata">
<node name="another1">
<node name="L11"/>
<node name="L12"/>
<node name="L13"/>
</node>
<node name="another2" />
<node name="another3">
<node name="L31"/>
<node name="L32"/>
<node name="L33"/>
</node>
</dataset>

<tree datapath="ancestors:/" showroot="false">

<tree datapath="*" text="$path{'@name'}">

<attribute name="isleaf" value="$path{'.'}"
setter="_setIsLeaf(isleaf)" />

<method name="_setIsLeaf" args="leaf">
if (leaf instanceof LzDataElement) {
if (leaf['childNodes']) {
leaf = (leaf.childNodes.length == 0)
} else {
// childNodes is undefined
leaf = true;
}
}
super._setIsLeaf(leaf);
</method>

<!-- Like basetree.createChildTrees() method, but simpler. Note that
this tree's children view is set to root datapath of 'moredata'
dataset. -->
<method name="linkIt">
<![CDATA[
// Replication manager overrides clone's _instanceAttrs, so we
// have to redo them here.
var args = {};
for (var a in this._instanceAttrs) {
if (a == 'id') continue;
if (a == 'showroot') continue; // skip for non-root trees
args[a] = this._instanceAttrs[a]
}

this.children.setDataPath('moredata:/');
args.datapath = '*';

new global[this.classname](this, args, null, true);

// no longer a leaf because it has children
this.setAttribute('isleaf', false);
]]>
</method>


<method event="onselected" args="isselected">
<![CDATA[
// fetch data only if this tree is a leaf
if (isselected && this.isleaf) {
//
this.linkIt();
}
]]>
</method>
</tree>
</tree>

</canvas>
Hope this helps.

pablo