collect icon indicating copy to clipboard operation
collect copied to clipboard

Field list does not update correctly

Open seadowg opened this issue 2 years ago • 0 comments

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 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

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.

seadowg avatar May 31 '22 13:05 seadowg