devo
devo

Reputation: 1332

How to do something with selected values of an xforms:select every time they change?

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.

Upvotes: 2

Views: 4023

Answers (2)

Jayy
Jayy

Reputation: 2436

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>   

Upvotes: 0

avernet
avernet

Reputation: 31743

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.

Upvotes: 3

Related Questions