Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
THRUST SERVICES & TOOLS
CLOUD EDITIONS
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Web CMS (TeamSite)
Traversing DCR tree problem
intel
Hi all,
I'm using javascript to traverse the DCR tree and modify an item if its called "order". I need to do this to create unique identifiers for insertion with DataDeploy. I'm simply using getRootItems, then calling getChildren on each of these elements, and if that returns a value, recursing through and finding their children etc. Thats the plan, but it doesn't work. There are quite a few levels of replicant nesting here (maybe 4 or 5). Running the function with debugging messages in reveals that it gets down to 2 or 3 recursions then jumps back out and stays doing this infinitely.
The function is below, its called with the onSaveValid handler: genIdentity("root");
function genIdentity(name)
{
var rootItems=[];
var children=[];
(name == "root")?rootItems = IWDatacapture.getRootItems():rootItems[0] = IWDatacapture.getItem(name);
for (var i=0; i<rootItems.length; i++) {
children = rootItems
.getChildren();
if (children) {
for (var j=0; j<children.length; j++) {
genIdentity(children.getName());
}
}
var orderName = rootItems
.getName() + "\/order";
var orderValue = IWDatacapture.getItem(orderName);
if (orderValue) orderValue.setValue(i+1);
}
return true;
}
Any help would be gratefully received.
Cheers
Jason
Find more posts tagged with
Comments
Michael
Hi Jason
One potential problem you have is with this line:
var orderName = rootItems.getName() + "\/order";
You have defined rootItems above to be an array of items. Therefore you probably shouldn't be calling getName() on the array. Perhaps you meant:
var orderName = rootItems
.getName() + "\/order"; ?
hth
Cheers
Michael
jbonifaci
Didn't look at it too closely, but you'll probably want to change:
children = rootItems.getChildren();
to:
children = rootItems
.getChildren();
and:
var orderName = rootItems.getName() + "\/order";
to:
var orderName = rootItems
.getName() + "\/order";
intel
Thats weird, for some reason (i guess to do with the forum software), its not putting [ i ] properly, instead formatting everything following as italics.
So, the reformatted function (excuse spaces) is:
function genIdentity(name)
{
var rootItems=[];
var children=[];
(name == "root")?rootItems = IWDatacapture.getRootItems():rootItems[0] = IWDatacapture.getItem(name);
if (rootItems[0] != null) {
for (var i=0; i<rootItems.length; i++) {
children = rootItems
.getChildren();
if (children) {
for (var j=0; j<children.length; j++) {
genIdentity(children.getName());
}
}
var orderName = rootItems
.getName() + "\/order";
var orderValue = IWDatacapture.getItem(orderName);
if (orderValue) orderValue.setValue(i+1);
}
}
return true;
}
actually i'll just try posting with the "without Markup/HTML" option set
intel
Further to this, if the nested replicant is changed to a container, it works.
hmmmm.....
intel
Right.
This is driving me nuts and I have no easy workaround. However I've managed to provide a simplified version of datacapture.cfg so that you can see whats going on.
Basically in the attached file there are a couple of replicant and container nests. There are also some hidden fields called "order", and a js function that is called when the file is saved. What is supposed to happen is that the function traverses the element tree, and for each element, check whether it is called "order". If so, give it an incremental value. I need to do this in order to preserve display ordering (and uniqueness) for DataDeploy.
The function is recursive. It gets all the root items and for each of these checks whether it has children. If so, it calls itself iteratively with each of the children as an argument, consequently checking whether each of them have children and so on and so on.
The problem is that it doesn't work. In the attached datacapture.cfg, running it as it is will produce an infinite loop, yielding (in alert boxes):
recurse /nest1/name
recurse /nest1/display-name
recurse /nest1/display-order
recurse /nest1/description
recurse /nest1
recurse /nest1/name
...
...
...
where nest1 is a container and nest 2 is a replicant.
Now, changing
<!--container name="nest2" hide-name="f" combination="and"-->
<item name="nest2">
<replicant min="0" max="20" default="0">
to
<container name="nest2" hide-name="f" combination="and">
<!--item name="nest2">
<replicant min="0" max="20" default="0"-->
and the corresponding end tags, i.e. changing nest2 from a replicant to a container yields:
recurse /nest1/name
recurse /nest1/display-name
recurse /nest1/display-order
recurse /nest1/description
recurse /nest1/nest2
recurse /nest1/nest2/name
recurse /nest1/nest2/url
and then finishes. Which is expected behaviour (or at least closer to it) although it skips newnest1 altogether (possibly because its a replicant.)
Wrapping the replicant in a container doesn't work either.
We're running teamsite and templating 5.5.2 both with SP4 on Win 2000 SP3
Again, any help would really help.
Cheers
Jason
JonathonG
Hmm, not sure why its giving you an infinite loop, but what happens if you change the replicant's min attribute to 1. Does that make it go in there? I'm suspecting it has something to do with calling getChildren on a replicant which has no instances.
Jonathon
Independent Interwoven Contractor
intel
OK,
so i finally figured it out and am posting here for future reference for anyone else who is stumped.
The problem is that TS fakes XPath, so the path that you get when you do IWItem.getName() is not representative of the true path.
For replicants, there is another (hidden) node level. (which is why containers worked, but replicants didn't).
Here is my modified code:
var count = 1;
var rootItems = IWDatacapture.getRootItems();
for(var i=0;i<rootItems.length;i++) {
genIdentity(rootItems
);
}
function genIdentity(itemObj) {
if (itemObj.getName().indexOf("\/display-order")!=-1){itemObj.setValue(count++);return true;}
var children = itemObj.getChildren();
if (children) {
for (var j=0;j<children.length;j++) {
var replicantchildren = children.getChildren();
if (replicantchildren) {
for (var k=0;k<replicantchildren.length;k++) genIdentity(replicantchildren);
}
else genIdentity(children);
} }
return true;
}
bar_chart.bmp