Skip to main content

JavaScript

Create custom event handlers that add any functionality that you need.

More detailed technical API documentation is available here: JavaScript API

info

Use our new AI bot Mapy who is now always avialable on MapSVG control panel and ready to answer your code-related questions!

Middleware

What is Middleware?

It is a function that sits between two parts of a process and allows you to change or handle data before it continues. It acts like a "filter" or "checkpoint" for data, letting you modify or control what happens before it moves on to the next step.

For example, when you use the MapSVG plugin and data is being fetched from a server (like map Regions or Objects), a middleware function allows you to:

  • Edit the data before it is displayed on the map
  • Validate the data to make sure it's correct
  • Log information for debugging

When MapSVG loads data, it goes through a series of steps. Middleware functions are called during these steps to give you control over how the data is handled.

Here’s an example:

  • Data Request: MapSVG requests data (like map Regions) from the server
  • Middleware Function: The middleware function checks or modifies the data before it's used
  • Data is Loaded: After the middleware, MapSVG loads the processed data onto the map
info

Consider checking if the map is being displayed in the WordPress admin area (by verifying map.inBackend). Typically, you don't want to run this middleware in the backend, because if you modify the map options there and then click "Save", those modifications will be saved as default options in the database.

Middleware parameters

Every middleware function has 2 parameters:

function(data, ctx){
// ...
  • data: the data which is getting passed through middleware, the data you can modify
  • ctx: context, which may contain parameters such as request,response,map, and others.

Map init middleware

Modify map options dynamically before applying them. You can conditionally change map settings based on factors like the current URL, user roles, or other runtime conditions.

For example, if the map is not in the backend and the user is viewing a specific post, you might disable the zoom controls:

function(data, ctx){
// Take the "map" object out of context parameter:
const { map } = ctx

if (!map.inBackend && window.location.href.includes("/a-post-about-cats")) {
data.controls.zoom = false;
}

// Always return the modified or unmodified data from the middleware:
return data
}

Controller render middleware

This middleware function allows you to modify the data before it is sent to a specific controller. Available controllers are: details, popover, tooltip, directory, filters.

You can check for the type of the controller using the following code:

if(controller.is("details")) { /*...*/ }
if(controller.is("popover")) { /*...*/ }
if(controller.is("tooltip")) { /*...*/ }
// etc.

You can customize the data for different controllers, such as formatting numbers, strings, etc.

Example: If the controller is details, format the totalAmount field from "1000000" to "1,000,000":

function(data, ctx){
const { controller } = ctx;

if(controller.is("details")){
return {
...data,
totalAmount: data.totalAmount.toLocaleString('en-US')
};
}

// Always return the data object after processing to ensure it continues through the middleware chain.
return data;
}

API request @middleware

This middleware function allows you to modify the request data before it is sent to the server. Use this when you need to interact with a custom API that expects a different query format from MapSVG.

Example: If the request is for the "users" repository and the action is "index" ("show all users"), you can modify the request data by appending "_bar" to the foo property:

function(data, ctx){
const { request, repository, map } = ctx;

if(repository.schema.objectNamePlural === "users" && request.action === "index") {
data = {
...data,
foo: data.foo + "_bar"
};
}

// Always return the data object after processing to ensure it continues through the middleware chain.
return data;
}

Events

Mapsvg has numerous event handlers that allow you to add any custom functionality. The possibilities are endless.

Every event handler has 1 parameter:

function(event) {

Which, in turn, can be decomposed into to parameters:

const { map, data } = event
  • map: every event handlers has a reference to the current map instance
  • data: data passed to the event. What's inside is different for every event handler (you will see examples below)

Map

There are 4 main event handlers related to the map.

beforeInit

This event handler triggers just before the map begins its initialization process. It's a good place to set up any pre-initialization configurations or modifications.

map parameter in the event parameter provides access to the MapSVG instance, allowing you to run any custom actions that need to be completed early in the initialization phase.

function(event) {
const { map } = event;
}

afterInit

This code executes before the map loads. Use it to run any custom actions that need the map to be fully loaded (for example, add a custom jQuery Modal plugin instead of the default Details View).

function(event) {
const { map } = event;
}

afterLoadRegions

This event triggers after all regions from the regionsRepository have been fully loaded onto the map. At this point:

  • Regions are connected to their respective data objects.
  • The directory (if present) is refreshed and populated with the updated data.

This is a good place to:

  • Perform actions that depend on the regions being fully available on the map.
  • Update or manipulate the directory based on the newly loaded data.
  • Implement custom logic or effects that require all regions to be loaded.
function(event) {
const { map } = event;
console.log('Regions are fully loaded and connected to data:', map.regions);
}

afterLoadObjects

This event triggers after all objects from the objectsRepository have been fully loaded onto the map. At this point:

  • Objects are connected to their respective markers and regions.
  • The directory (if present) is updated with the new data for these objects.

This is a good place to:

  • Perform actions that depend on the objects being fully loaded and connected.
  • Update or manipulate the map’s markers or regions based on the newly loaded objects.
  • Implement custom logic or visual effects that require all objects to be loaded and displayed.
function(event) {
const { map } = event;
console.log('Objects are fully loaded and connected to markers and regions:', map.objects);
}

zoom

This event handler triggers whenever the map is zoomed in or out. It's useful for executing actions based on the zoom level of the map.

map.zoomLevel provides the current zoom level of the map. You can use this to perform tasks like:

  • Adjusting the visibility of certain elements based on zoom.
  • Logging or displaying the current zoom level for debugging or user information.
  • Dynamically loading additional data or layers depending on the zoom level.
function(event) {
const { map } = event;
console.log(map.zoomLevel);
}

Repository

Repository is a collection of objects (in case of mapsvg, it may contain either Regions or Objects, which can be WP Posts, custom objects received from your API, or objects from mapsvg database).

beforeLoad.repository

Perform actions or logging before the data is fetched from an API source into repository internal storage.

function(event) {
const { map, data: { repository } } = event
}

afterLoad.repository

Perform actions or logging after the data is fetched from an API source into repository internal storage.

function(event) {
const { map, data: { repository } } = event
}

Region

Listen of events such as click or mouseover for map regions. Current Region instance is available inside of the data param:

const { map, data: { region } } = event
console.log(region)

click.region

Triggered when a region on the map is clicked.

function(event) {
const { map, data: { region } } = event
}

mouseover.region

Triggered when the mouse pointer hovers over a region on the map.

function(event) {
const { map, data: { region } } = event

// You can access the hovered region's data using the 'region' property.
}

mouseout.region

Triggered when the mouse pointer moves out of a region on the map.

function(event) {
const { map, data: { region } } = event

// You can access the region's data using the 'region' property.
}

Marker

click.marker

function(event) {
const { map, data: { marker } } = event

}

mouseover.marker

function(event) {
const { map, data: { marker } } = event

}

mouseout.marker

function(event) {
const { map, data: { marker } } = event

}

Directory item

click.directoryItem

Triggered on cliuck on a directory item.

Example: hide all markers and show only one that is connected to the clicked directory item:

function(event) {
const { map, data: { region, object, directoryItem } } = event

if(object && object.location){
map.markers.forEach(function (marker) {
if (object.location.marker.id !== String(marker.id)) {
marker.hide()
} else {
marker.show()
}
})
}
}

mouseover.directoryItem

mouseout.directoryItem

Details view

The instance of the current details view is available inside of the data as a controller parameter:

const { map, data: { controller } } = event      
console.log(controller)

beforeRedraw.detailsView

function(event) {
const { map, data: { controller } } = event
}

afterRedraw.detailsView

function(event) {
const { map, data: { controller } } = event

}

beforeShow.detailsView

function(event) {
const { map, data: { controller } } = event

}

afterShow.detailsView

function(event) {
const { map, data: { controller } } = event

}

beforeClose.detailsView

function(event) {
const { map, data: { controller } } = event

}

afterClose.detailsView

function(event) {
const { map, data: { controller } } = event

}

Popover

The instance of the current popover is available inside of the data as a controller parameter:

const { map, data: { controller } } = event      
console.log(controller)

beforeRedraw.popover

function(event) {
const { map, data: { controller } } = event
}

afterRedraw.popover

function(event) {
const { map, data: { controller } } = event

}

beforeShow.popover

function(event) {
const { map, data: { controller } } = event

}

afterShow.popover

function(event) {
const { map, data: { controller } } = event

}

beforeClose.popover

function(event) {
const { map, data: { controller } } = event

}

afterClose.popover

function(event) {
const { map, data: { controller } } = event

}

Tooltip

The instance of the current tooltip is available inside of the data as a controller parameter:

const { map, data: { controller } } = event      
console.log(controller)

beforeRedraw.tooltip

function(event) {
const { map, data: { controller } } = event
}

afterRedraw.tooltip

function(event) {
const { map, data: { controller } } = event

}

beforeShow.tooltip

function(event) {
const { map, data: { controller } } = event

}

afterShow.tooltip

function(event) {
const { map, data: { controller } } = event

}

beforeClose.tooltip

function(event) {
const { map, data: { controller } } = event

}

afterClose.tooltip

function(event) {
const { map, data: { controller } } = event

}

FAQ

How to modify map settings before applyng them to the map?

Use Map init middleware

How to modify data that is passed to a controller (details / popover / tooltip)?

Use Controller render middleware

How to add custom jQuery Modal?

Use Map afterInit event