Skip to content

Revise structure for easier skimming #1939

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

Merged
merged 5 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/entities-intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Introduction to Entities

If you've heard something about ODK Entities and want to better understand whether they're useful for your longitudinal data collection, you're in the right place! We've organized this page as a series of questions that are independent from each other so you can focus on the topics that interest you.

For a quick reference, check out the :doc:`quick reference </entities-quick-reference/>`. If you're someone who learns best by doing, you may prefer to jump straight into the tutorial on :doc:`building a community reporting tool with Entities <tutorial-community-reporting>` and to come back here if you have any questions. If you have a question that we haven't answered, you can `post on the forum <https://forum.getodk.org/c/support/6>`_.
For a quick summary of how to use Entities, check out the :doc:`quick reference </entities-quick-reference/>`. If you're someone who learns best by doing, you may prefer to jump straight into the tutorial on :doc:`building a community reporting tool with Entities <tutorial-community-reporting>` and to come back here if you have any questions. If you have a question that we haven't answered, you can `post on the forum <https://forum.getodk.org/c/support/6>`_.

**Topics**

Expand Down
119 changes: 63 additions & 56 deletions docs/entities-quick-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This page provides a quick reference for how to design forms in :doc:`XLSForm </
Creating and Updating Entity Data
---------------------------------

When you are designing your form, you can specify how Entities should be created from submissions.
When you are designing your form, you can specify how Entities should be created or updated from submissions.

To make a form that creates or updates Entities, there are two places to make changes in your form: the ``survey`` sheet and the ``entities`` sheet.

Expand All @@ -26,91 +26,96 @@ ____________
* For each field you want to save to an Entity, fill out the corresponding Entity *property name* in this column.

* The property name can be different from the field name.
* Not every field needs to be saved to a property. Only fill out the fields you need for your Entity workflow.
* Not every field needs to be saved to a property. Only make Entity properties for the fields you need in your Entity workflow.


.. note::
Entity property names follow the same naming rules as form field names. Additionally, the property names ``name``, ``label``, and anything beginning with ``__`` (two underscores) are not allowed.

.. rubric:: XLSForm
.. rubric:: XLSForm: ``survey`` sheet with ``save_to`` column filled in with property names for certain fields

.. csv-table:: Example ``survey`` sheet with ``save_to`` column filled in with property names for certain fields
.. csv-table:: survey
:header: type, name, label, ..., save_to

geopoint, location, Tree Location, ..., location
geopoint, location, Tree Location, ..., geometry
text, species, Tree Species, ..., species
text, intake_notes, Intake Notes, ...,

Entities Sheet
______________

The ``entities`` sheet is included in the `XLSForm template <https://docs.google.com/spreadsheets/d/1v9Bumt3R0vCOGEKQI6ExUf2-8T72-XXp_CbKKTACuko>`_, but you can add it yourself if your form does not have one. The required column headers include ``list_name`` and ``label`` but there are several optional column headers depending on your desired functionality.
The ``entities`` sheet is included in the `XLSForm template <https://docs.google.com/spreadsheets/d/1v9Bumt3R0vCOGEKQI6ExUf2-8T72-XXp_CbKKTACuko>`_, but you can add it yourself if your form does not have one. The required column headers are ``list_name`` and ``label`` and there are several optional column headers depending on your desired functionality.

* Under ``list_name``, write the name of the Entity List to create or update Entities in

* Under ``list_name``, write the name of your Entity List.

* Under ``label``, write how to build a label for each Entity.
* Under ``label``, write how to build a label for each Entity

* We recommend using :doc:`concat </form-logic/>` with fields from your form.
* The label can be blank if the form updates the Entity but does not change the label.
* You can use the label to show status information about the Entity, including using emoji like ✅ or ⚪️.
* The system does not enforce uniqueness of label values but you'll generally want to use values that you guarantee are unique through constraints or other mechanisms.

.. note::
Currently, the ``entities`` show can only have one row because each submission can only create or update a single Entity.

.. rubric:: XLSForm
Create
~~~~~~

.. csv-table:: Minimal ``entities`` sheet for creating an Entity
.. csv-table:: entities
:header: list_name, label

trees, "concat(""Tree: "", ${species})"

* **Optional**

* Column header ``create_if`` with a boolean expression.
* Column header ``update_if`` with a boolean expression.
* Column header ``entity_id`` with the ID of an existing Entity to update.

* Use ``coalesce(${existing_item},uuid())`` if designing a form that both creates and updates Entities.
Update
~~~~~~

.. csv-table:: entities
:header: list_name, label, entity_id

.. rubric:: XLSForm
trees, "concat(""Tree: "", ${species})", ${tree}

.. csv-table:: Example ``entities`` sheet for conditionally creating an Entity
:header: list_name, label, create_if

trees, "concat(""Tree: "", ${species})", ${tree_cm} > 20
.. note::

When updating an Entity, the value in the ``entity_id`` column is required and must be the Entity's system ID. This generally means that you need to attach an Entity List in order to update its Entities. See the :ref:`using Entity data <quick-reference-using-entity-data>` section.

.. rubric:: XLSForm
The label can be blank if the form updates the Entity but does not change the label.

.. csv-table:: Example ``entities`` sheet for conditionally updating an Entity
:header: list_name, label, update_if, entity_id
Create or update
~~~~~~~~~~~~~~~~

orders, "Approved: ${existing_order}", ${status} = 'approved', ${existing_order}
.. csv-table:: entities
:header: list_name, label, create_if, update_if, entity_id

trees, "concat(""Tree: "", ${species})", ${tree} = '', ${tree} != '', "coalesce(${tree}, uuid())"

.. rubric:: XLSForm
Conditionally create
~~~~~~~~~~~~~~~~~~~~

.. csv-table:: Example ``entities`` sheet for creating and updating Entities in the same form
:header: list_name, label, create_if, update_if, entity_id
.. csv-table:: entities
:header: list_name, label, create_if

trees, "concat(""Tree: "", ${species})", ${create_or_update} = 'create', ${create_or_update} = 'update', coalesce(${existing_item},uuid())
trees, "concat(""Tree: "", ${species})", ${tree_cm} > 20

Conditionally update
~~~~~~~~~~~~~~~~~~~~

.. note::
Current limitation: Only one Entity List can be updated per form and each submission can only create or update a single Entity.
.. csv-table:: entities
:header: list_name, label, entity_id, update_if

orders, "Approved: ${existing_order}", ${existing_order}, ${status} = 'approved'

Saving the Entity ID in a Registration Form
___________________________________________

Depending on your workflow, it may be helpful to save the Entity ID (UUID) in the submission data where the Entity is created.

.. rubric:: XLSForm
.. rubric:: XLSForm: Example of saving the ID of a new Entity in the submission.

.. csv-table:: Example of saving the ID of a new Entity in the submission.
.. csv-table:: survey
:header: type, name, calculation

calculate, new_entity_id, ``/data/meta/entity/@id``

.. _quick-reference-using-entity-data:

Using Entity Data
-----------------
Expand All @@ -121,20 +126,19 @@ Entity Lists are used just like CSV attachments. You can use multiple Entity Lis

* The **.csv** extension after **listname** is necessary.

#. Use ``csv-external`` with ``listname``
#. Use type :ref:`csv-external <form-datasets-attaching-csv>` with name ``listname`` (no extension)

.. note::
When you upload your form to Central, it will check the expected attachments and automatically connect an Entity List in place of an attachment when the name matches exactly. You can check what Entity Lists your forms are using by looking at those forms' attachments on Central.


Selecting an Entity
______________________________

When you use ``select_one_from_file listname.csv``, this form field will hold the ID of your selected Entity. This ID is the UUID that Central uses to uniquely track the Entity, e.g. ``4d6a1fe1-6dff-4f72-b122-1413fe9b2dd0``. You might notice UUIDs like this in your submission data.
When you use ``select_one_from_file listname.csv``, this form field will hold the system ID of your selected Entity. This ID looks like ``4d6a1fe1-6dff-4f72-b122-1413fe9b2dd0`` and is used to uniquely identify your Entity.

.. rubric:: XLSForm
.. rubric:: XLSForm: selecting an Entity with ``select_one_from_file``

.. csv-table:: Example ``survey`` sheet for selecting an Entity with ``select_one_from_file``.
.. csv-table:: survey
:header: type, name, label

select_one_from_file households.csv, hh_id, Select household
Expand All @@ -143,26 +147,29 @@ When you use ``select_one_from_file listname.csv``, this form field will hold th
Looking up an Entity from an External CSV
__________________________________________

Another way to choose an Entity from a list is by another key. Note that the ``calculate`` to get the ``name`` (also referred to as Entity ID or UUID) is only required if you need to update the Entity.
You can also identify a specific Entity using other data entered by the user, for example, a barcode number.

.. rubric:: XLSForm
.. rubric:: XLSForm: selecting a household by a barcode ID

.. csv-table:: Example of selecting a household by a barcode ID.
.. csv-table:: survey
:header: type, name, label, calculation

csv-external, households, ,
barcode, barcode, Scan household barcode,
calculate, hh_id, , instance("households")/root/item[id=${barcode}]/name
calculate, hh_id, , instance("households")/root/item[hh_id=${barcode}]/name

.. note::
Every Entity has a ``name`` property which represents its system ID. The ``calculate`` in the example above shows how to access that system ID from another unique value like a barcode number. The system ID is necessary to update the Entity.


Updating a Selected Entity
__________________________

The ID from a ``select_one_from_file`` or the ``name`` property described in the section above is the ID (represented as a UUID) that Central needs when updating the Entity.
The ID from a ``select_one_from_file`` or the ``name`` property described in the section above is the ID needed to update the Entity.

.. rubric:: XLSForm
.. rubric:: XLSForm: updating a selected Entity

.. csv-table:: Example ``entities`` sheet for updating a selected Entity.
.. csv-table:: entities
:header: list_name, label, entity_id

household, ,${hh_id}
Expand All @@ -180,9 +187,9 @@ _____________________

Once an Entity has been selected, you can use that Entity ID to access the properties of that Entity. You can also access the ``__version`` system property of an Entity to know how many updates have been made.

.. rubric:: XLSForm
.. rubric:: XLSForm: using the ``instance`` function to look up a property of a selected Entity

.. csv-table:: Example of using the ``instance`` function to look up a property of a selected Entity.
.. csv-table:: survey
:header: type, name, label, calculation

calculate, num_members, ,instance("households")/root/item[name=${hh_id}]/num_members
Expand All @@ -195,9 +202,9 @@ _______________________________
Note that if you are using ``select_one_from_file`` and want to use the existing value as a default, you will need to use a ``trigger`` to update the value when the Entity is selected.
This follows the pattern of using `dynamic defaults from form data </form-logic/#dynamic-defaults-from-form-data>`_.

.. rubric:: XLSForm
.. rubric:: XLSForm: using dynamic defaults from form data to pre-fill a field with an Entity property

.. csv-table:: Example of using dynamic defaults from form data to pre-fill a field with an Entity property.
.. csv-table:: survey
:header: type, name, label, save_to, trigger, calculation

integer, num_members, Enter number of household members, num_members, ${hh_id}, instance("households")/root/item[name=${hh_id}]/num_members
Expand All @@ -207,11 +214,11 @@ This follows the pattern of using `dynamic defaults from form data </form-logic/
Using a Different Key
_____________________

If your Entities have a different important key, you can use the ``parameters`` column to specify a different Entity property as the key. This is useful when you are *not* updating the Entity in the form, and just using the Entity list to manage shared data.
If your Entities have a different important property used to uniquely identify them, you can save that property's value when an Entity is selected. Use the ``parameters`` column to specify a different Entity property as the value that will be saved. This is useful when you are *not* updating the Entity in the form, and just using the Entity list to manage shared data.

.. rubric:: XLSForm
.. rubric:: XLSForm: saving a different property when selecting an Entity

.. csv-table:: Example of using a different column from your Entity List to serve as the ID or key.
.. csv-table:: survey
:header: type, name, label, ..., parameters

select_one_from_file states.csv, state, Select state, ..., value=state_id
Expand All @@ -226,7 +233,7 @@ Structure of an Entity
Entity ID
_________

Every Entity has an ID (a UUID) that is unique across all Entity Lists and projects within Central.
Every Entity has an ID (a UUID) that is unique across all Entity Lists and projects within Central. We often refer to this as an Entity's system ID because it's assigned by the system and can't be changed.

In a form, this Entity ID is accessed through the ``name`` property. This is to fit in with existing CSV attachments and choice lists in which the ``name`` column represents a unique identifier for that row.

Expand Down
Binary file modified docs/img/form-styling/fonts-good-and-bad-tips.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.