They are based on simple @DbColumn and @DbLookup. But when the result array is only one entry the repeat control fails. The code below shows the failing repeat control (xp:link simplified to keep the code clean).
[Note: single results from @DbColumn or @DbLookup are returned as string and not an array.]
<xp:repeat id="repeat1" rows="30" var="rowData" indexVar="rowIndex">
<xp:this.value><![CDATA[#{javascript:
@Unique(@DbLookup("", "xpSectionList", sessionScope.regionFilter, 2))
}]]></xp:this.value>
<li>
<xp:link escape="true" id="linkSubSection" title="#{javascript:rowData}">
<xp:this.text><![CDATA[#{javascript:rowData}]]></xp:this.text>
</xp:link>
</li>
</xp:repeat>
After some searching I found a solution in the LDD by Bob Cross, "Hint for Repeating a single value".Repeat controls are great - but they MUST return an array, even if it is just one entry.The proposed solution works fine and does solve the problem, but I consider it a workaround for a bug. The repeat control should also work when a single value is returned.
In my example, I used a repeat control to display entries from a dblookup. However, some of my lookups only returned one entry, so the result was a string, not an array. Since the result of my dblookup was a string, the repeat control would not display the one returned result.
The solution is to convert the result to a string first by using valueOf(). This returns a string delimited by commas. Then split the result by the commas to get an array. If split fails, then the result was an array to start with.
var tmpstr = result.valueOf();
try {
var newarr = tmpstr.split(",");
return(newarr)
}
catch(err){
return(tmpstr);
}
I have filed a service request (PMR) with IBM. Please do the same if you think this should be solved!
[Note: IBM have responded to the PMR: The repeat control works as designed and expects an array as input.]
The
<xp:repeat id="repeat1" rows="30" var="rowData" indexVar="rowIndex">
<xp:this.value><![CDATA[#{javascript:
var result = @Unique(@DbLookup("", "xpSectionList", sessionScope.regionFilter, 2));
var tmpstr = result.valueOf();
try {
var newarr = tmpstr.split(",");
return(newarr)
}
catch(err){
return(tmpstr);
}
}]]></xp:this.value>
<li>
<xp:link escape="true" id="linkSection" title="#{javascript:rowData}">
<xp:this.text><![CDATA[#{javascript:rowData}]]></xp:this.text>
</xp:link>
</li>
</xp:repeat>
9 comments:
Do you have an SPR#?
It's early so I might not be reading this correclty... But doesn't Julians code on XPagesWiki.com solve this problem?
He has a code example that guarantees an array is returned.
http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_DbColumn_and_DbLookup
@David Leedy
Had not come accross Julians code in my search, but indeed the 2 functions at the bottom of the page do solve the problem similar to Bob Cross' solution on LDD.
In my mind it is still a workaround though for what the repeat control should handle itself.
@Erik Brooks - sorry, but no SPR# yet. PMR# is 87011 211 788.
the easiest way to do this is like this:
var r = @DbLookup(...);
return (r.constructor == Array) ? r : [ r ];
this gets the value, then compares the original array object to the object that r was constructed from. If it was an Array, then it returns r, otherwise it puts r into any array. Other functions (like julian's) check to see if the value is a string, but that may not be the case, it could be a date, or number, or whatever...
I really don't see this as a bug, and I can't see IBM changing the way this works really. The repeat works using iterators for known java types. If the object (remember a string is actually an object) doesn't have an iterator, then it really doesn't have a "set" of values ... The programmer should give the repeat what it needs to operate...
Your code screams for optimization. Use a function that only does the @DBLookup if you don't have a value in your session already. Will improve load performance and you can take care of the array thingi
Excellent, this thread just saved me lots of time.
Just a complaint to add to the fun. A NotesViewEntryCollection works fine with a Repeat Control, but why oh
why isn't there an Iterator in the NotesViewNavigator object?
Hi Tom
i 'm using your code and how can i remove [ ] chars.
Post a Comment