[GIS] Leaflet infobox plugin

leafletpluginsqgisqgis2web

I am searching a plugin for Leaflet, to have an infobox at the border of the map. Please look at my screenshot.

A click on the info button should be open a window. In this window I would like to have some additional informations.

I have not found such a plugin within https://leafletjs.com/plugins.html
Maybe I have overlook a plugin with this function?

enter image description here

Background software: I am use the gis qgis with qgis2web plugin. With this plugin I can export a fully leaflet website. After export I have the possibilty to change the code and maybe insert a leaflet plugin.

Best Answer

Control L.control.info below was written as an exercise of what does it take to write simple custom control as extension of basic L.Control object. It's not very 'by the book' and not very well tested, just an exercise.

Control consists of button with (styled) title and (styled) text which is displayed uppon clicking on button.

Options:

  • title - HTML formatted title text, default is 'Info'
  • titleTooltip - tooltip text for title button, default is 'Click here for more info'
  • content - HTML formatted text, which is displayed uppon button click
  • maxWidth - maximum width of displayed content
  • titleClass - CSS style class for title
  • contentClass - CSS style class for content

Methods:

  • setTitle(txt) - set title text
  • setTitleTooltip(txt) - set title tooltip
  • setContent(txt) - set content text
  • setTitleClass(cssClass) - set CSS class for title
  • setContentClass(cssClass) - set CSS class for content

Control:

L.Control.Info = L.Control.extend({     

  options: {
    title: 'Info',
    titleTooltip: 'Click here for more info',
    content: '',
    maxWidth: '250px',
    titleClass: '',
    contentClass: ''
  },

  initialize: function(options) {        
    L.Util.setOptions(this, options);
    this._infoContainer = null;
    this._infoTitleContainer = null;
    this._infoBodyContainer = null;
    this._infoCloseButtonContainer = null;
    this._infoContentContainer = null;
    this._infoTitle = this.options.title;
    this._infoTitleTooltip = this.options.titleTooltip;
    this._infoContent = this.options.content;
    this._titleShown = false;
    this._titleClass = this.options.titleClass;
    this._contentClass = this.options.contentClass;
    this._infoTitleStyle = 'padding: 5px;';
    this._infoContainerClasses = 'leaflet-control-layers leaflet-control';
  },

  onAdd: function(map) {
    var infoContainer = L.DomUtil.create('div', 'leaflet-control-layers');

    var infoTitle = L.DomUtil.create('div');
    infoContainer.appendChild(infoTitle);
    infoTitle.setAttribute('style', this._infoTitleStyle);

    var infoBody = L.DomUtil.create('div', 'leaflet-popup-content-wraper');
    infoContainer.appendChild(infoBody);
    infoBody.setAttribute('style', 'max-width:' + this.options.maxWidth);

    var infoContent = L.DomUtil.create('div', 'leaflet-popup-content');
    infoBody.appendChild(infoContent);

    var infoCloseButton = L.DomUtil.create('a', 'leaflet-popup-close-button');
    infoContainer.appendChild(infoCloseButton);
    infoCloseButton.innerHTML = 'x';
    infoCloseButton.setAttribute('style', 'cursor: pointer');

    this._infoContainer = infoContainer;
    this._infoTitleContainer = infoTitle;
    this._infoBodyContainer = infoBody;
    this._infoContentContainer = infoContent;
    this._infoCloseButtonContainer = infoCloseButton;

    infoTitle.innerHTML = this._infoTitle;
    infoContent.innerHTML = this._infoContent;
    this._showTitle();

    L.DomEvent.disableClickPropagation(infoContainer);
    L.DomEvent.on(infoCloseButton, 'click', L.DomEvent.stop);
    L.DomEvent.on(infoContainer, 'click', this._showContent, this);
    L.DomEvent.on(infoCloseButton, 'click', this._showTitle, this);

    return infoContainer;
  },

  onRemove: function(map){},

  setTitle: function(title) {
    this._infoTitle = title;
    if (this._infoTitleContainer != null) {
      this._infoTitleContainer.innerHTML = title;
    }
  },

  setTitleTooltip: function(titleTooltip) {
    this._infoTitleTooltip = titleTooltip;
    if (this._titleShown) {
      this._showTitleTooltip(true);
    }
  },

  setContent: function(content) {
    this._infoContent = content;
    if (this._infoContentContainer != null) {
      this._infoContentContainer.innerHTML = content;
    }
  },

  setTitleClass: function(titleClass) {
    this._titleClass = titleClass;
    if (this._titleShown) {
      this._addInfoClass(this._titleClass);
    }
  },

  setContentClass: function(contentClass) {
    this._contentClass = contentClass;
    if (!this._titleShown) {
      this._addInfoClass(this._contentClass);
    }
  },

  _showTitle: function (evt) {
    this._addInfoClass(this._titleClass);
    this._displayElement(this._infoTitleContainer, true);
    this._displayElement(this._infoBodyContainer, false);
    this._displayElement(this._infoCloseButtonContainer, false);
    this._showTitleTooltip(true);
    this._setCursorToPointer(this._infoContainer, true);
    this._titleShown = true;
  },

  _showContent: function (evt) {
    this._addInfoClass(this._contentClass);
    this._displayElement(this._infoTitleContainer, false);
    this._displayElement(this._infoBodyContainer, true);
    this._displayElement(this._infoCloseButtonContainer, true);
    this._showTitleTooltip(false);
    this._setCursorToPointer(this._infoContainer, false);
    this._titleShown = false;
  },

  _showTitleTooltip: function (showIt) {
    this._infoContainer.setAttribute('Title', (showIt) ? this._infoTitleTooltip : '');
  },

  _displayElement: function (element, displayIt) {
    element.style.display = (displayIt) ? '' : 'none';
  },

  _setCursorToPointer: function (element, setIt) {
    element.style.cursor = (setIt) ? 'pointer' : '';
  },

  _addInfoClass: function (classToAdd) {
    L.DomUtil.setClass(this._infoContainer, this._infoContainerClasses + ' ' + classToAdd);
  }
});

L.control.info = function(opts) {
  return new L.Control.Info(opts);
}

JSFiddel example: https://jsfiddle.net/TomazicM/rqu3nvLj/

Related Question