I'm using XSLTForms in eXist 2.2 with the RESTXQ server.
I have a search form that lets users query a remote API, which responds with a set of XML records if the query is matched. I am using xf:repeat
to iterate over the records, and I want to be able to provide a checkbox at the head of each record, so that the user can choose the records they want. However, when I place a checkbox element inside xf:repeat
(using xf:input
bound to a boolean value), I don't get the desired functionality. Instead of being independent of each other, the checkboxes get activated as a group. When I click the first box, the second box is activated as well, etc. This seems as though it would be a common enough use case, but I can't seem to find any documentation or examples showing how to implement it.
I know I need to sync the two instances somehow, to ensure that there is a new bool
element for each checkbox, and I have tried different approaches with xf:insert
, but I can't get anything to work.
Model snippet:
<xf:instance xmlns="" id="default">
<results>
<sru:record sru:test="false">
<sru:recordData>
<marc:record>
...
</marc:record>
</sru:recordData>
</sru:record>
<sru:record sru:test="false">
<sru:recordData>
<marc:record>
...
</marc:record>
</sru:recordData>
</sru:record>
</results>
</xf:instance>
<xf:bind nodeset="instance('default')/sru:record/@sru:test" id="checkVal" type="xs:boolean"/>
Form snippet with xf:repeat
:
<div>
<xf:repeat
nodeset="instance('default')/sru:record/sru:recordData/marc:record"
id="marc-repeat" appearance="full">
<div class="checkbox">
<xf:input incremental="true" ref="../../@sru:test">
<xf:label>Select</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue
bind="checkVal"
if=". = boolean-from-string('false')">true</xf:setvalue>
<xf:setvalue
bind="checkVal"
if=". = boolean-from-string('true')">false</xf:setvalue>
</xf:action>
</xf:input>
</div>
...
</xf:repeat>
</div>
I finally figured out that I just needed a nested xf:repeat
to iterate through the set of records. I think my problem stemmed from a confusion about the functionality of the xf:bind
element, which I ended up removing. With this revised form structure, the value of each @sru:test
attributes now updates independently.
Form snippet with xf:repeat
:
<div>
<xf:repeat
nodeset="instance('default')/sru:record/sru:recordData"
id="marc-repeat" appearance="full">
<div class="checkbox">
<xf:repeat nodeset="marc:record">
<xf:input incremental="true" ref="../../@sru:test">
<xf:label>Select</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue
bind="checkVal"
if=". = boolean-from-string('false')">true</xf:setvalue>
<xf:setvalue
bind="checkVal"
if=". = boolean-from-string('true')">false</xf:setvalue>
</xf:action>
</xf:input>
</div>
...
</xf:repeat>
</div>