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 ​