Skip to content

feat(medic/cht-core#10676): store geolocation when submitting contact forms - #2221

Merged
dianabarsan merged 9 commits into
medic:mainfrom
cliftonmcintosh:feature/10676-contact-form-geolocation-stored
Aug 28, 2026
Merged

dianabarsan merged 9 commits into
medic:mainfrom
cliftonmcintosh:feature/10676-contact-form-geolocation-stored

Conversation

@cliftonmcintosh

@cliftonmcintosh cliftonmcintosh commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Documents the geolocation widget for household contact forms, introduced in medic/cht-core#10676.

New page — building/forms/configuring/contact-geolocation.md

Full reference for configuring GPS location capture in household contact forms. Covers:

  • XForm XML changes: model instance field, bind, body group, and translations
  • XLSForm equivalent (survey sheet row)
  • Widget behavior:
    • GPS acquisition starts automatically on render (no capture button);
    • on success, a context question ("I'm at the household" / "I'm somewhere else") appears;
    • on failure, a retry button and a self-acting Save without location checkbox appear;
    • permission-denied handling;
    • a GPS-unavailable state
  • Edit mode: a 4-option radio group (Keep / Change household location / I am not at the household / Remove household location), gated on a silent background GPS read
  • What gets stored on the contact document (geolocation, geolocation_log)
  • Scoped explicitly to household contacts: the widget's UI copy (badge, radio labels) is hardcoded around "household" wording and isn't intended for other contact types

Updated — building/forms/contact.md

New "Capturing GPS Location" section with a link to the configuring page, following the same pattern as the existing "Uploading Binary Attachments" section.

Updated — building/contact-management/contacts.md

New "GPS location capture" subsection under "Creating and Editing Contacts" alongside the existing Duplicate Contact Detection entry.

AI Disclosure

Claude Code was used to draft and revise all documentation in this PR, across multiple sessions (models claude-sonnet-4-6 and claude-sonnet-5). The original draft was based on a technical draft prepared by a separate Claude Code session that worked directly in the cht-core codebase; the revision was verified directly against the feature/10676-contact-form-geolocation-stored branch source (widget, services, and translation files). I reviewed the output for accuracy, style guide compliance, and correct placement within the docs site structure.

License

The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.

cliftonmcintosh and others added 3 commits August 4, 2026 13:34
…orms

Add reference page for the new geolocation widget that captures GPS
coordinates when a contact is created or edited. Documents XForm XML
and XLSForm configuration, widget behavior states, stored fields
(geolocation, geolocation_log), and context question customization.
Cross-reference from the contact forms reference page and the
contacts feature overview.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…implementation

Correct factual errors introduced before implementation was finalized:
remove geo_context XForm field, fix geolocation_log shape (is_home
boolean), fix skip value ("skipped"), scope geolocation field to home
captures only. Add edit mode and weak-signal failure path. Replace UI
string quotes and button labels with functional descriptions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…igned flow

The widget was redesigned since the last docs pass: GPS now starts
automatically on render instead of behind a capture button, the
context question moves to after a successful capture, "skip" is a
single self-acting checkbox rather than a button gated by one, and
edit mode is a 4-option radio group (adding "Remove") instead of 2.
Also corrects the "what gets stored" table (The capture field is
stripped before saving and never persists) and scopes the feature
to household contacts throughout, since the widget's UI copy is
hardcoded around "household" wording.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cliftonmcintosh
cliftonmcintosh force-pushed the feature/10676-contact-form-geolocation-stored branch from 8830444 to b01f044 Compare August 4, 2026 19:05
@cliftonmcintosh
cliftonmcintosh marked this pull request as ready for review August 5, 2026 20:55
@cliftonmcintosh

Copy link
Copy Markdown
Contributor Author

@dianabarsan

This is the documentation for medic/cht-core#11136. Would you be able to review this? If not, would you offer a recommendation for a reviewer?

@dianabarsan
dianabarsan self-requested a review August 7, 2026 06:15

@dianabarsan dianabarsan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, and very thorough, but I fear there it's slightly too technical, and the instructions don't cover the supported way of generating forms, via xlsx and cht-conf.

I added some small requests inline.

_Added in CHT `TBD`._

> [!CAUTION]
> This widget is designed for household contact forms only. Adding it to a report form is unsupported and may produce unexpected behavior. It's also written specifically for households: the badge and option labels use household-specific wording ("Household location already saved", "Change household location", and so on). Adding it to a form for another contact type shows that same wording, which won't make sense outside a household context.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please strengthen this phrase, such that it is understood that only language is the limitation, since all of the translations can me modified?
I fear that we are overly limiting this, when the feature itself can be used successfully for any contact.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.


## XForm configuration

Three changes are required in the household contact form XML: a model field, a bind, and a body element.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People do not manually create forms XML. They create xlsx that are later transformed with cht-conf to XML. These instructions should cover the XLSX changes, not the XML footprint.

## XLSForm equivalent

> [!WARNING]
> This section has not been tested against a real cht-conf XLSForm conversion. Verify the output before using it in a deployment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test this, as this is the supported way of generating xforms.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Claude Code, I tested the XLSForm example in this PR. It wrote a small Python script to build a test .xlsx file reproducing the docs' survey row inside a contact form structure, then ran it through two tools:

  1. cht-conf's actual XLSForm-to-XForm converter (the same one convert-contact-forms uses in production). It converted cleanly, and the resulting XForm XML matched the hand-written XForm example elsewhere on this page field-for-field.
  2. ODK Validate, the official XForm validator. it passed with zero warnings.

With Claude Code, I also ran a control test with a deliberately invalid field type to confirm the converter actually validates input rather than accepting anything, so the passing results above are meaningful.


- The progress bar is replaced by a success message
- The widget shows a context question with two options: "I'm at the household" and "I'm somewhere else"
- Selecting either option sets `geo_capture` to `"captured"`, records the choice, and lets the CHW proceed to the next page

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a photo capture of every state you describe here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

- If the failure is due to a weak or unreliable signal, a message prompts the CHW to move to an area with better reception
- A retry button and a checkbox labeled **Save without location** appear
- Tapping the retry button clears the failure state and starts a new capture attempt
- Checking **Save without location** immediately sets `geo_capture` to `"skipped"` and cancels the in-progress capture; unchecking it clears the field, and the CHW can then tap Retry to try again

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much technical implementation detail here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to be less technical.


- The progress bar is replaced by a success message
- The widget shows a context question with two options: "I'm at the household" and "I'm somewhere else"
- Selecting either option sets `geo_capture` to `"captured"`, records the choice, and lets the CHW proceed to the next page

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much implementation detail here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to be less technical.


Household contact forms can capture the device's GPS location at the time a household is created or edited. The geolocation widget handles the full capture experience automatically: it starts acquiring a position the instant the form renders, then shows progress, success, and failure states. It stores the result on the contact document.

After a successful capture, the widget asks whether the CHW is at the household or somewhere else, and records the answer alongside the coordinates. This context question is part of the widget and requires no additional XForm fields.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move the section "what gets stored" here? So people don;t need to scroll through so much text to figure out what data they would expect to see.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved.

cliftonmcintosh and others added 4 commits August 7, 2026 10:19
The widget has no code-level contact-type restriction. "household"
wording only comes from the default translation strings, which are
overridable. Reword the caution to separate the hard restriction
(report forms are unsupported) from the soft one (default copy is
household-specific but not a technical ceiling), and revert the
title, description, and cross-references in contact.md/contacts.md
from "household contact forms" back to generic "contact forms."

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per review, readers shouldn't have to scroll past the full
configuration and behavior walkthrough to find out what data the
widget actually writes. Moves the section to right after the intro
and caution, ahead of Configuration/Widget behavior/Edit mode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace prose-only descriptions of each widget state
with screenshots. Adds 7 images covering GPS acquiring, success,
failure, permission denied, GPS unavailable, and both edit-mode
states (capture options disabled/enabled), and wires each into
contact-geolocation.md via the figure shortcode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mrjones-plip

Copy link
Copy Markdown
Contributor

Dropping a quick note here to day Diana is on holiday for a few weeks and likely wont get back to this PR until her return.

@cliftonmcintosh

Copy link
Copy Markdown
Contributor Author

Dropping a quick note here to day Diana is on holiday for a few weeks and likely wont get back to this PR until her return.

Thanks, @mrjones-plip. I hope she enjoys her holiday!

@dianabarsan dianabarsan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice and thorough, thanks for all the changes.
I added two small requests inline.

> [!CAUTION]
> This widget is designed for contact forms only. Adding it to a report form is unsupported and may produce unexpected behavior.
>
> The widget's default copy is written for households ("Household location already saved", "Change household location"... ). Nothing in the widget restricts it to household contacts specifically. It activates on any form field with `appearance="geolocation-capture"`, regardless of contact type. To use it on another contact type, override the `geolocation.edit.*`, `geolocation.at.household`, and `geolocation.somewhere.else` translation keys with wording appropriate to that contact type. Otherwise the household-specific default text shows through.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this note.

appearance="geolocation-capture" makes direct reference to how the XML would look like, while in the XLS it will be a column. Can you please change the wording such that we are referring to XLS columns instead of XML attributes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@@ -0,0 +1,189 @@
---
title: "Capture GPS Location in Contact Forms"
linkTitle: "GPS Location Capture"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please call this "Contact GPS location capture" so it is not confused with a generic GPS capture.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Rename the linkTitle to "Contact GPS Location Capture" so it isn't
confused with a generic GPS capture feature. Reword the caution box
to describe the geolocation-capture appearance as an XLS column
value instead of XML attribute syntax, matching the XLSForm-first
configuration path.

@dianabarsan dianabarsan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely!

@dianabarsan
dianabarsan merged commit 7456e73 into medic:main Aug 28, 2026
1 check passed

### GPS location capture

_Added in CHT `TBD`._

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dianabarsan

Should I update the "TBD"s to 5.3 in a new pull request?

@mrjones-plip

Copy link
Copy Markdown
Contributor

already fixed - thanks @cliftonmcintosh !

@cliftonmcintosh

Copy link
Copy Markdown
Contributor Author

Great! Thanks!


After a successful capture, the widget asks whether the CHW is at the household or somewhere else, and records the answer alongside the coordinates.

_Added in CHT `TBD`._

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's here, too, @mrjones-plip. I'll race you


## Capturing GPS Location

_Added in CHT `TBD`._

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here, @mrjones-plip

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants