dominoGuru.com
Your Development & Design Resource
IBM XPages Demo: Using xp:repeat controls to create dynamic xp:radioGroups
07/13/2012 01:03 PM by Chris Toohey
One of the main reasons I make myself available on pretty much every social network out there is that I like to help fellow developers whenever I can.
When I started out in IT (and in particular, using, administering, and eventually developing in IBM Lotus Notes Domino), Google+, Facebook, and Twitter didn't exist. Hell, there weren't really websites out there aside from notes.net and the forums therein where someone completely new to the platform could ask for help.
I cut my teeth in the LDD forums, and the only reason I am at the level that I'm at now (and learning more and more, hourly) is because of the people in this community.
There's not a day that goes by that I'm not bugging someone that I consider close friends (in a few cases, despite having never met them in person) for their feedback on (if not their outright help with) one thing or another.
So whether it's by email, Facebook, Twitter, Google+, or even Skype IM... I try to make myself available to anyone just starting out, anyone who knows what they're doing and needs another set of eyes on a given problem, or anyone who even just wants to connect with a fellow developer.
All that being said... I got the following tweet yesterday:
@christoohey Any easy way to get ssjs values for radio group buttons generated inside a repeat control? Tried via getChildren, but no values
— edm00se (@edm00se) July 12, 2012
While my typical response to such a request for help would be to contact the requester and ask for more details, I immediately saw the problem that Eric was running into here.
If I need to access the value of an input control (eg.,
xp:inputText, xp:radioGroup, et al), I'll use getComponent(target
control's ID).getValue()
. Since the xp:radioGroup was inside of
an xp:repeat control, the ID property was not going to be directly
accessible.
Now, the ideal approach would be to update some scoped variable on
a given event (such as onChange or onClick), and simply read the values from
that variable, but I also wanted to show how you could use the
getComponent().getValue()
method... which is where I ran into a
problem.
To programmatically set the ID property of a control in XPages, you'll need to compute that ID on page load. In other words, while you can't do this:
<xp:inputText
id="#{some logic here}"
value="document.example">
</xp:inputText>
You can do this:
<xp:inputText
id="${some logic here}"
value="document.example">
</xp:inputText>
The problem I ran into however, and what I think Eric's problem originally was, is that by default an xp:repeat control does not allow you compute a value (such as ID) on page load, even if you set the "$" operator/designation on the computed property.
So I reached out to Tim (Tripcony) who pointed out something I was totally overlooking:
xp:repeat - 'Create controls at page creation' Option
This "pretty panels" change (as Tim calls it) change adds the
repeatControls="true"
property to the xp:repeat, which fixes the
until-then-not-working ${}/on page load IDs.
Here's the xp:repeat XPage XML source from a demo I put together:
<xp:table>
<xp:repeat
id="radioGroups"
value="#{sessionScope['repeats']}"
var="repeatval"
repeatControls="true">
<xp:tr>
<xp:td>
<xp:label
value="#{repeatval}" />
</xp:td>
<xp:td>
<xp:radioGroup
id="${repeatval}"
value="#{sessionScope[repeatval]}">
<xp:selectItem
itemLabel="Option1"
itemValue="value1">
</xp:selectItem>
<xp:selectItem
itemLabel="Option2"
itemValue="value2">
</xp:selectItem>
<xp:selectItem
itemLabel="Option3"
itemValue="value3">
</xp:selectItem>
</xp:radioGroup>
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table>
This allows me to use my getComponent().getValue()
method as
long as I know the target ID... which I should be easily able to access
since I'm using some sort of logic to set it.
Again, from the demo:
<xp:repeat
value="#{sessionScope['repeats']}"
var="repeatval">
<xp:text
tagName="h3"
styleClass="header">
<xp:this.value><![CDATA[#{javascript:repeatval + " getComponent('" +
repeatval + "').getValue()";}]]></xp:this.value>
</xp:text>
<xp:text>
<xp:this.value><![CDATA[#{javascript:if(getComponent(repeatval)) {
getComponent(repeatval).getValue();
}}]]></xp:this.value>
</xp:text>
</xp:repeat>
Online / Live Demo
XPages xp:radioGroup Control Value Demos
This demo covers quite a few things, and is all driven via sessionScope variables. Thus, if the demo goes to hell for whatever reason, simply close the browser and start a new session.
Conclusion
It just to happen to work out that I needed something like this for a project that I'm working on. And I was honestly shocked when it "didn't just work" like I thought it would, and after a few minutes of head-scratching when the ${}-driven properties were returning "", I'm thrilled that I was able to yet-again bug a friend who pointed me in the right direction.
And I guess that's what it's all about, right? Paying it forward. Sending the elevator back down. Making sure you don't assume you're in the penthouse when you're actually still in the lobby. Wait, my analogy is falling apart --
At the beginning of this post, I said that one of the reasons I put myself out there is because I like to help. And while that's a large part of it, an almost equally large part is because it's another opportunity to learn.
I learn with every new project that comes my way.
And I learn from the questions and requests that friends and followers send me.
Each time someone sends me an email, asks a question via a tweet, sends me a Facebook or Skype IM, it's an amazing opportunity for me to learn; to evolve; to ultimately improve myself.
And it's a small way of paying back people like Stan Rogers and the like, who took a kid with a criminology degree and absolutely no experience under their collective wing, and selflessly gave.