Format infoTemplate content with custom function

3792
11
Jump to solution
09-24-2013 09:27 AM
RyanClancy
Occasional Contributor
I'm trying to format the value of a field for display in an infoTemplate but nothing is happening; it appears as though the function is not being called. I used the example here as a guide, see the compare() function.

I simply want to format the text to display either Gbps or Tbps based on the value of the field. The relevant field is called "Capacity_G" and I put the console.log statements in there to test whether the function was executing; it is not.

var infoTemplate = new InfoTemplat(); infoTemplate.setTitle("<b>Cable: ${NAME}</b>"); infoTemplate.setContent("Capacity: ${CAPACITY_G:formatCapacity}");  function formatCapacity(value){     console.log("LALALALALAA");     var cap = "";     //1Tb = 1024Gb     if (value >= 1024){         cap = value/1024 + "Tbps";     }     else {         cap = value + "Mbps";     }     console.log("LALALALALALALA");     return cap; }


What have I done wrong? The text in the resulting popup appears unmodified, exactly as it is in the attributes of the data.
0 Kudos
1 Solution

Accepted Solutions
derekswingley1
Frequent Contributor
Are you using 3.7? graphic.attr() was introduced at 3.7 (we'll update the docs to say this).

Attr is also used to add attributes to a graphic's DOM node, it doesn't affect graphic.attributes (which I admit is confusing). If you want to add to or update a graphic.attributes, modify that object directly.

View solution in original post

0 Kudos
11 Replies
derekswingley1
Frequent Contributor
In the sample you linked to, the formatting function is in the global scope. To get your formatting function to run, make it a global (or a property on some global object).
0 Kudos
RyanClancy
Occasional Contributor
In the sample you linked to, the formatting function is in the global scope. To get your formatting function to run, make it a global (or a property on some global object).


Yep, that was it. Works perfectly now. Thanks!
0 Kudos
RyanClancy
Occasional Contributor
It seems I'm having another issue of scope on this same topic. I've updated my code to use dojo/ready and instead of the base infoWindow I'm now using a Popup. My formatting function is no longer being called. Is this a problem of scope or something to do with the Popup vs base infoWindow? Initially the formatCapacity() function was inside the ready(function(){*in here*}) as a global function but when it didn't work I moved it outside of the ready(). Either way it is not called. Everything else works.

require([
    "esri/map",
    "esri/dijit/Popup",
    "esri/dijit/PopupTemplate",
    "dojo/ready",
    etc.....
    ....
] , function(
    Map,
    Popup,
    PopupTemplate,
    ready,
    etc...
    ....
) {
   function formatCapacity(value){
       console.log("Formatting function is called");
   }
   ready(function(){
       .....
       .....
       var popupTemplate = new PopupTemplate();
       popupTemplate.setTitle("<b>${NAME}</b><br>")
       popupTemplate.setContent("<b>Cable: ${CAPACITY_G:formatCapacity}</b>");
   
       var popup = new Popup({
           highlight: false,
           titleInBody: true
       }, dojo.create("div"));

       etc....
       ....
       ....
   });
0 Kudos
derekswingley1
Frequent Contributor
If you're still using setContent and setTitle, continue to use an instance of InfoTemplate. You can use it with Popup. Unless you want PopupTemplate's specific features, no need to use PopupTemplate.
0 Kudos
RyanClancy
Occasional Contributor
If you're still using setContent and setTitle, continue to use an instance of InfoTemplate. You can use it with Popup. Unless you want PopupTemplate's specific features, no need to use PopupTemplate.


Okay, I switched back to InfoTemplate. Instead of displaying the default popup over the map I've disabled it with map.infoWindow.set("popupWindow", false) .  I'm writing the contents of the popup to a <div> that I define, somewhat like this. This is why I switched to Popup; I didn't realize I could use InfoTemplate with Popup. The only other difference is the addition of dojo/ready.

The map's infoWindow is set like so:
map = new map("mapDiv", {
    infoWindow: popup
}


The popup is defined as:
var popup = new Popup({
    highlight:false,
    titleInBody: true
}, dojo.create("div"));


InfoTemplate is:
var infoTemplate = new InfoTemplate();
infoTemplate.setTitle("<b>Cable:</b> ${NAME}");
infoTemplate.setContent("<b>Cable:</b> ${NAME}"<br>
                             + "<b>Capacity:</b> ${CAPACITY_G:formatCapacity}");


...all of this happens within ready() and the formatCapacity() function is never called regardless of whether it is nested with ready() or outside of ready().
0 Kudos
derekswingley1
Frequent Contributor
When you're not using the popup on the map, things are a little different. When putting content from a feature in an element outside the map, you have to do more with your code.

In the sample you linked to, the displayPopupContent function gets feature info and puts it in a div. This is where you could also do any custom formatting.
0 Kudos
RyanClancy
Occasional Contributor
Ah, I see. In that case, how do I call the graphic.attr() method? My code is giving me a "feature.attr is not a function" error. Here's what I'm trying to do:

showPopupContent(popup.getSelectedFeature());

function showPopupContent(feature){
    var cap = "";

    if (feature.attributes.CAPACITY_G > 0){
        if (feature.attributes.CAPACITY_G >= 1000{
            cap = dojo.number.format(feature.attributes.CAPACITY_G/1000, {places:2}) + " Tbps";
        }
        else {
            cap = feature.attribues.CAPACITY_G + " Gbps";
        }
    }
    else {
        cap = " n/a"
    }
    //Set the CAPACITY_G attribute to be the newly formatted value
    feature.attr("CAPACITY_G", cap);
    //Get the content for the current feature
    var content = feature.getContent();
    //Display content in the side panel
    dom.byId("cableInfo").innerHTML = content;
0 Kudos
derekswingley1
Frequent Contributor
Are you using 3.7? graphic.attr() was introduced at 3.7 (we'll update the docs to say this).

Attr is also used to add attributes to a graphic's DOM node, it doesn't affect graphic.attributes (which I admit is confusing). If you want to add to or update a graphic.attributes, modify that object directly.
0 Kudos
RyanClancy
Occasional Contributor
Are you using 3.7? graphic.attr() was introduced at 3.7 (we'll update the docs to say this).


Ah, that's the gotcha that got me. I was using 3.6 but I'll switch to 3.7 today. Thanks again!

Attr is also used to add attributes to a graphic's DOM node, it doesn't affect graphic.attributes (which I admit is confusing).


....and oh yes, that is confusing.
0 Kudos