# "XLSForm that looks up default values based on a selection" in a Repeat w/ Field-Lists

**URL:** <https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980>\
**Category:** Support\
**Tags:** odk-collect, odk-xlsform\
**Created:** [October 24, 2025, 5:13pm UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980 "2025-10-24T17:13:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jhogan](https://getodk.b-cdn.net/letter_avatar_proxy/v4/letter/j/65b543/32.png) [@jhogan](https://forum.getodk.org/u/jhogan)\
**Post date:** [October 24, 2025, 5:13pm UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980/1 "2025-10-24T17:13:07Z")

</div>

**1. What is the issue?**

Using the example of “XLSForm that looks up default values based on a selection” described [Form Logic - ODK Docs](https://docs.getodk.org/form-logic/#dynamic-defaults-from-form-data), I added a second question (age) and I have no problem with the trigger/calculation populating the default when I wrap the questions in a field\_list to get them on one page. However, if I place a repeat around it, then it appears that the trigger does not occur and the calculation does not populate the default. But if I remove the field\_list while retaining the repeat, the trigger does seem to occur and the calculation populates the default.

I’m really confused because it works with field\_list without a repeat and works with a repeat without a field\_list.

**2. What steps can we take to reproduce this issue?**

Does not work:

[selectlookuptest.xlsx](https://forum.getodk.org/uploads/short-url/anDBdZyOHpn8yOuIOhtVu3GSCKS.xlsx) (14.4 KB)

**3. What have you tried to fix the issue?**

Removing the field\_list fixes this, but the desired behavior is to have both on same screen.

[selectlookuptest-nofieldlist.xlsx](https://forum.getodk.org/uploads/short-url/jp5bDIDXbhV6Rfg200eOH1fUVvx.xlsx) (14.4 KB)

---

<div class="post-metadata">

**Author:** ![jhogan](https://getodk.b-cdn.net/letter_avatar_proxy/v4/letter/j/65b543/32.png) [@jhogan](https://forum.getodk.org/u/jhogan)\
**Post date:** [October 25, 2025, 3:32am UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980/4 "2025-10-25T03:32:00Z")

</div>

The triggers are happening and I can get it to work in Enketo using the following for the calculation:

`instance('participants')/root/item[name=indexed-repeat(${participant}, ${repeat_group}, position(../..))]/phone_number`

However, when I try to use it on the device (Connect) it gives me an error:

```auto
Error Occurred
Index 1 out of bounds for length 0

```

[selectlookuptest-enketoworking.xlsx](https://forum.getodk.org/uploads/short-url/iGN2FuHXBesnhJlDbkPJLTpdPna.xlsx) (14.5 KB)

Could this be a bug in Connect?

edit: I added this to an existing open issue on github.. maybe it's related:

> <https://github.com/getodk/collect/issues/5152>
>
> We've found a case where field lists do not update correctly when a question is …answered. I'll format this issue in a way that allows us to add any other cases we might find down the line (before making fixes) here as well.
> 
> \### Trigger + Calculate + Relevant
> 
> \#### Form
> 
> \`\`\`xml
> \<?xml version="1.0"?\>
> \<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events"
> xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa"
> xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"\>
> \<h:head\>
> \<h:title\>Trigger relevant\</h:title\>
> \<model odk:xforms-version="1.0.0"\>
> \<instance\>
> \<data id="trigger" version="1"\>
> \<field-list\>
> \<a/\>
> \<b/\>
> \</field-list\>
> \<meta\>
> \<instanceID/\>
> \</meta\>
> \</data\>
> \</instance\>
> \<bind nodeset="/data/field-list/a" type="string"/\>
> \<bind nodeset="/data/field-list/b" relevant="selected( /data/field-list/a , 'show')" type="string"/\>
> \<bind jr:preload="uid" nodeset="/data/meta/instanceID" readonly="true()" type="string"/\>
> \</model\>
> \</h:head\>
> \<h:body\>
> \<group appearance="field-list" ref="/data/field-list"\>
> \<label\>Field List\</label\>
> \<select1 ref="/data/field-list/a"\>
> \<label\>A\</label\>
> \<item\>
> \<label\>Show B\</label\>
> \<value\>show\</value\>
> \</item\>
> \<item\>
> \<label\>Hide B\</label\>
> \<value\>hide\</value\>
> \</item\>
> \<setvalue event="xforms-value-changed" ref="/data/field-list/b" value=" /data/field-list/a "/\>
> \</select1\>
> \<select1 ref="/data/field-list/b"\>
> \<label\>B\</label\>
> \<item\>
> \<label\>Show B\</label\>
> \<value\>show\</value\>
> \</item\>
> \<item\>
> \<label\>Hide B\</label\>
> \<value\>hide\</value\>
> \</item\>
> \<setvalue event="xforms-value-changed" ref="/data/field-list/a" value=" /data/field-list/b "/\>
> \</select1\>
> \</group\>
> \</h:body\>
> \</h:html\>
> \`\`\`
> 
> \#### Test
> 
> \`\`\`kotlin
> rule.startAtMainMenu()
> .copyForm("trigger-relevant.xml")
> .startBlankForm("Trigger relevant")
> .assertQuestion("A")
> .assertTextDoesNotExist("B")
> 
> .clickOnText("Show B")
> .assertQuestion("A")
> .assertQuestion("B")
> 
> .clickOnText("Hide B", 1) // Click the second "Hide B"
> .assertQuestion("A")
> .assertTextDoesNotExist("B")
> \`\`\`
> 
> \## Notes
> 
> It would be good to take the opportunity to revise how widget values are saved as part of fixing this issue. We've chatted in the past about having widgets and \`onActivityResult\` call a modified \`FormEntryViewModel#answerQuestion\` that in turns calls \`FormController#answerQuestion\` (or similar) and then some kind of optimized reload (probably through an interface) instead of using \`QuestionWidget#setData\`, \`WaitingForDataRegistry\`, \`WidgetValueChangedListener\` etc.

---

<div class="post-metadata">

**Author:** ![Grzesiek2010](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/grzesiek2010/32/2881_2.png) [@Grzesiek2010](https://forum.getodk.org/u/Grzesiek2010)\
**Post date:** [November 9, 2025, 8:40pm UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980/5 "2025-11-09T20:40:58Z")

</div>

Hi @jhogan

Thanks a lot for reporting the issue and for providing all the details that helped with the investigation. It seems to be a bug in ODK Collect, or more precisely in Javarosa, the library that powers the mobile app.

I need a bit more time to fully understand what is happening under the hood and to estimate how long it might take to fix. In the meantime, in case this issue is blocking you, here is a workaround you can use:

Instead of this:

```xml
instance('participants')/root/item[name=indexed-repeat(${participant}, ${repeat_group}, position(../..))]/phone_number

```

use this:

```xml
instance('participants')/root/item[name=current()/../../participant]/phone_number

```

It looks like the issue only occurs when the `indexed-repeat` function is used.

---

<div class="post-metadata">

**Author:** ![Grzesiek2010](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/grzesiek2010/32/2881_2.png) [@Grzesiek2010](https://forum.getodk.org/u/Grzesiek2010)\
**Post date:** [November 20, 2025, 8:42pm UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980/6 "2025-11-20T20:42:16Z")

</div>

Hi again @jhogan,

After investigating this with the team, it turns out that the behavior you observed is **not a bug in ODK Collect or JavaRosa** , but rather the expected way that XPath relative references work inside predicates.

### Why the original expression didn’t work

When using an expression like:

```auto
indexed-repeat(${participant}, ${repeat_group}, position(../..))

```

inside a predicate that queries an external instance, the call to `position(../..)` is evaluated **relative to the external instance** , not relative to your repeat group in `/data`. This is standard XPath behavior: in predicates, relative navigation is scoped to the node-set being filtered.

As a result, the position returned is not the position of the current repeat item, which is why the lookup fails.

### Working alternatives

Both of the following expressions work because they explicitly anchor the position to the current node in the main instance:

Using the raw XPath path:

```auto
instance('participants')/root/item[name=current()/../../participant]/phone_number

```

Or keeping `indexed-repeat` but using `current()` to bind the position to the repeat context:

```auto
indexed-repeat(${participant}, ${repeat_group}, position(current()/../..))

```

Enketo behaves differently here because it implements parts of the XPath evaluation model slightly differently than JavaRosa. But in JavaRosa, the above behavior is correct and consistent.

---

<div class="post-metadata">

**Author:** ![jhogan](https://getodk.b-cdn.net/letter_avatar_proxy/v4/letter/j/65b543/32.png) [@jhogan](https://forum.getodk.org/u/jhogan)\
**Post date:** [November 20, 2025, 10:05pm UTC](https://forum.getodk.org/t/xlsform-that-looks-up-default-values-based-on-a-selection-in-a-repeat-w-field-lists/56980/7 "2025-11-20T22:05:37Z")

</div>

Ok, thank you. I'm new to ODK and XPath and your explanation clarifies a lot for me. Thanks for looking into it.

John
