Skip to content

GoogleMap

The GoogleMap controller renders an interactive Google Maps view with markers positioned via client-side geocoding of address fields from the database. It includes an optional data grid sidebar with a draggable splitter, similar to the ChartPanel layout.

The GoogleMap controller is a standalone data panel (Controller: GoogleMap) that reads model records, concatenates address fields for geocoding, and displays the results as map markers. Clicking a marker shows an InfoWindow with record details; clicking a grid row centers the map on the corresponding marker.

GoogleMap with Customer data from TasKitto

Obtaining a Google Maps API Key

The GoogleMap controller requires a Google Maps API key. To obtain one:

  1. Go to the Google Cloud Console
  2. Create a new project (or select an existing one)
  3. Navigate to APIs & Services > Library
  4. Enable the following APIs:
    • Maps JavaScript API — required to display the map
    • Geocoding API — required to convert addresses to coordinates
    • Directions API — only needed if using routing features
  5. Navigate to APIs & Services > Credentials
  6. Click Create Credentials > API Key
  7. (Recommended) Restrict the key to your application's HTTP referrers

API Key Security

The API key is embedded in the web page and visible to users. Always restrict it to specific HTTP referrers in the Google Cloud Console to prevent unauthorized use. Never use an unrestricted key in production.

Configure the key globally in Config.yaml:

yaml
GoogleMapsApiKey: AIzaSy...your-key-here

Individual views can override the key via the GoogleMap/ApiKey node.

Basic usage

yaml
Type: Data
Controller: GoogleMap
  GoogleMap:
    Zoom: 6
    Center:
      Latitude: 41.9028
      Longitude: 12.4964
    MapTypeId: ROADMAP
    MapControls:
      Zoom: True
      MapType: True
      FullScreen: True
      StreetView: False
    MapView:
      Traffic: False
      Bicycling: False
      Markers: True
    SidebarPosition: West
    SidebarWidth: 600
    AddressFields: ADDRESS, CITY
    TitleField: CUSTOMER_NAME
    InfoFields: CUSTOMER_NAME, ADDRESS, CITY, PHONE, EMAIL
MainTable:
  Model: CUSTOMER
DisplayLabel: Customer Map
ImageName: map

The controller geocodes each record's address (built by concatenating the fields listed in AddressFields) and places a marker on the map. The TitleField is displayed as the InfoWindow header, and the remaining InfoFields (excluding the title field to avoid duplication) form the InfoWindow body.

Map configuration

Map options are defined under the GoogleMap node:

PropertyDefaultDescription
ApiKeyfrom Config.yamlGoogle Maps API key (overrides the global GoogleMapsApiKey)
Center/Latitude0Initial map center latitude
Center/Longitude0Initial map center longitude
Center/AddressInitial center by address (geocoded, used when lat/lng are 0)
Zoom12Initial zoom level (1 = world, 20 = building)
MapTypeIdROADMAPMap type: ROADMAP, SATELLITE, HYBRID, TERRAIN
Height0Map height in pixels (0 = fill available space)

MapControls

The MapControls node defines which UI controls are displayed on the map. These can also be toggled at runtime via toolbar checkboxes:

PropertyDefaultDescription
ZoomTrueShow +/- zoom buttons on the map
MapTypeTrueShow Map/Satellite toggle on the map
FullScreenTrueShow fullscreen button on the map
StreetViewFalseShow Street View pegman on the map
yaml
GoogleMap:
  MapControls:
    Zoom: True
    MapType: True
    FullScreen: True
    StreetView: False

MapView

The MapView node defines which layers and features are active by default. Each feature has a corresponding toggle button in the toolbar that the user can click to enable/disable at runtime:

PropertyDefaultDescription
TrafficFalseShow real-time traffic overlay
BicyclingFalseShow cycling paths overlay
MarkersTrueShow/hide all markers on the map
yaml
GoogleMap:
  MapView:
    Traffic: False
    Bicycling: False
    Markers: True

The toggle buttons in the toolbar are highlighted with the accent color when their feature is active.

Toolbar

The toolbar above the data grid provides:

  • Refresh button — reloads both markers and grid data from the server
  • Toggle buttons for each MapView feature (Traffic, Bicycling, Markers) — click to activate/deactivate
  • Checkboxes for each MapControl (Zoom, Map Type, Full Screen, Street View) — check/uncheck to show/hide controls on the map

All toolbar actions take effect immediately without reloading the page.

The data grid sidebar is rendered automatically when the view has a MainTable/Model. The sidebar position and width are configured under the GoogleMap node:

PropertyDefaultDescription
SidebarPositionWestSidebar position: West (left) or East (right)
SidebarWidth400Sidebar initial width in pixels

A draggable splitter between the sidebar and the map allows the user to resize both areas interactively.

Grid-map interaction:

  • Click a grid row to center the map on the corresponding marker and open its InfoWindow
  • Click a marker to highlight the corresponding row in the grid and scroll it into view

Marker configuration

Markers are positioned by geocoding addresses built from model fields:

PropertyDefaultDescription
AddressFieldsComma-separated list of model field names concatenated to form the geocoding address (e.g., ADDRESS, CITY, COUNTRY)
TitleFieldModel field displayed as the InfoWindow header (bold)
InfoFieldsComma-separated list of model fields displayed in the InfoWindow body. The TitleField is automatically excluded to avoid duplication

Records with empty address fields are skipped (no marker placed).

Geocoding throttling

Google Geocoding API has rate limits. The client-side JS processes markers in batches of 5 with a 300ms delay between batches to stay within limits. For large datasets, consider storing lat/lng coordinates in the model and using those directly instead of geocoding.

Routing

The GoogleMap controller supports route calculation between two addresses via the Google Directions API (requires enabling the Directions API in Google Cloud Console). Add a Routing node under GoogleMap:

yaml
Controller: GoogleMap
  GoogleMap:
    Zoom: 6
    Routing:
      Origin: Rome, Italy
      Destination: Milan, Italy
      Mode: DRIVING
    ShowDirectionsPanel: True
PropertyDefaultDescription
Routing/OriginStart address or coordinates
Routing/DestinationEnd address or coordinates
Routing/ModeDRIVINGTravel mode: DRIVING, WALKING, BICYCLING, TRANSIT
ShowDirectionsPanelFalseShow turn-by-turn directions panel next to the map

Data endpoint

The GoogleMap controller provides an automatic JSON endpoint for refreshing markers:

kx/view/{ViewName}/map-data

The endpoint returns a JSON object with two properties:

json
{
  "markers": [
    {"address": "corso Vittorio 88, TORINO", "title": "Starlight Media", "info": "...", "idx": 0}
  ],
  "gridHtml": "<tr>...</tr>..."
}

The Refresh toolbar button triggers this endpoint to reload both markers and grid data.

TasKitto example

The TasKitto demo application includes a Customer Map view that displays all customers on a map, geocoded from their address fields.

Config.yaml

Add the Google Maps API key to the application config:

yaml
GoogleMapsApiKey: AIzaSy...your-key-here

Customer model

The CUSTOMER model provides address fields used for geocoding:

yaml
ModelName: CUSTOMER
ImageName: shopping_bag
Fields:
  CUSTOMER_ID: String(32) not null primary key
    IsVisible: False
    DefaultValue: %COMPACT_GUID%
  CUSTOMER_NAME: String(40) not null
  ADDRESS: String(60)
  CITY: String(60)
  PHONE: String(20)
  EMAIL: String(60)
  STATUS: String(10)
    AllowedValues:
      Prospect: Prospect
      Active: Active
      Inactive: Inactive
DetailReferences:
  PROJECT: PROJECT

CustomerMap view

The view uses AddressFields: ADDRESS, CITY to build the geocoding address from two model fields. The MapControls and MapView nodes configure the initial state of controls and layers:

yaml
Type: Data
Controller: GoogleMap
  GoogleMap:
    Zoom: 6
    Center:
      Latitude: 41.9028
      Longitude: 12.4964
    MapTypeId: ROADMAP
    MapControls:
      Zoom: True
      MapType: True
      FullScreen: True
      StreetView: False
    MapView:
      Traffic: False
      Bicycling: False
      Markers: True
    SidebarPosition: West
    SidebarWidth: 600
    AddressFields: ADDRESS, CITY
    TitleField: CUSTOMER_NAME
    InfoFields: CUSTOMER_NAME, ADDRESS, CITY, PHONE, EMAIL
MainTable:
  Model: CUSTOMER
DisplayLabel: Customer Map
ImageName: map

Menu entry

Add the view to the navigation menu:

yaml
Folder: _(Customers)
  View: Customers
  View: Projects
  View: CustomerMap

Theme integration

The GoogleMap controller fully adapts to the current Kittox theme (light, dark, or auto):

Map rendering:

  • Uses the native Google Maps colorScheme property: DARK when the theme is dark, LIGHT otherwise
  • Dark mode renders roads, water, parks, and labels with dark colors automatically (no custom styling needed)
  • Theme detection checks data-theme="dark" on the HTML element, with fallback to prefers-color-scheme media query for Auto mode

InfoWindow (marker popup):

  • Light theme: white background, dark text (#333)
  • Dark theme: dark background (#1f2937), light text (#e5e7eb), dark scrollbars, light close icon
  • Header title adapts its color to match the current theme
  • CSS overrides on Google Maps internal classes (.gm-style-iw-*) ensure consistent dark styling

Sidebar grid and toolbar:

  • Grid rows, headers, and hover states use --kx-surface, --kx-text, --kx-border, --kx-row-hover
  • Active row highlight (when a marker is clicked) uses --kx-accent
  • Toggle buttons use --kx-accent background when active
  • The splitter follows the standard region splitter styling (--kx-chrome-light)

See also

  • ChartPanel — chart views with grid sidebar (same layout pattern)
  • CalendarPanel — calendar views with event data
  • List — tabular data grid
  • Dashboard — composed views with multiple panels

Released under Apache License, Version 2.0.