Google Maps adding custom button into mapTypeControl

Viewed 52

I have added a custom button into google maps API using the following code:

function createHideControl(map) {
    const controlButton = document.createElement("button");

    // Set CSS for the control.
    controlButton.style.backgroundColor = "#fff";
    controlButton.style.border = "2px solid #fff";
    controlButton.style.borderRadius = "3px";
    controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)";
    controlButton.style.color = "rgb(25,25,25)";
    controlButton.style.cursor = "pointer";
    controlButton.style.fontFamily = "Roboto,Arial,sans-serif";
    controlButton.style.fontSize = "16px";
    controlButton.style.lineHeight = "38px";
    controlButton.style.margin = "8px 0 22px";
    controlButton.style.padding = "0 5px";
    controlButton.style.textAlign = "center";

    controlButton.textContent = "Hide Map";
    controlButton.title = "Click to hide the map";
    controlButton.type = "button";
    controlButton.id = "findme";

    
    controlButton.addEventListener("click", () => {
        GOOGLE_MAP.setMapTypeId(null)
   
    });

    return controlButton;
}

const hideMapDiv = document.createElement("div");
// Create the control.
const hidMapControl = createHideControl(GOOGLE_MAP);
// Append the control to the DIV.
hideMapDiv.appendChild(hidMapControl);

But want to add it into the mapTypeControl menu. It looks disjointed where it is now.

enter image description here

Is there a way to push into mapTypeControl instead of into the position LEFT TOP?

1 Answers

Your best option is to make a custom control which simulates the exiting one. There is an example of how to do that in the Replacing Default Controls example in the documentation.

Then add your "Hide Map" button to it.

function initMapTypeControl(map) {
  const mapTypeControlDiv = document.querySelector(".maptype-control");

  document.querySelector(".maptype-control-map").onclick = function() {
    mapTypeControlDiv.classList.add("maptype-control-is-map");
    mapTypeControlDiv.classList.remove("maptype-control-is-satellite");
    mapTypeControlDiv.classList.remove("maptype-control-is-hide");
    map.setMapTypeId("roadmap");
  };

  document.querySelector(".maptype-control-satellite").onclick = function() {
    mapTypeControlDiv.classList.remove("maptype-control-is-map");
    mapTypeControlDiv.classList.remove("maptype-control-is-hide");
    mapTypeControlDiv.classList.add("maptype-control-is-satellite");
    map.setMapTypeId("hybrid");
  };
  document.querySelector(".maptype-control-hide").onclick = function() {
    mapTypeControlDiv.classList.remove("maptype-control-is-satellite");
    mapTypeControlDiv.classList.remove("maptype-control-is-map");
    mapTypeControlDiv.classList.add("maptype-control-is-hide");
    document.getElementById("map").style.display = "none";
    document.getElementById("nomap").style.display = "block";
  };
  document.querySelector(".maptype-control-show").onclick = function() {
    document.getElementById("map").style.display = "block";
    document.getElementById("nomap").style.display = "none";
  };
  map.controls[google.maps.ControlPosition.RIGHT_TOP].push(mapTypeControlDiv);
}

proof of concept fiddle

screenshot of resulting map

code snippet:

let map;

function initMap() {
  map = new google.maps.Map(document.querySelector("#map"), {
    center: {
      lat: -34.397,
      lng: 150.644
    },
    zoom: 8,
    disableDefaultUI: true,
  });
  initMapTypeControl(map);
}

function initMapTypeControl(map) {
  const mapTypeControlDiv = document.querySelector(".maptype-control");

  document.querySelector(".maptype-control-map").onclick = function() {
    mapTypeControlDiv.classList.add("maptype-control-is-map");
    mapTypeControlDiv.classList.remove("maptype-control-is-satellite");
    mapTypeControlDiv.classList.remove("maptype-control-is-hide");
    map.setMapTypeId("roadmap");
  };

  document.querySelector(".maptype-control-satellite").onclick = function() {
    mapTypeControlDiv.classList.remove("maptype-control-is-map");
    mapTypeControlDiv.classList.remove("maptype-control-is-hide");
    mapTypeControlDiv.classList.add("maptype-control-is-satellite");
    map.setMapTypeId("hybrid");
  };
  document.querySelector(".maptype-control-hide").onclick = function() {
    mapTypeControlDiv.classList.remove("maptype-control-is-satellite");
    mapTypeControlDiv.classList.remove("maptype-control-is-map");
    mapTypeControlDiv.classList.add("maptype-control-is-hide");
    document.getElementById("map").style.display = "none";
    document.getElementById("nomap").style.display = "block";
  };
  document.querySelector(".maptype-control-show").onclick = function() {
    document.getElementById("map").style.display = "block";
    document.getElementById("nomap").style.display = "none";
  };
  map.controls[google.maps.ControlPosition.RIGHT_TOP].push(mapTypeControlDiv);
}

window.initMap = initMap;
#map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.gm-style .controls {
  font-size: 28px;
  /* this adjusts the size of all the controls */
  background-color: white;
  box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
  box-sizing: border-box;
  border-radius: 2px;
  cursor: pointer;
  font-weight: 300;
  height: 1em;
  margin: 6px;
  text-align: center;
  user-select: none;
  padding: 2px;
  width: 1em;
}

.gm-style .controls button {
  border: 0;
  background-color: white;
  color: rgba(0, 0, 0, 0.6);
}

.gm-style .controls button:hover {
  color: rgba(0, 0, 0, 0.9);
}

.gm-style .controls.zoom-control {
  display: flex;
  flex-direction: column;
  height: auto;
}

.gm-style .controls.zoom-control button {
  font: 0.85em Arial;
  margin: 1px;
  padding: 0;
}

.gm-style .controls.maptype-control {
  display: flex;
  flex-direction: row;
  width: auto;
}

.gm-style .controls.maptype-control button {
  display: inline-block;
  font-size: 0.5em;
  margin: 0 1px;
  padding: 0 6px;
}

.gm-style .controls.maptype-control.maptype-control-is-map .maptype-control-map {
  font-weight: 700;
}

.gm-style .controls.maptype-control.maptype-control-is-satellite .maptype-control-satellite {
  font-weight: 700;
}

.gm-style .controls.fullscreen-control button {
  display: block;
  font-size: 1em;
  height: 100%;
  width: 100%;
}

.gm-style .controls.fullscreen-control .fullscreen-control-icon {
  border-style: solid;
  height: 0.25em;
  position: absolute;
  width: 0.25em;
}

.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-top-left {
  border-width: 2px 0 0 2px;
  left: 0.1em;
  top: 0.1em;
}

.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-left {
  border-width: 0 2px 2px 0;
}

.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-top-right {
  border-width: 2px 2px 0 0;
  right: 0.1em;
  top: 0.1em;
}

.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-right {
  border-width: 0 0 2px 2px;
}

.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-left {
  border-width: 0 0 2px 2px;
  left: 0.1em;
  bottom: 0.1em;
}

.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-left {
  border-width: 2px 2px 0 0;
}

.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-right {
  border-width: 0 2px 2px 0;
  right: 0.1em;
  bottom: 0.1em;
}

.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-right {
  border-width: 2px 0 0 2px;
}
<!DOCTYPE html>
<html>

<head>
  <title>Replacing Default Controls</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
</head>

<body>
  <div id="nomap" style="display:none">
    <button class="maptype-control-show" title="Hide map">
          Show Map
        </button>
  </div>
  <div id="map"></div>
  <!-- Hide controls until they are moved into the map. -->
  <div style="display: none">
    <div class="controls zoom-control">
      <button class="zoom-control-in" title="Zoom In">+</button>
      <button class="zoom-control-out" title="Zoom Out">−</button>
    </div>
    <div class="controls maptype-control maptype-control-is-map">
      <button class="maptype-control-hide" title="Hide map">
          Hide Map
        </button> <button class="maptype-control-map" title="Show road map">Map</button>
      <button class="maptype-control-satellite" title="Show satellite imagery">
          Satellite
        </button>
    </div>
    <div class="controls fullscreen-control">
      <button title="Toggle Fullscreen">
          <div
            class="fullscreen-control-icon fullscreen-control-top-left"
          ></div>
          <div
            class="fullscreen-control-icon fullscreen-control-top-right"
          ></div>
          <div
            class="fullscreen-control-icon fullscreen-control-bottom-left"
          ></div>
          <div
            class="fullscreen-control-icon fullscreen-control-bottom-right"
          ></div>
        </button>
    </div>
  </div>

  <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
</body>

</html>

Related