Esri / storymap-shortlist

The Shortlist story map application template by Esri
http://storymaps.arcgis.com/en/app-list/shortlist/
Apache License 2.0
43 stars 61 forks source link

custom-scripts.js seems to be executed before the page is fully loaded #88

Closed scMarth closed 6 years ago

scMarth commented 6 years ago

Hello, I am trying to write code to hide location markers for a certain tab (the tab contains information about a general area, so it wouldn't make sense to have specific locations for them)

Here is what my custom-scripts looks like:

` define(["dojo/topic"], function(topic) { /*

`

The on-click function works as expected, but it seems that when $('#map_gc > g:nth-child(2) > image').remove(); is called, the map is still loading. Is there a better place to put this line of code? I am having trouble finding the right place to put it.

cooney commented 6 years ago

Try hooking into the map's load event (https://developers.arcgis.com/javascript/3/jsapi/map-amd.html#event-load). You can reference the map used in the Shortlist app with 'app.map'.

scMarth commented 6 years ago

Thanks for the reply. I added an on load function but it doesn't seem to fire. I may be doing something wrong though:

// The application is ready

topic.subscribe("tpl-ready", function(){
    /*
    * Custom Javascript to be executed when the application is ready goes here
    */

  app.map.on("load", function(){
     console.log("Hello, the map has been loaded");
     console.log($('#map_gc > g:nth-child(2) > image'));
     $('#map_gc > g:nth-child(2) > image').remove();
  });

  // Everytime the Overview tab is clicked, hide the location markers
  $('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs').click(function(event) {
     if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1)')){
        $('#map_gc > g:nth-child(2) > image').remove();
     }else if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1) > .entryLbl')){
        $('#map_gc > g:nth-child(2) > image').remove();
     }else{
        return;
     }
  });
});

cooney commented 6 years ago

Try: if (app.map.loaded) { console.log("map is loaded") } else { app.map.on('load', function() { console.log("MAP READY"); }); }

scMarth commented 6 years ago

Thanks for the suggestion. I tried it and I get

map is loaded p.fn.init [prevObject: p.fn.init(1), context: document, selector: "#map_gc > g:nth-child(2) > image"]

in the console. However, the location markers are still there.

This is my code:

// The application is ready
topic.subscribe("tpl-ready", function(){
   /*
   * Custom Javascript to be executed when the application is ready goes here
   */

   if (app.map.loaded){
      console.log("map is loaded")
      console.log($('#map_gc > g:nth-child(2) > image'));
      $('#map_gc > g:nth-child(2) > image').remove();
   }else{
      app.map.on('load', function(){
         console.log("MAP READY");
         console.log($('#map_gc > g:nth-child(2) > image'));
         $('#map_gc > g:nth-child(2) > image').remove();
      });
   }

   // Everytime the Overview tab is clicked, hide the location markers
   $('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs').click(function(event) {
      if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1)')){
         console.log('tab clicked');
         console.log($('#map_gc > g:nth-child(2) > image'));
         $('#map_gc > g:nth-child(2) > image').remove();
      }else if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1) > .entryLbl')){
         console.log('tab clicked');
         console.log($('#map_gc > g:nth-child(2) > image'));
         $('#map_gc > g:nth-child(2) > image').remove();
      }else{
         return;
      }
   });
});

If I click on the first tab I get:

tab clicked

p.fn.init(5) [image, image, image, image, image, prevObject: p.fn.init(1), context: document, selector: "#map_gc > g:nth-child(2) > image"]

This time, printing out the results of the same selector in the console log will show the images (location markers), and the location markers are removed as expected. It seems that the location markers are loaded into the map after app.map.loaded becomes true

scMarth commented 6 years ago

I tried testing app.map.graphics.loaded as well, still no luck

      if (app.map.graphics.loaded){
         console.log("map graphics loaded");
         console.log($('#map_gc > g:nth-child(2) > image'));
         $('#map_gc > g:nth-child(2) > image').remove();
      }else{
         app.map.graphics.on('load', function(){
            console.log("MAP GRAPHICS READY");
            console.log($('#map_gc > g:nth-child(2) > image'));
            $('#map_gc > g:nth-child(2) > image').remove();
         });
      }
cooney commented 6 years ago

You can try with the graphic layer's update-end event: https://developers.arcgis.com/javascript/3/jsapi/layer-amd.html#event-update-end.

And probably better to use the Esri JS API to manage your graphics: https://developers.arcgis.com/javascript/3/jsapi/graphic-amd.html

scMarth commented 6 years ago

Good idea, thanks for the tip.

No luck with the graphic layer's update-end or update events. Code that I attach to these events will fire but the location markers still haven't been loaded at these points.

cooney commented 6 years ago

This works for me: var slLayer = app.map.getLayer(app.data.getShortlistLayerId()); if(slLayer.updating){ slLayer.on("update-end", function() { console.log("Layer done updating"); slLayer.hide(); }) } else { console.log("Layer already updated"); slLayer.hide(); }

scMarth commented 6 years ago

Thanks. I was able to accomplish what I wanted


define(["dojo/topic"], function(topic) {
   /*
   * Custom Javascript to be executed while the application is initializing goes here
   */

   // The application is ready
   topic.subscribe("tpl-ready", function(){
      /*
      * Custom Javascript to be executed when the application is ready goes here
      */

      var slLayer = app.map.getLayer(app.data.getShortlistLayerId());

      function hideFirstTabLocationMarkers(){
         for (var i=0; i<slLayer.graphics.length; i++){
            if (slLayer.graphics[i].attributes.tab_id == 0)
               slLayer.graphics[i].hide();
         }
      }

      if (slLayer.updating)
         slLayer.on("update-end", hideFirstTabLocationMarkers);
      else
         hideFirstTabLocationMarkers();

      // (DESKTOP) Everytime the Overview tab is clicked, hide the location markers
      $('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs').click(function(event) {
         if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1)'))
            hideFirstTabLocationMarkers();
         else if ($(event.target).is('#nav-bar > div.nav-bar.isTab > div.entries > ul.nav.nav-tabs > .entry:nth-child(1) > .entryLbl'))
            hideFirstTabLocationMarkers();
      });

      // (MOBILE) Everytime the Overview tab is navigated to, hide the location markers
      $('#mobileThemeBar').click(function(event) {
         if ($(event.target).is('#mobileThemeBar > #navThemeLeft'))
            hideFirstTabLocationMarkers();
         else if ($(event.target).is('#mobileThemeBar > #navThemeLeft > div.detail-btn.ion-chevron-left'))
            hideFirstTabLocationMarkers();
         else if ($(event.target).is('#mobileThemeBar > #navThemeLeft > div.detail-btn.ion-chevron-left::before'))
            hideFirstTabLocationMarkers();
      });

   });
});