1

I am new to javascript and am playing around with customizing the CMV template https://github.com/cmv/cmv-app. I am trying to customize my info windows for my layers, and have had some luck modifying the identify.js file. I would like to use the same info window setup (fields and formatting) for more than one layer in my map service, but I can't figure out how to do that. I've tried to just add an array ([6,7]), and also tried adding a for loop to loop through the array with no luck. I don't get any errors, just no info windows load when I tried to use the array or loop through it:

msArray = [6,7];
for (var i = 0;  i < msArray.length; i++) {    define({map:!0,mapClickMode:!0,mapRightClickMenu:!0,identifyLayerInfos:!0,identifyTolerance:5,identifies:{
    mapSets:{msArray[i]:{title:"Map Sets",description: "<b>Name:</b>  {Sheet Label}<br><b>County:</b>  {County}<br><b>Route:</b>  {Route}<br><b>Postmile:</b>  {Postmile}<br><b>Map Type:</b>  {Map Type}\
    <br><b>Hanging File:</b>  {Hanging File}<br><b>Revision Date:</b>  {Revision Date}<br><b>Original Draft Decade:</b>  {Original Draft Decade}<br><b>Coordinate System:</b>  {Coordinate System} \
    <br><br><div align=center>{image_path}</div>"}};
}

Here's the code that works, when I reference one layer only (layer id in the code below is 6):

define({map:!0,mapClickMode:!0,mapRightClickMenu:!0,identifyLayerInfos:!0,identifyTolerance:5,identifies:{ 
mapSets:{6:{title:"Map Sets",description: "<b>Name:</b>  {Sheet Label}<br><b>County:</b>  {County}<br><b>Route:</b>  {Route}<br><b>Postmile:</b>  {Postmile}<br><b>Map Type:</b>  {Map Type}\
<br><b>Hanging File:</b>  {Hanging File}<br><b>Revision Date:</b>  {Revision Date}<br><b>Original Draft Decade:</b>  {Original Draft Decade}<br><b>Coordinate System:</b>  {Coordinate System} \
<br><br><div align=center>{image_path}</div>"}},

UPDATE: Latest code posted below, using function provided in solution. Second function does not work:

define(function () {

    function createSharedTemplateMS () {
        return {
            title:"Map Sets",
            description: [
                '<b>Name:</b>  {Sheet Label}<br>',
                '<b>County:</b>  {County}<br>',
                '<b>Route:</b>  {Route}<br>',
                '<b>Postmile:</b>  {Postmile}<br>',
                '<b>Map Type:</b>  {Map Type} <br>',
                '<b>Hanging File:</b>  {Hanging File}<br>',
                '<b>Revision Date:</b>  {Revision Date}<br>',
                '<b>Original Draft Decade:</b>  {Original Draft Decade}<br>',
                '<b>Coordinate System:</b>  {Coordinate System}<br><br>',
                '<div align=center>{image_path}</div>'
            ].join('')
         };
    }
    return {
        map:true,
        mapClickMode:true,
        mapRightClickMenu:true,
        identifyLayerInfos:true,
        identifyTolerance:5,
        identifies: {
            mapSets: {
                6: createSharedTemplateMS(),
                7: createSharedTemplateMS(),
                8: createSharedTemplateMS(),
                9: createSharedTemplateMS(),
                10: createSharedTemplateMS(),
                11: createSharedTemplateMS(),
                12: createSharedTemplateMS()
            }
        }
    };
});

define(function () {

    function createSharedTemplatePrcl () {
        return {
            title:"Parcels",
            description: [
                '<b>Name:</b>  {Name}<br>',
                '<b>County:</b>  {County}<br>',
                '<b>Route:</b>  {Route}<br>',
                '<b>Postmile:</b>  {Postmile}',
                '<br><b>Description:</b>  {Description}<br>',
                '<b>Area:</b>  {Area}<br>',
                '<b>Map Sheet:</b>  {Map Sheet}<br>',
                '<b>Parcel Type:</b>  {Parcel Type}<br>',
                '<b>Parcel Phase:</b>  {Parcel Phase}',
                '<br><b>Geometry Quality:</b>  {Geometry Quality}<br>',
                '<b>Source:</b>  {Source}<br><br>',
                '<br><div align=center>{doc_path}</div>'
            ].join('')
         };
    }
    return {
        map:true,
        mapClickMode:true,
        mapRightClickMenu:true,
        identifyLayerInfos:true,
        identifyTolerance:5,
        identifies: {
            mapSets: {
                1: createSharedTemplatePrcl(),
                2: createSharedTemplatePrcl(),
                3: createSharedTemplatePrcl(),
                4: createSharedTemplatePrcl()
            }
        }   
    };
});
  • Is this code for a single file? You can't combine them like that. Put the two functions side-by-side in the code I provided and combine your mapSets into a single object with sublayers 1 - 12 all in the same place. – tmcgee Oct 7 '14 at 20:13
  • Yes I have the code in the same file - I'm not sure exactly what you mean by side by side? – kflaw Oct 7 '14 at 22:12
  • I can't post the whole code here due to stackexchange limits on comment size. Here is your code reworked into something functional: pastebin.com/uCs0U8i7 – tmcgee Oct 8 '14 at 16:29
  • I'm trying to use one of the templates now for a feature layer also, but it won't work and I'm not sure why - it loads all fields in the info window for the feature service without the formatting. Or must I use a separate function? – kflaw Oct 28 '14 at 19:54
  • You should be able to use the same function for a feature layer. I believe you have found a bug that will be fixed in release 1.3.1 (due today or tomorrow). – tmcgee Oct 28 '14 at 21:01
2

First, when working with CMV, you should start with the unminified versions of the configuration files that will make it much easier to work with. The latest release is here.

With respect to your question, you can use a function to create the popup template. Here's an reformatted example of your code reusing the same template for 3 different sublayers - 2 for your mapSets layer and one for another layer. Obviously, you'll need to modify it for the layers in your CMV application.

define(function () {

    function createSharedTemplate () {
        return {
            title:"Map Sets",
            description: [
                '<b>Name:</b>  {Sheet Label}<br>',
                '<b>County:</b>  {County}<br>',
                '<b>Route:</b>  {Route}<br>',
                '<b>Postmile:</b>  {Postmile}<br>',
                '<b>Map Type:</b>  {Map Type} <br>',
                '<b>Hanging File:</b>  {Hanging File}<br>',
                '<b>Revision Date:</b>  {Revision Date}<br>',
                '<b>Original Draft Decade:</b>  {Original Draft Decade}<br>',
                '<b>Coordinate System:</b>  {Coordinate System} align=center>{image_path}'
            ].join('')
         };
    }

    return {
        map:true,
        mapClickMode:true,
        mapRightClickMenu:true,
        identifyLayerInfos:true,
        identifyTolerance:5,
        identifies: {
            mapSets: {
                6: createSharedTemplate(),
                7: createSharedTemplate()
            },
            layer2: {
                1: createSharedTemplate()
            }
        }
    };
});

One last thing, I used a trick of putting all the text for the description into multiple elements of an array. I find this easier to see each line of the HTML in the code. When doing that, it became obvious that you had an extra closing div tag </div> at the end of your code. I think that would explain the CSS problem I assisted you with on IRC.

  • thanks so much for the response this is very helpful! i have a ways to go in learning javascript – kflaw Oct 7 '14 at 15:11
  • this works great. I tried to create another function in the same js file that defines a popup for several other layers, but it doesn't work. I basically copied and pasted the above function below itself, then changed the function name and parameters. Not sure why it doesnt work – kflaw Oct 7 '14 at 19:55
  • can you post your current code? – tmcgee Oct 7 '14 at 19:57
  • posted code above – kflaw Oct 7 '14 at 20:03
2

I'm not familiar with CMV, there are a few JavaScript mistakes in your code if that's the exact code you're using.

Firstly, you cannot use a variable (myArray[i]) as a name for JSON object key. Please see this tutorial and this reference. You should've gotten an error for this, I would've guessed...

Secondly, you cannot put Dojo's define in a loop. You should only call define once per file.

Lastly, I believe you need to explicitly specify each layer you want to identify with specific fields you need. CMV documented as such:

// config object definition:
//  {<layer id>:{
//      <sub layer number>:{
//          <pop-up definition, see link below>
//          }
//      },
//  <layer id>:{
//      <sub layer number>:{
//          <pop-up definition, see link below>
//          }
//      }
//  }

// for details on pop-up definition see: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html

Familiarizing yourself better with JavaScript and Dojo basics will help you a lot in the long run when creating applications with ArcGIS JSAPI

As a side note, please format your code better in the question, we are not machines and cannot read compressed code very readily :)

Good luck!

  • thanks for the reply and tips. I tihnk it was not helping that the code I initially downloaded was not foramtted to begin with. – kflaw Oct 7 '14 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.