javascriptleafletpopupinfobubble

How can I port the part of a Google maps application that uses infobubble.js to use Leaflet?


I am trying to port an old application that has a Google maps plugin, and uses infobubble.js to display popups on the map to use Leaflet instead. I have got most of it working, but I'm not sure how to tackle the part that uses infobubble.js. In particular, it uses the tabs features of infobubble e.g. infoBubble.addTab() to attach several different bits of html information to one location / marker. I've looked through the leaflet plugins at https://leafletjs.com/plugins.html and haven't been able to find anything that looks suitable. I found the source code for infobubble.js at https://github.com/googlearchive/js-info-bubble, but porting that to Leaflet seems beyond my limited javascript abilities. I've also considered making a simple replacement, but most references to creating tabbed content seem to suggest using jquery to manage the tabs, but (again, with my limited skills) I'm not sure whether that would work, or how to do that with html that is only displayed in a popup.


Solution

  • You don't need any jquery for that. A small library is enough. Take a look at this tabby and here is an example of how to use it - example

    All you need to do when building a popup in leaflejs is the appropriate html and that's it. The only thing you have to do is move the tabs behind the popup outline with css.

    /* eslint-disable no-undef */
    /**
     * tabs in popup
     */
    
    // config map
    let config = {
      minZoom: 1,
      maxZomm: 18,
    };
    // magnification with which the map will start
    const zoom = 15;
    // co-ordinates
    const lat = 50.0595;
    const lng = 19.9379;
    
    // calling map
    const map = L.map("map", config).setView([lat, lng], zoom);
    
    // Used to load and display tile layers on the map
    // Most tile servers require attribution, which you can set under `Layer`
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    }).addTo(map);
    
    // custom popup image + text
    const customPopup = `<div class="customPopup">
        <ul class="tabs-example" data-tabs>
          <li><a data-tabby-default href="#sukiennice">Sukiennice</a></li>
          <li><a href="#lorem">lorem</a></li>
        </ul>
        <div id="sukiennice">
          <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/A-10_Sukiennice_w_Krakowie_Krak%C3%B3w%2C_Rynek_G%C5%82%C3%B3wny_MM.jpg/1920px-A-10_Sukiennice_w_Krakowie_Krak%C3%B3w%2C_Rynek_G%C5%82%C3%B3wny_MM.jpg" width="300">Source: wikipedia.org<div>Kraków,[a] also written in English as Krakow and traditionally known as Cracow, is the second-largest and one of the oldest cities in Poland. Situated on the Vistula River in Lesser Poland Voivodeship... <a href="https://en.wikipedia.org/wiki/Krak%C3%B3w" target="_blank">→ show more</a></div>
        </div>
        <div id="lorem">
          Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.
        </div>
      </div>`;
    
    // specify popup options
    const customOptions = {
      minWidth: "220", // set max-width
      keepInView: true, // Set it to true if you want to prevent users from panning the popup off of the screen while it is open.
    };
    
    const marker = L.marker([50.0616, 19.9373])
      .bindPopup(customPopup, customOptions)
      .on('click', tabsrun);
    
    marker.addTo(map);
    
    // center map when click on marker
    function tabsrun(e) {
      if (marker.isPopupOpen()) {
        const tabs = new Tabby("[data-tabs]");
      }
    }
    html, body {
      height: 100%;
      margin: 0;
    }
    
    #map {
      height: 100%;
    }
    
    .tabs-example {
      margin-top: -45px !important;
      position: absolute;
    }
    
    .tabs-example li {
      background: #fff;
    }
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.0/dist/js/tabby.polyfills.min.js"></script>
    <link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
    <link href="https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.0/dist/css/tabby-ui.min.css" rel="stylesheet"/>
    
    <div id="map"></div>

    I have added an example of using a tab to my examples tabs in popup