block by ThomasG77 77bee632812a3441a72eb534603930a6

Vanilla JS fork of ol3-ext GeoBookmark http://bl.ocks.org/ThomasG77/77bee632812a3441a72eb534603930a6 (original version at http://viglino.github.io/ol3-ext/examples/map.control.geobookmark.html) due to jQuery dependency

Full Screen

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <meta name=description content="">
    <meta name=viewport content="width=device-width, initial-scale=1">
    <title>Simple OpenStreetMap Map</title>

    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v4.4.1/build/ol.js" type="text/javascript"></script>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.4.1/css/ol.css">
 
    <!-- Vanilla fork of ol3-ext GeoBookmark //viglino.github.io/ol3-ext/examples/map.control.geobookmark.html -->
    <script src="geo-bookmarks.js"></script>
    <link rel="stylesheet" href="geobookmarkcontrol.css" type="text/css" />


    <style type="text/css">
      html, body {
        margin: 0;
        height: 100%;
      }
      #map {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
      }

    </style>
  </head>
  <body>
    <div id="map" class="map">
    </div>
    <script>

      var map = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        target: 'map',
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });

      var bm = new ol.control.GeoBookmark({
        marks: {
          "Paris": {
            pos: ol.proj.fromLonLat([2.351828, 48.856578]),
            zoom: 11,
            permanent: true
          },
          "London": {
            pos: ol.proj.fromLonLat([-0.1275,51.507222]),
            zoom: 11,
            permanent: true
          },
          "Geneve": {
            pos: ol.proj.fromLonLat([6.149985,46.200013]),
            zoom: 13,
            permanent: true
          },
          "Bruxelles": {
            pos: ol.proj.fromLonLat([4.35,50.83]),
            zoom: 12,
            permanent: true
          },
          "Madrid": {
            pos: ol.proj.fromLonLat([-3.683333,40.433333]),
            zoom: 12
          },
          "Roma": {
            pos: ol.proj.fromLonLat([12.48657,41.888732]),
            zoom: 12
          }
        }
      });
      map.addControl(bm);

    </script>
  </body>
</html>

geo-bookmarks.js

/** GeoBookmarks
 *
 * @constructor
 * @extends {ol.control.Control}
 * @trigger add|remove when a bookmark us added or deleted
 * @param {Object=} Control options.
 *  - className {string} default ol-bookmark
 *  - placeholder {string} input placeholder, default Add a new geomark...
 *  - editable {bool} enable modification, default true
 *  - marks a list of default bookmarks : { BM1:{pos:ol.coordinates, zoom: integer, permanent: true}, BM2:{pos:ol.coordinates, zoom: integer} }
 */
ol.control.GeoBookmark = function(options) {
  options = options || {};
  var self = this;

  var element = document.createElement('div');
  if (options.target) {
    element.className = options.className || "ol-bookmark";
  } else {
    element.className = (options.className || "ol-bookmark") +
          " ol-unselectable ol-control ol-collapsed";
    element.addEventListener("mouseleave", function() {
      if (input !== document.activeElement) {
        menu.style.display = 'none';
      };
    });
    // Show bookmarks on click
    this.button = document.createElement('button');
    this.button.setAttribute('type', 'button');
    this.button.addEventListener('click', function(e) {
      menu.style.display = (menu.style.display === '' || menu.style.display === 'none' ? 'block': 'none');
    });
    element.appendChild(this.button);
  }
  // The menu
  var menu = document.createElement('div');
  element.appendChild(menu);
  var ul = document.createElement('ul');
  menu.appendChild(ul);
  var input = document.createElement('input');
  input.setAttribute("placeholder", options.placeholder || "Add a new geomark...")
  input.addEventListener("change", function(e) {
    console.log('change', this);
    var title = this.value;
    if (title) {
      self.addBookmark(title);
      this.value = '';
      self.dispatchEvent({
        type: "add",
        name: title
      });
    }
    menu.style.display = 'none';
  });
  input.addEventListener("blur", function() {
    menu.style.display = 'none';
  });
  if (options.editable !== false) {
    menu.appendChild(input);
  };

  // Init
  ol.control.Control.call(this, {
    element: element,
    target: options.target
  });

  this.set("editable", options.editable !== false);
  // Set default bmark
  this.setBookmarks(options.marks);
};
ol.inherits(ol.control.GeoBookmark, ol.control.Control);

/** Set bookmarks
* @param {} bmark a list of bookmarks : { BM1:{pos:ol.coordinates, zoom: integer}, BM2:{pos:ol.coordinates, zoom: integer} }
* @param [boolean} modify, default false
*/
ol.control.GeoBookmark.prototype.setBookmarks = function(bmark) {
  if (!bmark) bmark = JSON.parse(localStorage["ol@bookmark"] || "{}");
  var modify = this.get("editable");
  var ul = this.element.querySelector("ul");
  var menu = this.element.querySelector("div");
  var self = this;

  localStorage["ol@bookmark"] = JSON.stringify(bmark);
  // ul.innerHtml = '';
  Array.prototype.slice.call(ul.querySelectorAll('li')).forEach(function(li) {
    li.remove();
  });
  for (var b in bmark) {
    var li = document.createElement('li');
    li.textContent = b;
    li.setAttribute('data-bookmark', JSON.stringify(bmark[b]));
    li.addEventListener('click', function() {
      var bm = JSON.parse(this.getAttribute("data-bookmark"));
      self
        .getMap()
        .getView()
        .setCenter(bm.pos);
      self
        .getMap()
        .getView()
        .setZoom(bm.zoom);
      menu.style.display = 'none';
    });
    ul.appendChild(li);
    if (modify && !bmark[b].permanent) {
      var button = document.createElement('button');
      button.setAttribute('data-name', b);
      button.setAttribute("title", "Suppr.");
      button.addEventListener('click', function(e) {
        self.removeBookmark(this.getAttribute("data-name"));
        self.dispatchEvent({ type: "add", name: this.getAttribute("data-name") });
        e.stopPropagation();
      });
      li.appendChild(button);
    }
  }
};

/** Get Geo bookmarks
* @return a list of bookmarks : { BM1:{pos:ol.coordinates, zoom: integer}, BM2:{pos:ol.coordinates, zoom: integer} }
*/
ol.control.GeoBookmark.prototype.getBookmarks = function() {
  return JSON.parse(localStorage["ol@bookmark"] || "{}");
};

/** Remove a Geo bookmark
* @param {string} name
*/
ol.control.GeoBookmark.prototype.removeBookmark = function(name) {
  if (!name) {
    return;
  };
  bmark = JSON.parse(localStorage["ol@bookmark"] || "{}");
  delete bmark[name];
  this.setBookmarks(bmark);
};

/** Add a new Geo bookmark
* @param {string} name
* @param {ol.Coordintes} position, default current position
* @param {number} zoom, default default map zoom
* @param {bool} permanent: prevent from deletion, default false
*/
ol.control.GeoBookmark.prototype.addBookmark = function(
  name,
  position,
  zoom,
  permanent
) {
  if (!name) return;
  bmark = JSON.parse(localStorage["ol@bookmark"] || "{}");
  bmark[name] = {
    pos:
      position ||
      this.getMap()
        .getView()
        .getCenter(),
    zoom:
      zoom ||
      this.getMap()
        .getView()
        .getZoom()
  };
  if (permanent) {
    bmark[name].permanent = true;
  }
  this.setBookmarks(bmark);
};

geobookmarkcontrol.css

.ol-control.ol-bookmark 
{	top: 0.5em;
	left: 3em;
}
.ol-control.ol-bookmark button
{	position: relative;
}
.ol-control.ol-bookmark > button::before
{	content: "";
	position: absolute;
	border-width: 10px 5px 4px;
	border-style: solid;
	border-color: #fff;
	border-bottom-color: transparent;
	top: 50%;
	left: 50%;
	-webkit-transform: translate(-50%, -50%);
	transform: translate(-50%, -50%);
	height: 0;
}

.ol-control.ol-bookmark > div
{	display: none;
	min-width: 5em;
}
.ol-control.ol-bookmark input
{	font-size: 0.9em;
	margin: 0.1em 0 ;
	padding: 0 0.5em;
}
.ol-control.ol-bookmark ul
{	margin:0;
	padding: 0;
	list-style: none;
}
.ol-control.ol-bookmark li
{	color: rgba(0,60,136,0.8);
	font-size: 0.9em;
	padding: 0 0.2em 0 0.5em;
	cursor: default;
	clear:both;
}

.ol-control.ol-bookmark li:hover
{	background-color: rgba(0,60,136,.5);
	color: #fff;
}

.ol-control.ol-bookmark > div button
{	width: 1em;
	height: 0.8em;
	float: right;
	background-color: transparent;
	cursor: pointer;
	border-radius: 0;
}
.ol-control.ol-bookmark > div button:before
{	content: "\2A2F";
    color: #936;
	font-size: 1.2em;
	line-height: 1em;
	border-radius: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
}