2

I have this problem with XForms I am running on Orbeon Forms. I am using a fr:box-select control as follows:

<fr:box-select bind="box-select-bind" id="box-select-control">
        <xforms:action ev:event="xforms-value-changed">
         <xxforms:variable name="selected-value" select="."/>
         <xforms:message level="modal">Hello:<xforms:output select="$selected-value" />
         </xforms:message>

        </xforms:action>

        <xforms:itemset nodeset="instance('codes')/box-select/item">
                                    <xforms:label ref="label"/>
                                    <xforms:value ref="value"/>
         </xforms:itemset>
   </fr:box-select>

The binding is to a simple XML file:

<box-results></box-results>

The codes XML looks like:

<box-select>
    <item>
        <label>Cat</label>
        <value>cat</value>
    </item>
    <item>
        <label>Dog</label>
        <value>dog</value>
    </item>
    <item>
        <label>Bird</label>
        <value>bird</value>
    </item>
    <item>
        <label>Fish</label>
        <value>fish</value>
    </item>
</box-select>

When I check entries in the box, my node <box-results> gets updated with the selected values separated by a space, which seems to be what is expected. However, I can't seem to find any documentation on how to process the selected values. I want to get access to what value was just selected, de-selected and use the value of this item in an xpath. So, if a value was selected then I would do this:

<setvalue
 ref="somexpath[id=$selected-value]/display
 value="'true'"/>

And if a value was deselected I would do this:

<setvalue
 ref="somexpath[id=$selected-value]/display
 value="'false'"/>

Basically, I just want to know the event to use, and how to get access to the value when it fires. Then I want to use this value in an xpath. I am going to use this to hide/display portions of the form. Using the xforms-value-changed event the Xpath "." doesn't return what I would expect, as it does in "select1" controls.

I can loop through all the values that are selected like so:

<xforms:action ev:event="xforms-select" xxforms:iterate="for $s in tokenize(instance('data-inst')/box-results,'\s')return xxforms:element('text',$s)">
    <xforms:message level="modal">Hello selected:<xforms:output select="$s" />
</xforms:action>

However, this isn't exactly what I need. I might be able to make this work, but it would require a lot more work because I need to do know what ones are deselected to change the display for the user.

avernet
  • 30,895
  • 44
  • 126
  • 163
devo
  • 1,290
  • 1
  • 15
  • 28

2 Answers2

3

Since in your case you don't need to know specifically which value changed, you can on value change reset all the values in somexpath[id=$selected-value] as needed. You can do this with the following code which uses just <xforms:setvalue> with an xxforms:iterate:

<xforms:action ev:event="xforms-value-changed">
    <xxforms:variable name="selected-values" select="tokenize(., '\s+')"/>
    <xforms:setvalue xxforms:iterate="instance('codes')/item" 
                     ref="@selected">false</xforms:setvalue>
    <xforms:setvalue xxforms:iterate="$selected-values"
                     ref="for $v in . return instance('codes')/item
                     [value = $v]/@selected">true</xforms:setvalue>
</xforms:action>

Also see the full source of an example that uses the above snippet.

avernet
  • 30,895
  • 44
  • 126
  • 163
  • Hey, thanks for your reply. This is what I was thinking of doing but was looking to see if there was a way to get at the individual item selected/deselected. I didn't realize you could use the iterate on the setvalue command, thanks for that! One thing though. I wasn't able to get the tokenize to use the "." xpath, I had to go to my instance where the data is being stored like so: select="tokenize(instance('codes')/box-results, '\s+')". Not sure why that is, but it works at any rate. Thanks again, you showed me a couple of things about orbeon I didn't know. – devo Sep 27 '11 at 14:21
  • Right: for XBL components, unlike what you have with regular XForms controls, the context in which the event handler runs isn't changed by the `ref` attribute on the component. In my example it works by "chance", as I had an `` which doesn't change the context. But in a more general case, you are right: you can't use `.` in the event handler and count on this being the node to which the `` is bound. – avernet Sep 27 '11 at 18:40
  • To complete @avernet's comment: the behavior of the XPath context here is a bug. – ebruchez Sep 29 '11 at 04:03
0

you can use ev:event="xforms-select" and ev:event="xforms-deselect" events.

Also the selected value can be captured using event('xxforms:item-value')

Here is how it would be used in case anyone is wondering:

<xforms:action ev:event="xforms-select">
<xxforms:variable name="selected" select="event('xxforms:item-value')" />
<xforms:message level="modal">Select:<xforms:output value="$selected" /></xforms:message>
</xforms:action>

<xforms:action ev:event="xforms-deselect">
<xxforms:variable name="deselected" select="event('xxforms:item-value')" />
<xforms:message level="modal">deSelect:<xforms:output value="$deselected" />
</xforms:message>
</xforms:action>   
devo
  • 1,290
  • 1
  • 15
  • 28
Jayy
  • 2,368
  • 4
  • 24
  • 35
  • Thanks, that works great too. I updated your post with an example. BTW, where did you find this out? I am having trouble finding documentation on orbeon xforms. – devo Sep 27 '11 at 17:06
  • Yeah.. i usually google a lot as i cannot find all documentation in a sigle place. You can find the above used elements here. http://wiki.orbeon.com/forms/doc/developer-guide/xforms-events – Jayy Sep 29 '11 at 10:19