Skip to content

Filter combo field options by optionsLocationSet - #12657

Open
julcnx wants to merge 1 commit into
openstreetmap:developfrom
julcnx:combo-options-locationset
Open

Filter combo field options by optionsLocationSet#12657
julcnx wants to merge 1 commit into
openstreetmap:developfrom
julcnx:combo-options-locationset

Conversation

@julcnx

@julcnx julcnx commented Jul 31, 2026

Copy link
Copy Markdown

This came out of a discussion on openstreetmap/id-tagging-schema#2332, where a maintainer asked whether a single surface combo option (laterite, a tropical soil type essentially absent outside a specific belt of countries) could be scoped to only the regions where it's actually relevant, instead of appearing in the dropdown everywhere. Field-level locationSet already exists for hiding a whole field by region (modules/ui/field.js), but there's nothing equivalent for a single option inside a shared combo field like surface, which is used across most highway presets globally.

id-tagging-schema's schema gained an optionsLocationSet property to carry this (companion PR: openstreetmap/schema-builder#349), a map from option value to a locationSet object. This PR wires that data up on the iD side.

What changed

  • modules/presets/index.js: when merging a field with an optionsLocationSet, each option's locationSet gets pushed through locationManager.registerLocationSets() (the same call already used for whole-field/preset/category locationSets), and the resulting locationSetIDs land on field.optionsLocationSetID, keyed by option value.
  • modules/ui/fields/combo.js: adds optionAllowedHere(value), which checks the current entity's location against the option's locationSetID the same way modules/ui/field.js's isAllowed() already does for whole fields (same combinedEntityExtent() / locationManager.locationSetsAt() pattern). Applied in both suggestion paths:
    • the static options list (getOptions())
    • the live taginfo-backed suggestions, since taginfo has no concept of this restriction and would otherwise surface a globally-popular value (laterite currently has 700+ uses) regardless of where you're editing

An option with no entry in optionsLocationSetID, or when the entity's location can't be determined (e.g. no entity yet), is offered everywhere, unchanged from today. Typing a value directly is still always possible (customValues), this only affects what gets suggested, matching how whole-field locationSet filtering already behaves (it hides the field, but doesn't retroactively invalidate already-tagged data).

Testing

  • modules/presets/index.js: unit test confirming optionsLocationSetID resolves correctly on merge, and that fields without optionsLocationSet are unaffected.
  • modules/ui/fields/combo.js: two end-to-end tests exercising the real DOM/combobox path (render the field, focus, simulate a keypress to open the dropdown, read the actual rendered .combobox-option elements), confirming a region-restricted option is excluded when locationSetsAt() doesn't include its id, and included when it does.
  • Full suite passes locally (npm run lint, tsc, vitest run, 2367 passed).

This is the iD half of a three-repo change; a follow-up id-tagging-schema PR will apply optionsLocationSet to laterite once this and the schema-builder PR both land. Happy to adjust the approach if you'd prefer something different.

id-tagging-schema's field.json schema gained an optionsLocationSet
property (openstreetmap/schema-builder#349): a per-option locationSet,
letting a single combo option (e.g. surface=laterite, a tropical soil
type essentially absent outside a specific belt of countries) be
offered only in the regions where it's relevant, without touching the
rest of the shared field's option list.

This wires that data up on the iD side, reusing the exact mechanism
already used to hide a whole field by region:

- modules/presets/index.js: when merging a field with an
  optionsLocationSet, resolves each option's locationSet through
  locationManager.registerLocationSets() (same call already used for
  whole-field/preset/category locationSets) and stores the results in
  field.optionsLocationSetID, keyed by option value.

- modules/ui/fields/combo.js: adds optionAllowedHere(value), checking
  the current entity's location against the option's locationSetID
  the same way modules/ui/field.js already does for whole fields.
  Applied in both suggestion paths: the static options list
  (getOptions()) and the live taginfo-backed suggestions, since
  taginfo doesn't know about this restriction and would otherwise
  surface a globally-popular value regardless of region.

An option with no entry in optionsLocationSetID, or when the entity's
location can't be determined, is offered everywhere, unchanged from
today's behavior. Typing a value directly is still always possible
(customValues), this only affects what's suggested.
@tordans

tordans commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

We are still discussing what the new format should look like. Latest discussion on this topic is here openstreetmap/id-tagging-schema#2493 (comment)

I don't think the idea at https://github.com/openstreetmap/schema-builder/pull/349/changes#diff-52dd1cfe1fba598e780b1576304786ad0f86bbbbcb7b0c505e75ba12563075c9R120 is better.

@julcnx

julcnx commented Jul 31, 2026

Copy link
Copy Markdown
Author

Thanks for the pointer, hadn't seen #2493. Fair concern, optionsLocationSet as a standalone property is exactly the kind of one-off metadata addition that thread is trying to avoid piling up.

This PR's combo.js/presets/index.js plumbing only depends on field.optionsLocationSetID at runtime, it doesn't care what the upstream schema property is called or how it's nested. So it should adapt to whatever comes out of #2493 (e.g. living under a richer options: [{value, locationSet}] shape) with a small follow-up rather than a rewrite.

Happy to wait for #2493 to settle before pushing on the schema side, or to help prototype the richer-field-metadata format there if that's useful. Let me know which is more helpful.

@k-yle k-yle left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i agree, we should go with tobias' more flexible proposal from openstreetmap/id-tagging-schema#2493 (comment) - that would solve 3 different issues at once

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