Ol3 Boundless - layer selector placement

by Albert van Niekerk   Last Updated May 28, 2018 10:22 AM

I recently started playing around with ol3 + boundless. I created the edit application using > suite-sdk create myApp ol3edit.

I am trying to move the layer view/selector from the map to a .col-md-1 on the side of the map (the layer view/selector on the map annoys me and is limiting)

I could manage to get it removed from the map, it renders to my declared div, but it moves it to the bottom of the map. See images and code, the code is the code that was scaffold-ed by the suite-sdk create command...

Code:
index.html

<div class="container-fluid map-container">
  <div class="row">
      <!-- have layers displayed here: BEGIN -->
      <div class="col-sm-1 col-md-1">
          <div id="layers">
          </div>
      </div>
      <!-- have layers displayed here: END -->
    <div class="col-sm-7 col-md-7 nopadding">
      <div id="map"></div>
    </div>
    <div class="col-sm-4 col-md-4 ">
      <div id="features-container">
        <table id="features" class="table table-hover table-responsive">
        </table>
      </div>
    </div>
  </div>
</div>

LayersControl.js

var app = window.app;
// added by me
var layersContainer = document.getElementById('layers');

app.LayersControl = function(opt_options) {
    this.defaultGroup = "default";
    var options = opt_options || {};

    if (options.groups) {
        this.groups = options.groups;
        if (!this.groups[this.defaultGroup]) {
            this.groups[this.defaultGroup] = {};
        }
    } else {
        this.groups = {};
        this.groups[this.defaultGroup] = {};
    }
    this.containers = {};
    for (var group in this.groups) {
        this.containers[group] = document.createElement('ul');
        if (this.groups[group].title) {
            $(this.containers[group]).html(this.groups[group].title);
        }
        //element.appendChild(this.containers[group]);
        // added by me
        layersContainer.appendChild(this.containers[group]);
    }
    ol.control.Control.call(this, {
        // edited by me
        element: layersContainer,
        target: options.target
    });
};

ol.inherits(app.LayersControl, ol.control.Control);

app.LayersControl.prototype.setMap = function(map) {
    ol.control.Control.prototype.setMap.call(this, map);
    var layers = map.getLayers().getArray();
    for (var i=0, ii=layers.length; i < ii; ++i) {
        var layer = layers[i];
        var title = layer.get('title');
        var group = layer.get('group') || this.defaultGroup;
        if (title) {
            var item = document.createElement('li');
            if (this.groups[group] && this.groups[group].exclusive === true) {
    $('<input />', {type: 'radio', name: group, value: title, checked:
      layer.getVisible()}).
      change([map, layer, group], function(evt) {
        var map = evt.data[0];
        var layers = map.getLayers().getArray();
        for (var i=0, ii=layers.length; i<ii; ++i) {
          if (layers[i].get("group") == evt.data[2]) {
            layers[i].setVisible(false);
          }
        }
        var layer = evt.data[1];
        layer.setVisible($(this).is(':checked'));
      }).appendTo(item);
    $('<span />').html(title).appendTo(item);
    this.containers[group].appendChild(item);
 // added by me
 layersContainer.appendChild(item);
  } else {
    $('<input />', {type: 'checkbox', checked: layer.getVisible()}).
      change(layer, function(evt) {
        evt.data.setVisible($(this).is(':checked'));
      }).appendTo(item);
    $('<span />').html(title).appendTo(item);
    if (this.containers[group]) {
      this.containers[group].appendChild(item);
    } else if (this.containers[this.defaultGroup]) {
      this.containers[this.defaultGroup].appendChild(item);
    }
    // added by me
    layersContainer.appendChild(item);
      }
    }
  }
};

Currently: enter image description here

Desired: desired

  • Does anybody know why it is moving the html?
  • Is there maybe just a config that I need to set to have the layer view in its own container?


Answers 1


Fixed it.

There was a config that I did not add to the layers control. I had to add the following to the extended ol.control: target: document.getElementById('layers')

So the code looks as following:

html

  <div class="container-fluid map-container">
    <div class="row">
      <!-- add layers here -->
      <div class="col-sm-2 col-md-2">
          <div id="layers"></div>
      </div>
    <div class="col-sm-6 col-md-6 nopadding">
      <div id="map"></div>
    </div>
    <div class="col-sm-4 col-md-4 ">
      <div id="features-container">
        <table id="features" class="table table-hover table-responsive">
        </table>
      </div>
    </div>
  </div>
</div>

js

var map = new ol.Map({
controls: ol.control.defaults().extend([
    new app.LayersControl({
        groups: {
            background: {
                title: "Base Layers",
                exclusive: true
            },
            'default': {
                title: "Overlays"
            }
        },
        // this was missing!!!
        target: document.getElementById('layers')
    })
]),

css

As Jonatas has mentioned in the comments, there was a bit of css editing to do as well. I had to remove the bottom and top styling as this caused the layers to be displayed in the nav bar area

 .layers-control {
    /*bottom: 21px;*/
    /*top: auto;*/
    right: 20px;
    background-color: #333;
    color: #fff;
  }

The result final result

Albert van Niekerk
Albert van Niekerk
December 02, 2015 07:12 AM

Related Questions


open source GIS boundless sdk gxp template

Updated June 16, 2017 13:22 PM

How can I query Postgres tables directly from OpenLayers?

Updated September 16, 2017 13:22 PM


Dynamically add style to layer with user inputs

Updated August 10, 2017 08:22 AM

OpenGeo Suite create map application GXP or GeoEXT

Updated September 06, 2017 06:22 AM