Capuring setVisibleLayers() on-complete?

757
5
Jump to solution
05-17-2011 02:00 AM
AlistairDorman-Smith
New Contributor
Hi

I'm using some code from the ESRI examples for toggling the layer visiblity. It works well.

function updateLayerVisibility() {
var inputs = dojo.query(".list_item"), input;
visible = [];
for (var i=0, il=inputs.length; i<il; i++) {
   if (inputs.checked) {
  visible.push(inputs.id);
   }
}
dynamicLayer.setVisibleLayers(visible);
}

However, I have some layers which are slow to load - maybe take a couple of seconds. They are slow as they contain a lot of data and we've optimised as much as we can for now.

Is there a way to capture when the setVisibleLayers() has completed? It would be nice to know when it's completed so I can have a "loading" message.

I've had a look on the ESRI API Reference, but there doesn't seem to be a mention of such functionality. Can anyone help?
0 Kudos
1 Solution

Accepted Solutions
HemingZhu
Occasional Contributor III
Hi

Thanks for that.
I've been experimenting with putting this into the code, but so far, not got it working. I'm not entirely clear where I need to put it.

I'm basically using code very similar to this example here:
http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/map_dynamiclay...

How would you suggest it can be incorporated into this example?

I've tried putting:
dojo.connect(dynamicLayer, "onVisibilityChange",handleVisibilityChange);
within the init() function, and I've also tried putting it just before
map.addLayer(layer)
within the buildLayerList function (swapping the first parameter to just be "layer").

My handleVisibilityChange() function is never called.

I could be doing something very wrong here, so advice on how to get this working would be great!

Thanks.


My mistake! onVisibilityChange fire when the layer's visible property change, not for the visibility of the sublayers. Use layer onUpdateStart and onUpdateEnd to handle your situation. I added some code to the sample you mentioned. Try it to see if it works for you. here is the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Dynamically Create Map Service Layer List</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.3/js/dojo/dijit/themes/claro/claro.css">
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.3"></script>

    <script type="text/javascript">

      dojo.require("esri.map");

      var layer, map, visible = [];

      function init() {
        loading = dojo.byId("loadingImg");  //loading image. id
        map = new esri.Map("map");
        layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/Map...");

        if (layer.loaded) {
          buildLayerList(layer);
        }
        else {
          dojo.connect(layer, "onLoad", buildLayerList);
        }
      }

      function buildLayerList(layer) {
        var items = dojo.map(layer.layerInfos,function(info,index){
          if (info.defaultVisibility) {
            visible.push(info.id);
          }
          return "<input type='checkbox' class='list_item' checked='" + (info.defaultVisibility ? "checked" : "") + "' id='" + info.id + "' onclick='updateLayerVisibility();' /><label for='" + info.id + "'>" + info.name + "</label>";
        });

        dojo.byId("layer_list").innerHTML = items.join();

        layer.setVisibleLayers(visible);
        map.addLayer(layer);
        dojo.connect(layer, "onUpdateStart", showLoading);
        dojo.connect(layer, "onUpdateEnd", hideLoading);

      }
      function showLoading() {
          esri.show(loading);
      }

      function hideLoading(error) {
          esri.hide(loading);
      }

      function updateLayerVisibility() {
        var inputs = dojo.query(".list_item"), input;
   
        visible = [];

        dojo.forEach(inputs,function(input){
          if (input.checked) {
              visible.push(input.id);
          }
          });
        //if there aren't any layers visible set the array to be -1
        if(visible.length === 0){
          visible.push(-1);
        }
        layer.setVisibleLayers(visible);
      }

      dojo.addOnLoad(init);

    </script>


  </head>

  <body>
    This sample loads an ArcGISDynamicMapServiceLayer.<br />
    It determines the layers in the map service and presents them as checkboxes that can be used to toggle their visibility.<br />
    <br />
    Layer List : <span id="layer_list"></span><br />
    <br />
    <div id="map" class="claro" style="width:600px; height:400px; border:1px solid #000;">
        <img id="loadingImg" src="images/loading.gif" style="position:absolute; right:300px; top:200px; z-index:100;" />
    </div>
  </body>
</html>

View solution in original post

0 Kudos
5 Replies
HemingZhu
Occasional Contributor III
Hi

I'm using some code from the ESRI examples for toggling the layer visiblity. It works well.

function updateLayerVisibility() {
var inputs = dojo.query(".list_item"), input;
visible = [];
for (var i=0, il=inputs.length; i<il; i++) {
   if (inputs.checked) {
  visible.push(inputs.id);
   }
}
dynamicLayer.setVisibleLayers(visible);
}

However, I have some layers which are slow to load - maybe take a couple of seconds. They are slow as they contain a lot of data and we've optimised as much as we can for now.

Is there a way to capture when the setVisibleLayers() has completed? It would be nice to know when it's completed so I can have a "loading" message.

I've had a look on the ESRI API Reference, but there doesn't seem to be a mention of such functionality. Can anyone help?


Look into esri.layers.Layer.onVisibilityChange event. It's on http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi/layer.htm#onVisibilityChange
0 Kudos
AlistairDorman-Smith
New Contributor
Hi

Thanks for that.
I've been experimenting with putting this into the code, but so far, not got it working. I'm not entirely clear where I need to put it.

I'm basically using code very similar to this example here:
http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/map_dynamiclay...

How would you suggest it can be incorporated into this example?

I've tried putting:
dojo.connect(dynamicLayer, "onVisibilityChange",handleVisibilityChange);
within the init() function, and I've also tried putting it just before
map.addLayer(layer)
within the buildLayerList function (swapping the first parameter to just be "layer").

My handleVisibilityChange() function is never called.

I could be doing something very wrong here, so advice on how to get this working would be great!

Thanks.
0 Kudos
HemingZhu
Occasional Contributor III
Hi

Thanks for that.
I've been experimenting with putting this into the code, but so far, not got it working. I'm not entirely clear where I need to put it.

I'm basically using code very similar to this example here:
http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/map_dynamiclay...

How would you suggest it can be incorporated into this example?

I've tried putting:
dojo.connect(dynamicLayer, "onVisibilityChange",handleVisibilityChange);
within the init() function, and I've also tried putting it just before
map.addLayer(layer)
within the buildLayerList function (swapping the first parameter to just be "layer").

My handleVisibilityChange() function is never called.

I could be doing something very wrong here, so advice on how to get this working would be great!

Thanks.


My mistake! onVisibilityChange fire when the layer's visible property change, not for the visibility of the sublayers. Use layer onUpdateStart and onUpdateEnd to handle your situation. I added some code to the sample you mentioned. Try it to see if it works for you. here is the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Dynamically Create Map Service Layer List</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.3/js/dojo/dijit/themes/claro/claro.css">
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.3"></script>

    <script type="text/javascript">

      dojo.require("esri.map");

      var layer, map, visible = [];

      function init() {
        loading = dojo.byId("loadingImg");  //loading image. id
        map = new esri.Map("map");
        layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/Map...");

        if (layer.loaded) {
          buildLayerList(layer);
        }
        else {
          dojo.connect(layer, "onLoad", buildLayerList);
        }
      }

      function buildLayerList(layer) {
        var items = dojo.map(layer.layerInfos,function(info,index){
          if (info.defaultVisibility) {
            visible.push(info.id);
          }
          return "<input type='checkbox' class='list_item' checked='" + (info.defaultVisibility ? "checked" : "") + "' id='" + info.id + "' onclick='updateLayerVisibility();' /><label for='" + info.id + "'>" + info.name + "</label>";
        });

        dojo.byId("layer_list").innerHTML = items.join();

        layer.setVisibleLayers(visible);
        map.addLayer(layer);
        dojo.connect(layer, "onUpdateStart", showLoading);
        dojo.connect(layer, "onUpdateEnd", hideLoading);

      }
      function showLoading() {
          esri.show(loading);
      }

      function hideLoading(error) {
          esri.hide(loading);
      }

      function updateLayerVisibility() {
        var inputs = dojo.query(".list_item"), input;
   
        visible = [];

        dojo.forEach(inputs,function(input){
          if (input.checked) {
              visible.push(input.id);
          }
          });
        //if there aren't any layers visible set the array to be -1
        if(visible.length === 0){
          visible.push(-1);
        }
        layer.setVisibleLayers(visible);
      }

      dojo.addOnLoad(init);

    </script>


  </head>

  <body>
    This sample loads an ArcGISDynamicMapServiceLayer.<br />
    It determines the layers in the map service and presents them as checkboxes that can be used to toggle their visibility.<br />
    <br />
    Layer List : <span id="layer_list"></span><br />
    <br />
    <div id="map" class="claro" style="width:600px; height:400px; border:1px solid #000;">
        <img id="loadingImg" src="images/loading.gif" style="position:absolute; right:300px; top:200px; z-index:100;" />
    </div>
  </body>
</html>
0 Kudos
StephenLead
Regular Contributor III
Is there a way to capture when the setVisibleLayers() has completed? It would be nice to know when it's completed so I can have a "loading" message.


You could also listen for the map.onUpdateStart and map.OnUpdateEnd events, rather than listening to an individual layer:

onUpdateStart()
Fires when one or more layers being updating their content. This event is often used in combination with onUpdateEnd to display a "Map is busy" or "Loading? " message as visual feedback to the end-user. (As of v2.2)

See the sample at http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/map_showloadin...
0 Kudos
AlistairDorman-Smith
New Contributor
Thanks to you both for this help.

I have now got this working which is great. I've found that the "loading" message appears no matter whether I'm loading the map, panning, or toggling layer which is ok, although it's really the toggling layer aspect I'm interested in.

I've added the event listeners to the buildLayerList() function and don't quite see a way to only fire them when you toggle a layer on and off, but in many ways that's not a major issue.

I suppose it's helpful to the user to see when something is loading at any stage of the application.

Thanks again for your help.
0 Kudos