In the first example, called ch05_toolbar, we create the constructor function for our management system and add some methods to it to add and remove controls. We don't need any styling at this point. Firstly, we create the constructor:
var toolBar = function (options) {
'use strict';
if (!(this instanceof toolBar)) {
throw new Error('toolBar must be constructed with the new keyword.');
} else if (typeof options === 'object' && options.map && options.target && options.layertree) {
if (!(options.map instanceof ol.Map)) {
throw new Error('Please provide a valid OpenLayers 3 map object.');
}
this.map = options.map;
this.toolbar = document.getElementById(options.target);
this.layertree = options.layertree;
this.controls = new ol.Collection();
} else {
throw new Error('Invalid parameter(s) provided.');
}
};Similar to the layer tree, we use the use strict paradigm to avoid bad invokes. The constructor takes an object with properties as an argument. The object must contain a reference to our map, a target element, and a reference to our layer tree. If everything is in place, we create an empty collection object in which we will store the controls associated with the given instance of our toolbar. Next, we add an addControl method to its prototype:
toolBar.prototype.addControl = function (control) {
if (!(control instanceof ol.control.Control)) {
throw new Error('Only controls can be added to the toolbar.');
}
if (control.get('type') === 'toggle') {
control.on('change:active', function () {
if (control.get('active')) {
this.controls.forEach(function (controlToDisable) {
if (controlToDisable.get('type') === 'toggle' && controlToDisable !== control) {
controlToDisable.set('active', false);
}
});
}
}, this);
}
control.setTarget(this.toolbar);
this.controls.push(control);
this.map.addControl(control);
return this;
};The method checks whether a valid OpenLayers 3 control has been given to it. If not, it simply returns a user-friendly error message. Next, it checks the type of the control, which we have to set manually later. In our structure, only one control can be active with a toggle type at a time. Every toggle control will get a listener associated with it. If it gets activated, every other toggle control in the toolbar gets deactivated (except the activated control). As a last step, we set the control's target and add it to the toolbar's collection and the map as well.
Next, we extend our toolbar further with a removeControl method:
toolBar.prototype.removeControl = function (control) {
this.controls.remove(control);
this.map.removeControl(control);
return this;
};This very simple method removes the control from the toolbar and also from the map. As every event is associated with the removed control, the library takes care of cleaning up automatically.
As a last step, we remove the zoom control from the map's constructor in our init function and add it to our toolbar instead:
var tools = new toolBar({
map: map,
target: 'toolbar',
layertree: tree,
}).addControl(new ol.control.Zoom());Now save the example and load it up in your browser. Do you see any changes? No? This means, everything works fine. From now on, our own control management system handles the zoom controls.