Skip to content

Floor Navigation

Programmatically move between floors, build a custom floor picker UI, and react to floor changes in real time.

Prerequisites

  • A working map embed — complete Embed your first map first.
  • The map must be ready before calling navigation methods. Put navigation calls inside the onload callback.
  • getFloors() returns a Promise — resolve it with .then() or await. It also only returns floor data once the user has entered a building (outdoor view resolves to []). Call selectEntity(buildingId) to drive into a building, then read getFloors() after the floorChange event fires.

Steps

1. Fetch the list of floors with getFloors

getFloors returns a Promise<FloorInfo[]> for the currently loaded building. Each FloorInfo object includes floorId, floorNumber, longName, and shortName. Both longName and shortName are MultiLangString objects (Record<string, string>) — locale codes map to display strings, e.g. { en: "Ground Floor", fr: "Rez-de-chaussée" }. Access the English label with floor.shortName['en'] ?? floor.longName['en'].

getFloors() returns a Promise — always resolve it with .then() or await. It only returns data once the user has entered a building (outdoor view resolves to []).

javascript
mapsted.maps.init({
  element: document.getElementById("mapsted-map"),
  propertyId: 603,
  onload: function () {
    // Enter a building first so getFloors() has data.
    mapsted.maps.selectEntity(22);  // CAW Student Centre

    const unsub = mapsted.maps.once("floorChange", function () {
      mapsted.maps.getFloors().then(function (floors) {
        console.log(floors);
        /*
        [
          { floorId: 1355, shortName: { en: "L1" }, longName: { en: "Level 1" }, floorNumber: 1 },
          { floorId: 1356, shortName: { en: "L2" }, longName: { en: "Level 2" }, floorNumber: 2 },

        ]
        */
        floors.forEach(function (floor) {
          var label = floor.shortName['en'] ?? floor.longName['en'] ?? ('Floor ' + floor.floorNumber);
          console.log('Floor ' + floor.floorId + ': ' + label + ' (floorNumber ' + floor.floorNumber + ')');
        });
      });
    });
  }
});

2. Build a simple floor picker

Use the getFloors result to render buttons that drive navigation.

javascript
mapsted.maps.init({
  element: document.getElementById("mapsted-map"),
  propertyId: 603,
  onload: function () {
    const picker = document.getElementById("floor-picker");

    function renderPicker(floors) {
      picker.innerHTML = "";
      floors.forEach(function (floor) {
        const btn = document.createElement("button");
        // shortName and longName are MultiLangString (Record<string, string>)
        btn.textContent = floor.shortName['en'] ?? floor.longName['en'] ?? ('Floor ' + floor.floorNumber);
        btn.addEventListener("click", function () {
          mapsted.maps.navigateToFloorById(floor.floorId);
        });
        picker.appendChild(btn);
      });
    }

    // Drive into a building so floors populate, then re-render the
    // picker every time the floor changes.
    mapsted.maps.selectEntity(22);  // CAW Student Centre (property 603)
    mapsted.maps.on("floorChange", function () {
      mapsted.maps.getFloors().then(renderPicker);
    });
  }
});

On your own page, add a container the picker can mount into:

html
<div id="floor-picker" style="position:absolute; top:16px; right:16px; z-index:10;"></div>

Note. The in-page sandbox only ships a #mapsted-map container. The embedded version above creates the picker dynamically as a positioned overlay; your own page can use the #floor-picker div shown here.

3. Change floor by name with navigateToFloorByName

When you know the display name of the floor, pass it directly. The match is case-sensitive and must equal the English short name returned in shortName['en'] from getFloors().

javascript
mapsted.maps.navigateToFloorByName("L2");

4. Change floor by ID with navigateToFloorById

Use the numeric floorId for a reliable match that is unaffected by localization or name changes.

javascript
mapsted.maps.navigateToFloorById(1356);

V2/V3 floor navigation methods deprecated

mapsted.maps.changeFloorById() and mapsted.maps.changeFloorByName() are deprecated V2/V3 compatibility shims. They emit a console.warn and throw MAPSTED-1093 in strict mode. Use the canonical methods navigateToFloorById() and navigateToFloorByName() shown above.

5. Listen for floor changes

Subscribe to the floorChange event to keep your custom UI in sync whenever the floor changes — whether triggered by your code or by the built-in floor selector.

javascript
mapsted.maps.on("floorChange", function (payload) {
  // FloorInfo: { floorId, floorNumber, longName: Record<string,string>, shortName: Record<string,string> }
  var label = payload.shortName['en'] ?? payload.longName['en'] ?? ('Floor ' + payload.floorNumber);
  console.log("Now on floor:", payload.floorId, label);

  // highlight the matching button in your custom picker
  document.querySelectorAll("#floor-picker button").forEach(function (btn) {
    btn.classList.toggle("active", btn.textContent === label);
  });
});

6. Move to a different building

If your property has multiple buildings, select the building entity and recenter the map; floorChange fires once the building loads its default floor.

javascript
mapsted.maps.selectEntity(buildingId);
// Optionally recenter the viewport on the building's footprint.
// setViewport is the current method; setMapView is a legacy alias kept
// for backward compatibility.
mapsted.maps.setViewport({ mapCenter: buildingCenter });

mapsted.maps.on("floorChange", function () {
  // fires once the building loads its default floor
  // getFloors() returns a Promise<FloorInfo[]> — always await or .then()
  mapsted.maps.getFloors().then(function (floors) {
    console.log("New building floors:", floors);
  });
});

Expected output

Clicking a button in the custom floor picker animates the map to the selected floor. The browser console logs the floorChange event with the updated floorId and shortName['en']. The active button in the picker reflects the current floor at all times.

Next steps