`convert-contact-form` can break contact form with nested groups in `init` group
Opened this issue · 0 comments
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
calculation
s 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
.