Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify that documentation uses XLSForm notation which is not valid in Build #1024

Open
lognaturel opened this issue Apr 29, 2019 · 3 comments

Comments

@lognaturel
Copy link
Member

getodk/build#212

It would be good to have a standard warning for this with a page that describes how to go from one notation to the other.

@florianm
Copy link
Contributor

florianm commented Dec 5, 2020

I too got burned by the syntax difference.
The tips in the Build sidebar are a good start, but a friendly section in the docs would certainly not hurt.
Would you accept a small PR to the docs?

@lognaturel
Copy link
Member Author

That would be hugely appreciated!

@florianm
Copy link
Contributor

florianm commented Dec 8, 2020

Something like:

Consider a form is created in ODK Build with

  • a metadata field of kind "Username" and Data Name "username",
  • a subsequent field can reference the username field as follows:
    • Label: Hello ${/data/username}!
    • Hint: If you're not ${/data/username}, discard this form and update the ODK Collect Username through the settings, then start over.
    • Calculate: /data/username
  • a third field (text), and
  • a fourth field referencing the third field in its label, hint, and calculated value.

The resulting XForms XML will look like this:

<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa">
  <h:head>
    <h:title>Test form</h:title>
    <model>
      <instance>
        <data id="build_Test-form_1607416879">
          <meta>
            <instanceID/>
          </meta>
          <username/>
          <group1>
            <username_repeat/>
            <some_text/>
            <some_text_repeat/>
          </group1>
        </data>
      </instance>
      <itext>
        <translation lang="English">
          <text id="/data/group1:label">
            <value>Group 1</value>
          </text>
          <text id="/data/group1/username_repeat:label">
            <value>Hello <output value="/data/username"/>!</value>
          </text>
          <text id="/data/group1/username_repeat:hint">
            <value>If you're not <output value="/data/username"/>, set Username.</value>
          </text>
          <text id="/data/group1/some_text:label">
            <value>Some text</value>
          </text>
          <text id="/data/group1/some_test_repeat:label">
            <value>The second field is <output value="/data/group1/some_text"/></value>
          </text>
          <text id="/data/group1/some_test_repeat:hint">
            <value>Hint: The second field is <output value="/data/group1/some_text"/></value>
          </text>
        </translation>
      </itext>
      <bind nodeset="/data/meta/instanceID" type="string" readonly="true()" calculate="concat('uuid:', uuid())"/>
      <bind nodeset="/data/username" type="string" jr:preload="property" jr:preloadParams="username"/>
      <bind nodeset="/data/group1/username_repeat" type="string" readonly="true()" calculate="/data/username"/>
      <bind nodeset="/data/group1/some_text" type="string"/>
      <bind nodeset="/data/group1/some_text_repeat" type="string" calculate="/data/group1/some_text"/>
    </model>
  </h:head>
  <h:body>
    <group ref="/data/group1" appearance="field-list">
      <label ref="jr:itext('/data/group1:label')"/>
      <input ref="/data/group1/username_repeat">
        <label ref="jr:itext('/data/group1/username_repeat:label')"/>
        <hint ref="jr:itext('/data/group1/username_repeat:hint')"/>
      </input>
      <input ref="/data/group1/some_text">
        <label ref="jr:itext('/data/group1/some_text:label')"/>
      </input>
      <input ref="/data/group1/some_text_repeat">
        <label ref="jr:itext('/data/group1/some_text_repeat:label')"/>
        <hint ref="jr:itext('/data/group1/some_text_repeat:hint')"/>
      </input>
    </group>
  </h:body>
</h:html>

Note:

  • The surrounding ${} will tell ODK Collect to evaluate the XPath within the curly brackets to become Hello <output value="/data/username"/>!
  • The contents of the ${} must be a valid XPath. A direct reference of the Data Name like ${username} (as allowed in XLSForms) will cause an error.
  • The calculate field already expects an XPath expression, which will become calculate="/data/username".
  • Review also the XML above how some_text_repeat references some_text by its XPath. Note that both live inside a Group named group1, which becomes part of the XPath.
  • Note that when entering text into some_text, the label, hint, and calculated value of some_text_repeat updates as you type. This shows that references update even on the same screen.
  • In contrast, metadata like the Username are calculated once. Any changes (updated Username) are only shown in forms filled in after the change.

The above test form is attached for reference.
Test form.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants