Get Styles for Feature Layer in Feature Collection, Customize Layer List

6694
16
Jump to solution
04-01-2016 12:34 PM
JugalPatel
New Contributor II

Hey everyone, so I'm using the JavaScript API to customize an ArcGIS web app and I need to take feature layers and group them in the layer list widget. Here's the code I have that does that: Customize Layer List Widget for ArcGIS Web App Builder · GitHub

I can do this through the addFeatureCollection method, but when I create new groups, the feature layers in the groups don't pull in their styles and symbology. Another issue is that when I take my original feature layers and then group them into feature collections, the layer list widget shows both the grouped feature collections, and the original feature layers. Here's what my app is looking like with the code as is.

Here's an ungrouped feature layer that's pulling in styles correctly: Feature layers with styles.png

And here's a grouped feature collection layer that isn't pulling in it's styles:

Feature collection without styles.png

Does anyone know how I can get the styles for my feature layers and have the layer list widget not display the individual, ungrouped feature layers, but only the feature collections?

0 Kudos
16 Replies
JugalPatel
New Contributor II

Ohhh ok, I understand now. The feature layers I've been accessing aren't actually part of the web map. They were just the layers alone. I do have those layers already in the web map though, and I need to access and group them into feature collections.

Lines 11, 15, 21, 24, 30, and 33 in the code are where I'm accessing the separate feature layers, creating new instances of the feature layer objects (on top of the ones I already have), and then storing them into variables that can be grouped into a collection. Instead I'll need to call the layers I already have in the json of my web map instead of pulling in new layers. Do you know how I can do that? Thanks so much for your help by the way!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jugal,

  If you already have the layer in the web map and you just want to group them, then your code would look like this:

startup: function() {
        this.inherited(arguments);
        NlsStrings.value = this.nls;
        // summary:
        //    this function will be called when widget is started.
        // description:
        //    according to webmap or basemap to create LayerInfos instance
        //    and initialize operLayerInfos;
        //    show layers list;
        //    bind events for layerLis;

        if (this.map.itemId) {
          LayerInfos.getInstance(this.map, this.map.itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              var thirdFloorLayers = [];
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                //this is where I am searching for specific layers using their title
                if(layerInfo && layerInfo.title.substr(0, 7) === "Highway"){
                  thirdFloorLayers.push(layerInfo.layerObject);
                  this.map.removeLayer(layerInfo.layerObject);
                }
              }, this);
              this.operLayerInfos.addFeatureCollection(thirdFloorLayers, "3rd Floor");
              this.showLayers();
              this.bindEvents();
              dom.setSelectable(this.layersSection, false);
            }));
        } else {
          var itemInfo = this._obtainMapLayers();
          LayerInfos.getInstance(this.map, itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              this.showLayers();
              this.bindEvents();
              dom.setSelectable(this.layersSection, false);
            }));
        }
      },
JugalPatel
New Contributor II

Robert, this is great, thanks so much! I've got it working now.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jugal,

  I don't know about the layer order, you are going to have to figure that one out but the layer title is simple:

Here is your code optimized and fixed for the layer title.

Don't forget to mark this question as answered and replies as helpful if you thought they were.

startup: function() {
        this.inherited(arguments);
        NlsStrings.value = this.nls;
        // summary:
        //    this function will be called when widget is started.
        // description:
        //    according to webmap or basemap to create LayerInfos instance
        //    and initialize operLayerInfos;
        //    show layers list;
        //    bind events for layerList;

        if (this.map.itemId) {
          LayerInfos.getInstance(this.map, this.map.itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              
              //begin grouping feature layers for rooms and labels
              var firstFloorLayers = [], secondFloorLayers = [], thirdFloorLayers = [];
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                //get the original layer title and add it to the new sublayer title
                layerInfo.layerObject.title = layerInfo.title;
                if(layerInfo && layerInfo.title.substr(0, 5) === "First"){
                  firstFloorLayers.push(layerInfo.layerObject);
                  this.map.removeLayer(layerInfo.layerObject);
                }
                if(layerInfo && layerInfo.title.substr(0, 5) === "Secon"){
                  secondFloorLayers.push(layerInfo.layerObject);
                  this.map.removeLayer(layerInfo.layerObject);
                }
  if(layerInfo && layerInfo.title.substr(0, 5) === "Third"){
                  thirdFloorLayers.push(layerInfo.layerObject);
                  this.map.removeLayer(layerInfo.layerObject);
                }
              }, this);  
              this.operLayerInfos.addFeatureCollection(firstFloorLayers, "1st Floor");
              this.operLayerInfos.addFeatureCollection(secondFloorLayers, "2nd Floor");
              this.operLayerInfos.addFeatureCollection(thirdFloorLayers, "3rd Floor");
              // end of code to group layers
              
              this.showLayers();
              this.bindEvents();
              dom.setSelectable(this.layersSection, false);
            }));
        } else {
          var itemInfo = this._obtainMapLayers();
          LayerInfos.getInstance(this.map, itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              this.showLayers();
              this.bindEvents();
              dom.setSelectable(this.layersSection, false);
            }));
        }
      },
JugalPatel
New Contributor II

Hey Robert,

Thanks for helping out again. Just a quick question: the layers I'm using that are attached to the web map are for rooms and for the labels of the rooms. Those are the layers we grouped into feature collections. The labels don't resize for the layers that are attached to the web map however, but this layer (which isn't attached) does have labels that resize: http://geovis01.ts.odu.edu/odugis/rest/services/Test/SM_Rooms_P_4_1/FeatureServer/0 https://orgsync.com/55669/forms/193744/

Do you know how I can use that layer instead? The last and final thing I'm trying to get done is just to have the labels resize in accordance with the map's zoom.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jugal,

Sounds like you need to edit your web map and add that layer instead of the other label layer then.

SuzanneLiebergen1
New Contributor II

This is very helpful and with your code example, I was able to group my layers into a feature collection. I would like to have each of the layers in the feature collection group turn on upon turning on the feature collection group name ("Prowl Line" in the image below). I'm a bit stuck, but think I need to use the _onLayreInfosIsVisibleChanged section of the widget.js code

0 Kudos