-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Describe the bug
The convert-contact-forms action contains logic that manually manipulates the order of elements in the body section of the form xml. Basically, when the form contains a /data/contact group it will try to update the body section so that the /data/contact group is nested inside of the /data/init group.
So, an xml with a body like:
<h:body class="pages">
<group ref="/data/contact">
...
</group>
<group appearance="field-list" ref="/data/init">
...
</group>
</h:body>becomes:
<h:body class="pages">
<group appearance="field-list" ref="/data/init">
...
<group ref="/data/contact">
...
</group>
</group>
</h:body>Unfortunately the this logic seems to be bugged when /data/init contains a nested group. In that case, the form xml actually ends up being converted into:
<h:body class="pages">
<group appearance="field-list" ref="/data/init">
...
<group ref="/data/init/non_relevant_group">
...
<group ref="/data/contact">
...
</group>
</group>
</group>
</h:body>Notice that /data/contact is now actually instead /data/init/non_relevant_group.
This does not seem to have any negative effects except when /data/init/non_relevant_group is non-relevant and /data/contact has calculate fields that should be evaluated. When that happens the /data/contact calculations will not be evaluated since they are regarded by Enketo as non-relevant.
To Reproduce
Create a contact-create form with the following contents (does not have to result in a "valid" contact:
| type | name | label::en | relevant | appearance | calculation |
|---|---|---|---|---|---|
| begin group | contact | NO_LABEL | |||
| string | parent | NO_LABEL | |||
| calculate | first_name | ${first_name_contact} | |||
| end group | contact | ||||
| begin group | init | NO_LABEL | field-list | ||
| text | first_name_contact | Name | |||
| begin group | non_relevant_group | NO_LABEL | false() | ||
| text | non_relevant_question | Should not see this | |||
| end group | non_relevant_group | ||||
| end group | init |
Convert/upload the form with cht-conf, then open the form in the CHT. Enter a value into the "Name" field.
Then, in the browser console, run window.CHTCore.debugFormModel() to dump the current form model data.
The expected behavior is that data/contact/first_name should be populated with the same value you entered in data/init/fist_name_contact. However, this will not be the case in the dumped model data. Instead, data/contact/first_name is not populated at all (presumably because Enketo considers it to be non-relevant).
Expected behavior
I believe that if the convert-contact-forms action simply nested /data/contact inside /data/init (as a sibling of /data/init/non_relevant_group) everything would work as expected.
This convert-contact-form functionality was originally added in #25. I am not 100% sure, but this seems to have been a hack try to and work around medic/cht-core#8226. A better long-term solution might be to solve #8226 and then unjankify some of this contact form logic. At the very least we need more complete documentation regarding the required structure of contact forms....
Additional context
Originally reported on the forum.
One final note is that it this does not seem to be related to any specific Enketo version. I have reproduced the behavior on 3.17.2 and on master.