Skip to main content
Odoo Community Association

Mapbox Widget

Beta License: LGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

This module adds a form-view Mapbox map widget for JSON fields.

Declare a fields.Json field on any model and set widget="mapbox" in the form arch. The widget renders markers from a JSON payload, supports map and satellite styles, zoom, pan, pitch, and fullscreen, and can open a popup form when a marker is marked clickable.

Markers may use optional Font Awesome icons, sizes, and HEX colors. When several markers share a location, earlier items in the payload are drawn on top. The Map / Satellite control remembers the last choice in the browser and applies it to every mapbox widget on that origin.

Mapbox GL JS is loaded from the Mapbox CDN at runtime and is not vendored in this addon.

Table of contents

Configuration

  1. Create a Mapbox account and a public (pk.) token at https://account.mapbox.com/.

  2. Open Settings → General Settings and find Mapbox Token under Integrations.

  3. Paste the public token and save. Backend forms that use widget="mapbox" then receive the token through the user session.

  4. The browser must be able to reach api.mapbox.com (Mapbox GL JS, styles, and tiles).

The token stored here is a Mapbox public token. It is still a credential: restrict who can change Settings, and do not treat it as anonymous data. This module does not read or write the Enterprise web_map token (web_map.token_map_box / map_box_token).

Usage

Add a JSON field on the model that should show a map, then use the widget in the form view:

<field name="my_map" widget="mapbox"/>

The field value must be a JSON object. null, false, or a non-object value show a placeholder instead of a map. Unknown extra keys are kept when the widget writes.

The map container is full width of the field and 400px tall. A missing Mapbox token, a failed CDN load, or empty / non-object data each show a translated placeholder and do not construct a map.

Payload

{
  "elements": [],
  "style": {
    "map": "mapbox://styles/mapbox/streets-v12",
    "satellite": "mapbox://styles/mapbox/satellite-streets-v12"
  },
  "default_center": {"lat": 52.37, "lon": 4.89},
  "default_zoom": 12,
  "allow_zoom": true,
  "allow_pan": true,
  "allow_fullscreen": true,
  "default_pitch": 0,
  "allow_pitch": true,
  "updated": []
}

Key

Type

Default if omitted

elements

array of marker objects

[]

style.map

Mapbox style URL

mapbox://styles/mapbox/streets-v12

style.satellite

Mapbox style URL

mapbox://styles/mapbox/satellite-streets-v12

default_center

{lat, lon}

first valid element, else {"lat": 0, "lon": 0}

default_zoom

number

12

allow_zoom

bool

true

allow_pan

bool

true

allow_fullscreen

bool

true (Mapbox fullscreen control)

default_pitch

number

0, clamped to [0, 85]

allow_pitch

bool

true

updated

array

[]; written by the widget after a drag

The map does not fit bounds. When default_center is a valid {lat, lon} pair it is used even if markers exist. Otherwise the camera centers on the first valid element.

Classic Mapbox style URLs only — not Mapbox Standard. The initial style is style.map, unless the browser already stores a Satellite preference (see below).

Map / Satellite preference

The Map / Satellite control writes the last choice to browser storage (web_widget_mapbox.style: map or satellite) and applies it to every mapbox widget on this origin, including maps that are already open. New maps start with that choice. An invalid or missing value falls back to Map. The preference survives page reloads on the same origin.

Changing style keeps the current pitch.

Markers

Key

Type

Notes

lat / lon

number

required for a visible marker; lat in [-90, 90], lon in [-180, 180]

label

string

optional; Mapbox popup when a form is not opened

rec_model

string

model to open on click

rec_id

int

positive id of rec_model

clickable

bool

default false; with rec_model and rec_id opens a popup form

icon

string

Font Awesome 4.7 name, with or without the fa- prefix

size

int

optional size in pixels of the custom icon element; ignored when icon is omitted

color

string

optional HEX #RGB or #RRGGBB; tints the default Mapbox pin or the Font Awesome icon

editable

bool

default false; when true and the field is writable, the marker can be dragged

index

int

only on updated items; 0-based index in elements

Invalid coordinates are skipped. Every valid element is drawn as an equal marker. When several markers share a location, earlier items in elements are drawn on top (so list order controls which pin receives clicks). Invalid or omitted color leaves the default Mapbox pin color, or the icon’s inherited color.

A marker click opens a popup form (FormViewDialog) only when clickable is true and rec_model is a non-empty string and rec_id is a positive integer. If that triple is incomplete, the form is not opened (the label popup is used instead when label is set). A click that follows a drag does not open the form. If the map is in fullscreen, the click leaves fullscreen first so the form is visible, then the map is resized to the in-page container.

Drag and updated

Dragging does not rewrite elements. On drag end the widget copies that element, sets lat / lon from the marker, sets index to the source position, and upserts it into root updated. Extra element keys (including clickable, rec_model, rec_id, and color) are copied onto the updated item.

Drag is enabled only when the field is not readonly, editable is true, and the coordinates are valid.

Payload updates

When the field value changes (for example a computed JSON that recomputes):

  • Changes to elements (or other marker data) rebuild markers only. The camera is not reset.

  • Changes to camera keys (default_center, default_zoom, default_pitch), style URLs, or allow_zoom / allow_pan / allow_pitch / allow_fullscreen recreate the map so the new config applies.

  • Switching to another record always recreates the map for that record’s payload.

Computed non-stored JSON

Display works on a computed JSON field that is not stored. Odoo defaults store=False and readonly=True unless an inverse is set, so the map still renders when the field is in the view.

updated is persisted only when the field is writable (stored, or computed with an inverse / readonly=False). Do not set store=True unless the consuming module needs those writes.

Example of a computed non-stored field (typical consumer; not added by this addon):

map_data = fields.Json(compute="_compute_map_data")

def _compute_map_data(self):
    for rec in self:
        rec.map_data = {
            "elements": [...],
            "default_center": {
                "lat": rec.partner_latitude,
                "lon": rec.partner_longitude,
            },
            "default_zoom": 12,
        }

Known issues / Roadmap

  • Clustering, drawing, routing, and GeoJSON polygons are not in scope.

  • The widget does not add, delete, or geocode markers in the UI.

  • Website and portal assets are not loaded; this is a backend form widget.

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed feedback.

Do not contact contributors directly about support or help with technical issues.

Credits

Authors

  • Cetmix

Contributors

Other credits

This module loads Mapbox GL JS v3.30.0 from the Mapbox CDN at runtime (https://api.mapbox.com/mapbox-gl-js/v3.30.0/). The library is not copied into this repository.

Mapbox GL JS v2 and later is licensed under the Mapbox Terms of Service, not an OSI license. Using this widget requires a Mapbox account and compliance with those terms: https://www.mapbox.com/legal/tos.

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

This module is part of the OCA/geospatial project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

Release files for odoo-addon-web-widget-mapbox 18.0.1.0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for odoo-addon-web-widget-mapbox 18.0.1.0.0.3
File Interpreter ABI Platform
odoo_addon_web_widget_mapbox-18.0.1.0.0.3-py3-none-any.whl Python 3 none any Details

Release files / odoo_addon_web_widget_mapbox-18.0.1.0.0.3-py3-none-any.whl

Download URL odoo_addon_web_widget_mapbox-18.0.1.0.0.3-py3-none-any.whl
Size 51.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6e069c76e9d946b46e97a20bab37ffc3910c991bfd8aad80e0690f9dfbb14a15
BLAKE2b-256 checksum
How to use checksums
268c0673b4f299b6a161026cac947ff250cbae61af179cd986fa590dc0851615
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

18.0.1.0.0.3 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page