Select to view content in your preferred language

Dynamically set fieldinfos in popup template discussion

5188
4
02-26-2014 12:55 PM
RuchiraWelikala
Regular Contributor
I want to create a certain function to streamline some of my customization work.

I work with a web app that's built using ArcGIS JavaScript API which contains a few layers.

Each layer is configured to an identity task that uses a popup template to display attribute information from the layer.

Now, there are lots of attributes PER layer that I manually configure up in the popup template declaration.

Ex.
    var popupContent = {
 title: "Business ID#: {UNIQUEID_1}",
 fieldInfos: [
 {fieldName: "BUSNAME_1", visible: true, label:"Business Name: "},
 {fieldName: "Standard_Name", visible: true, label:"Standard Name: "},
 {fieldName: "LATITUDE_1", visible: true, label:"Latitude: "},
 {fieldName: "LONGITUDE_1", visible: true, label:"Longitude: "},
 {fieldName: "INFO_EMP_1", visible: true, label:"Employment Info: "},
 {fieldName: "Est_Employment", visible: true, label:"Estimated Employment: "},
 {fieldName: "INFO_SAL_1", visible: true, label:"Salary Info: "},
 {fieldName: "Est_Revenue", visible: true, label:"Estimated Revenue: "},
 {fieldName: "PRMSIC4_1", visible: true, label:"Primary SIC: "},
 {fieldName: "NAICS_1", visible: true, label:"NAICS: "},
 {fieldName: "NAICS4_1", visible: true, label:"NAICS 4 Code: "},
 {fieldName: "NAICS4DESC_1", visible: true, label:"NAICS 4 Desc.: "},
 {fieldName: "NAICS2_1", visible: true, label:"NAICS 2 Code: "},
 {fieldName: "NAICS2DESC_1", visible: true, label:"NAICS 2 Desc.: "},
 {fieldName: "Use_Type", visible: true, label:"Use Type: "},
 {fieldName: "UseSubcategory", visible: true, label:"Use Subcategory: "},
 {fieldName: "UseCategory", visible: true, label:"Use Category: "}
 ]
    };

This is one of the shorter templates that i use, but as you can see, it gets pretty tedious to set these manually. Once in a while is okay, but the layers are constantly getting fields added/removed.

I was wondering if any of you had any clever ideas as to how I could automate this.

One possible way I was thinking is to have a table in my ArcGIS server that acts as a lookup table for the fields.
Table structure:

1. The column field names in this table will be the "Layername_fieldname" and "LayerName_label" of the layers in my web app (from the layers' corresponding attribute tables).

Ex.

    || Layer1_fieldname || Layer1_label || Layer2_fieldname || Layer2_label ||
    --------------------------------------------------------------------------
    || BusinessLoc      || Biz Location:|| CountyBoundary   || County Name: ||
    ||                  ||              ||                  ||              ||



2. Rows can be added or deleted as needed to each column as my web app layers grow or shrink in attribute size.

Basically, I want to know if this is a viable option or if there are other methods out there to perform this task. If this is a good solution, is it possible to query the field lookup table and use those values in my popup template constructor.

Any help or ideas would be greatly appreciated.

Thanks!
0 Kudos
4 Replies
BenFousek
Deactivated User
One way is to make a request to the layer's endpoint and retrieve the layer's info, then iterate through the fields to add fieldInfo object for each field. I add result to the corresponding layerInfo as the info object. That way if I want it again I don't need to make a request. This is especially handy for an app with several classes and widgets that may need layer info.
function createPopupContent(layer, layerId) {
  esriRequest({
    url: layer.url + '/' + layerId,
    content: {
      f: 'json'
      token: layer._getToken()
    },
    handleAs: 'json',
    callbackParamName: 'callback'
  }).then(function (r) {
    layer.layerInfos[layerId].info = r; //add result to layer's LayerInfo
    var popupContent = {
      title: 'Business ID#: {UNIQUEID_1}',
      fieldInfos: []
    };
    array.forEach(r.fields, function (field) {
      if (field.type !== 'esriFieldTypeOID' && field.type !== 'esriFieldTypeGeometry' && field.type !== 'esriFieldTypeBlob' && field.type !== 'esriFieldTypeRaster' && field.type !== 'esriFieldTypeGUID' && field.type !== 'esriFieldTypeGlobalID' && field.type !== 'esriFieldTypeXML') {
        popupContent.fieldInfos.push({
          fieldName: field.name,
          visible: true,
          label: field.alias + ': '
        });
      }
    });
    return popupContent;
  }, function (e) {
    console.log(e);
  });
}
0 Kudos
RuchiraWelikala
Regular Contributor
Thanks for this! This would still require me having the field LABEL (the label that actually appears on the popup) in the actual service, layer right? Rather than have it be in a separate table itself.
0 Kudos
BenFousek
Deactivated User
Yes. The example uses the field alias from the data's attribute table.

Details like setting field aliases, field descriptions, service description, etc make developing much easier. Heck I use document info, service tags, layer description, etc to store additional info (stringified json) for parameters used by my custom classes for creating TOC, query/identify params, editing params, etc so I don't have to do it in the app. Something I've been doing lately is using a published service with tables to store and retrieve json for layer and task specific parameters. I'm hoping to get started on a table with all of my most used esri graphics symbol json soon. AGS rocks!

I have control over most of data and services I work with. If you don't, there's not much you can do. I've made suggestions to couple fed agencies with AGS I use to improve the usefulness of their services with field aliases and layer descriptions, but so far no luck.
0 Kudos
RuchiraWelikala
Regular Contributor
Haha, I'm falling in love with AGS too. The end point offers so much that we take for granted and typically go unused.

I have full control over all of the layers/services so everything can be modified. But I don't want to modify the layers in places.
Plus, I want to make this easy for interns to modify with new field information as it becomes available. I figured setting up a separate table would be the easiest, but I will give your method a go and see what it churns out! Really appreciate your help!
0 Kudos