diff --git a/README.md b/README.md
index 0eb8825..13857b8 100644
--- a/README.md
+++ b/README.md
@@ -80,6 +80,10 @@ recursing nested groups.
|`fn`|`function`| Callback which will be called for each `ol.layer.Base` found under `lyr`. The signature for `fn` is the same as `ol.Collection#forEach` |
+##### `(static) ol.control.LayerSwitcher.uuid()`
+
+Generate a UUID
+
## License
MIT (c) Matt Walker.
diff --git a/src/ol3-layerswitcher.js b/src/ol3-layerswitcher.js
index 61e42e2..b2ab9d9 100644
--- a/src/ol3-layerswitcher.js
+++ b/src/ol3-layerswitcher.js
@@ -165,7 +165,7 @@ ol.control.LayerSwitcher.prototype.renderLayer_ = function(lyr, idx) {
var li = document.createElement('li');
var lyrTitle = lyr.get('title');
- var lyrId = lyr.get('title').replace(/\s+/g, '-') + '_' + idx;
+ var lyrId = ol.control.LayerSwitcher.uuid();
var label = document.createElement('label');
@@ -238,6 +238,19 @@ ol.control.LayerSwitcher.forEachRecursive = function(lyr, fn) {
});
};
+/**
+ * Generate a UUID
+ * @returns {String} UUID
+ *
+ * Adapted from http://stackoverflow.com/a/2117523/526860
+ */
+ol.control.LayerSwitcher.uuid = function() {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+}
+
/**
* @private
* @desc Apply workaround to enable scrolling of overflowing content within an
diff --git a/test/index.html b/test/index.html
index 6b2fdf4..0f7df32 100644
--- a/test/index.html
+++ b/test/index.html
@@ -22,6 +22,7 @@
+
diff --git a/test/spec/twomaps.js b/test/spec/twomaps.js
new file mode 100755
index 0000000..fb6b2a5
--- /dev/null
+++ b/test/spec/twomaps.js
@@ -0,0 +1,130 @@
+describe('ol.control.LayerSwitcher - Two maps', function() {
+ var map1, map2, target1, target2, switcher1, switcher2;
+
+ beforeEach(function() {
+ target1 = document.createElement('div');
+ target1.id = 'map1';
+ document.body.appendChild(target1);
+ target2 = document.createElement('div');
+ target2.id = 'map2';
+ document.body.appendChild(target2);
+ switcher1 = new ol.control.LayerSwitcher();
+ switcher2 = new ol.control.LayerSwitcher();
+ map1 = new ol.Map({
+ target: target1,
+ layers: [
+ new ol.layer.Group({
+ title: 'Base',
+ layers: [
+ new ol.layer.Tile({
+ title: 'Foo',
+ type: 'base',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ }),
+ new ol.layer.Tile({
+ title: 'Too',
+ type: 'base',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ })
+ ]
+ }),
+ new ol.layer.Tile({
+ title: 'Bar',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ }),
+ ],
+ controls: [switcher1]
+ });
+ map2 = new ol.Map({
+ target: target2,
+ layers: [
+ new ol.layer.Group({
+ title: 'Base',
+ layers: [
+ new ol.layer.Tile({
+ title: 'Foo',
+ type: 'base',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ }),
+ new ol.layer.Tile({
+ title: 'Too',
+ type: 'base',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ })
+ ]
+ }),
+ new ol.layer.Tile({
+ title: 'Bar',
+ source: new ol.source.TileDebug({
+ projection: 'EPSG:3857',
+ tileGrid: ol.tilegrid.createXYZ({
+ maxZoom: 22
+ })
+ })
+ }),
+ ],
+ controls: [switcher2]
+ });
+ });
+
+ afterEach(function() {
+ document.body.removeChild(target1);
+ document.body.removeChild(target2);
+ target1 = null;
+ target2 = null;
+ switcher1 = null;
+ switcher2 = null;
+ map1 = null;
+ map2 = null;
+ });
+
+ describe('Layer IDs are unique', function() {
+ it('Inputs for layers with the same title in different maps will have different IDs', function() {
+ switcher1.showPanel();
+ switcher2.showPanel();
+ var bar1Id = jQuery('#map1 .layer-switcher label:contains("Bar")').siblings('input').attr('id');
+ var bar2Id = jQuery('#map2 .layer-switcher label:contains("Bar")').siblings('input').attr('id');
+ expect(bar1Id).to.not.equal(bar2Id);
+ });
+ });
+
+ /**
+ * Returns the Layer instance that has the given title
+ */
+ function getLayerByTitle(map, title) {
+ var layer = null;
+ ol.control.LayerSwitcher.forEachRecursive(map, function(lyr) {
+ if (lyr.get('title') && lyr.get('title') === title) {
+ layer = lyr;
+ return;
+ }
+ });
+ return layer;
+ }
+
+});