mardi 30 décembre 2014

How to adapt layerswitcher to include listboxs


For my project I needed something that allowed the user to change the application´s layers and the best solution I found was this one layer switcher since openlayers 3 does not support a layerswitcher by default. This solution allowed me to do so with ease ... until I noticed that I had way too many options and that checkboxs were not enough... I tried editing as much as I could so it could display a listbox but I have a problem. The box is being filled correctly but when I try to change a value it always selects the last option.


This is the code I edited



ol.control.LayerSwitcher.prototype.renderLayer_ = function(lyr, idx, selectList) {

var this_ = this;
var li = document.createElement('li');
var lyrTitle = lyr.get('title');
var lyrId = lyr.get('title').replace(' ', '-') + '_' + idx;
var label = document.createElement('label');

if (lyr.getLayers) {

li.className = 'group';
label.innerHTML = lyrTitle;
li.appendChild(label);
var ul = document.createElement('ul');
li.appendChild(ul);
this.renderLayers_(lyr, ul);

} else {

var input = document.createElement('input');
var option = document.createElement("option");

if (lyr.get('type') === 'base') {
input.type = 'radio';
input.name = 'base';
option.value = idx;
option.text = lyrTitle;
option.name = 'base';
selectList.appendChild(option);
} else {
input.type = 'checkbox';
}
input.id = lyrId;

option.selected= lyr.get('visible');
selectList.onchange = function (e) {
alert(e.target.selectedIndex);
this_.setVisible_(lyr, e.target.selectedIndex);

};
li.appendChild(selectList);

input.checked = lyr.get('visible');
input.onchange = function (e) {
this_.setVisible_(lyr, e.target.checked);
};
li.appendChild(input);

label.htmlFor = lyrId;
label.innerHTML = lyrTitle;
li.appendChild(label);

}

return li;
};


and



ol.control.LayerSwitcher.prototype.renderLayers_ = function(lyr, elm) {
var lyrs = lyr.getLayers().getArray().slice().reverse();

var selectList = document.createElement("select");
selectList.id = "mapTypes";
selectList.size = 5;

for (var i = 0, l; i < lyrs.length; i++) {
l = lyrs[i];
if (l.get('title')) {
elm.appendChild(this.renderLayer_(l, i, selectList));
}
}
};


I know I have to change something in the onChange function but I am not that good with javascript so i am a little bit lost on what to do next.


(the onChange function)



ol.control.LayerSwitcher.prototype.setVisible_ = function(lyr, visible) {
var map = this.getMap();
var selectedid = 2;

lyr.setVisible(visible);

if (visible && lyr.get('type') === 'base') {
// Hide all other base layers regardless of grouping

ol.control.LayerSwitcher.forEachRecursive(map, function (l, idx, a) {

if (l != lyr && l.get('type') === 'base') {
alert(lyr);
l.setVisible(false);
}
});
}
};


I left the input/radio button implementation since it helps with debugging


And this is the "original" js file Original JS


What would I need to change to have a fully functional listbox? Or is there a better way to have a similar implementation that uses listboxs to change the layer?


thank you for your time





Aucun commentaire:

Enregistrer un commentaire