I have a map service which is configured to have some layers visible at certain scale. The layerlist widget in the Web Appbuilder show all the sublayers with invisible layers greyed out. How do I configure/customize the layerlist widget so that invisible sublayers are not listed (scale dependent). Thanks
Solved! Go to Solution.
Helen,
That would involve changing a couple of files in the widget folder.
1. Widget.js:
_onZoomEnd: function() {
var layerInfoArray = [];
this.operLayerInfos.traversal(lang.hitch(this, function(layerInfo) {
layerInfoArray.push(layerInfo);
}));
var that = this;
setTimeout(function() {
var layerInfo = layerInfoArray.shift();
query("[class~='layer-title-div-" + layerInfo.id + "']", this.domNode)
.forEach(function(layerTitleDivIdDomNode) {
try {
if (layerInfo.isInScale()) {
html.removeClass(layerTitleDivIdDomNode, 'grayed-title');
} else {
html.addClass(layerTitleDivIdDomNode, 'grayed-title');
}
} catch (err) {
console.warn(err.message);
}
}, that);
//RJS Add
query("[class~='layer-tr-node-" + layerInfo.id + "']", this.domNode).forEach(function(layerTitleDivIdDomNode) {
try {
if (layerInfo.isInScale()) {
html.removeClass(layerTitleDivIdDomNode, 'not-in-scale');
} else {
html.addClass(layerTitleDivIdDomNode, 'not-in-scale');
}
} catch (err) {
console.warn(err.message);
}
}, that);
//RJS END ADD
if(layerInfoArray.length > 0) {
setTimeout(arguments.callee, 30); // jshint ignore:line
}
}, 30);
},
LayerListView.js:
addLayerNode: function(layerInfo, level, toTableNode, position) {
var layerTrNode, layerTdNode, ckSelectDiv, ckSelect, imageNoLegendDiv, handle,
imageNoLegendNode, popupMenuNode, i, imageShowLegendDiv, divLabel;
var rootLayerInfo = layerInfo.getRootLayerInfo();
// if(!this._layerNodeHandles[rootLayerInfo.id]) {
// this._layerNodeHandles[rootLayerInfo.id] = [];
// }
// init _layerDomNodeStorage for rootLayerInfo.
if(layerInfo.isRootLayer() || layerInfo.isTable) {
this._layerDomNodeStorage[layerInfo.getObjectId()] = {
layerTrNode: null,
layerContentTrNode: null,
layerNodeEventHandles: [],
layerNodeReferredDijits: []
};
}
//RJS ADD/change
var sdClass = '';
try {
if (!layerInfo.isInScale()) {
sdClass = 'not-in-scale';
}
} catch (err) {
console.warn(err.message);
}
var layerTrNodeClass = "layer-tr-node-" + layerInfo.id;
layerTrNode = domConstruct.create('tr', {
'class': 'jimu-widget-row layer-row ' + sdClass +
( /*visible*/ false ? 'jimu-widget-row-selected ' : ' ') + layerTrNodeClass ,
'layerTrNodeId': layerInfo.id
});
domConstruct.place(layerTrNode, toTableNode, position);
//RJS END
....
},
style.css add this rule to the end of the file:
.jimu-widget-layerList .not-in-scale {
display: none;
}
Helen,
That would involve changing a couple of files in the widget folder.
1. Widget.js:
_onZoomEnd: function() {
var layerInfoArray = [];
this.operLayerInfos.traversal(lang.hitch(this, function(layerInfo) {
layerInfoArray.push(layerInfo);
}));
var that = this;
setTimeout(function() {
var layerInfo = layerInfoArray.shift();
query("[class~='layer-title-div-" + layerInfo.id + "']", this.domNode)
.forEach(function(layerTitleDivIdDomNode) {
try {
if (layerInfo.isInScale()) {
html.removeClass(layerTitleDivIdDomNode, 'grayed-title');
} else {
html.addClass(layerTitleDivIdDomNode, 'grayed-title');
}
} catch (err) {
console.warn(err.message);
}
}, that);
//RJS Add
query("[class~='layer-tr-node-" + layerInfo.id + "']", this.domNode).forEach(function(layerTitleDivIdDomNode) {
try {
if (layerInfo.isInScale()) {
html.removeClass(layerTitleDivIdDomNode, 'not-in-scale');
} else {
html.addClass(layerTitleDivIdDomNode, 'not-in-scale');
}
} catch (err) {
console.warn(err.message);
}
}, that);
//RJS END ADD
if(layerInfoArray.length > 0) {
setTimeout(arguments.callee, 30); // jshint ignore:line
}
}, 30);
},
LayerListView.js:
addLayerNode: function(layerInfo, level, toTableNode, position) {
var layerTrNode, layerTdNode, ckSelectDiv, ckSelect, imageNoLegendDiv, handle,
imageNoLegendNode, popupMenuNode, i, imageShowLegendDiv, divLabel;
var rootLayerInfo = layerInfo.getRootLayerInfo();
// if(!this._layerNodeHandles[rootLayerInfo.id]) {
// this._layerNodeHandles[rootLayerInfo.id] = [];
// }
// init _layerDomNodeStorage for rootLayerInfo.
if(layerInfo.isRootLayer() || layerInfo.isTable) {
this._layerDomNodeStorage[layerInfo.getObjectId()] = {
layerTrNode: null,
layerContentTrNode: null,
layerNodeEventHandles: [],
layerNodeReferredDijits: []
};
}
//RJS ADD/change
var sdClass = '';
try {
if (!layerInfo.isInScale()) {
sdClass = 'not-in-scale';
}
} catch (err) {
console.warn(err.message);
}
var layerTrNodeClass = "layer-tr-node-" + layerInfo.id;
layerTrNode = domConstruct.create('tr', {
'class': 'jimu-widget-row layer-row ' + sdClass +
( /*visible*/ false ? 'jimu-widget-row-selected ' : ' ') + layerTrNodeClass ,
'layerTrNodeId': layerInfo.id
});
domConstruct.place(layerTrNode, toTableNode, position);
//RJS END
....
},
style.css add this rule to the end of the file:
.jimu-widget-layerList .not-in-scale {
display: none;
}
Hi Robert:
This code is great and it did work although did not work whenever I expanded a layer to see the icon symbology and left it expanded prior to zooming in or zooming out. Can this be easily rectified? See photos below. One photo shows the icon symbology of an expanded layer that is no longer visible in the map. The other photo shows no icon symbology and no layer name for the same layer that is no longer visible in the map if the icon symbology was not expanded prior to zooming in or zooming out.
I tried adding the text "html.addClass(contentDomNode, 'not-in-scale'); " and "html.removeClass(contentDomNode, 'not-in-scale'); " to the widget.js as seen below although it did not work.
{ html.addClass(layerTitleDivIdDomNode, 'not-in-scale'); html.addClass(contentDomNode, 'not-in-scale');
I also tried adding .jimu-widget-layerList .not-in-scale .esriLegendLayer {display: none;} to the css and that also did not work. I was not sure how to change the LayerListView.js or if it was needed at all.
It looks like this same type of logic needs to be applied to the layercontentnodeid
Robert,
It works. Thanks so much.
Helen