Select to view content in your preferred language

esri.dijit.Popup calling a function that inserts script

2719
8
Jump to solution
04-03-2012 12:05 PM
bbieb
by
Frequent Contributor
I have a esri.InfoTemplate that calls a function.  Within the function I am setting content of a dojox.layout.ContentPane.  I am utilizing a dojox content pane because I need a piece of javascript code to execute.  Eventually I need to get a reference to a node within the dojox.layout.ContentPane, whether that node was part of the content or dynamically created.  The problems is that I cannot get a reference to a node within the ContentPane in IE 8.  The code works fine in FF, Safari, and Chrome.

My question is, is there a way to get a reference to a node in the content pane in IE 8 utilizing the code below?

Entire Process:
1. identify feature
2. process the identified features by attaching script as a feature attribute
3. set feature info template to a function
4. function creates a dojox.layout.ContentPane
5. function retrieves script from feature
6. function sets script/node as the content
7. returns content pane domNode to feature
8. if all goes correctly, a video plays within the popup window

Below is simplified code to illustrate the problem in IE 8.

        //called by maptip each time the maptip record selector moves to that graphic      function getLiveViewContent(graphic) {     var cpX = new dojox.layout.ContentPane({id:"videoContainer"});               //the node is part of the content of the contentpane but when the content is set, IE 8 cannot find the node     var videoNode1 = "<div id='videoNode1'>Loading.....</div><scr" + "ipt type='text/javascript'> var cnNode;var vidNode; var i=0;function checkContainter(){while(cnNode==null&&i<50){cnNode = dijit.byId('videoContainer');if (cnNode!=null){console.log('got cnNode');}i++;}}checkContainter();i=0;function checkVideoNode(){while(vidNode==null&&i<50){vidNode = dojo.byId('videoNode1');i++;console.log(i);if (vidNode!=null){console.log('got vidNode');}}}checkVideoNode();console.log('done');<\/scr" + "ipt>";          //this code retrieves an already created node within the document and appends that node to the container node.  In IE 8, after the append the dojo.byID('videodiv') is null     var videoNode2 = "<scr" + "ipt type='text/javascript'> var cnNode;var vidNode; var i=0;function checkContainter(){while(cnNode==null&&i<50){cnNode = dijit.byId('videoContainer');if (cnNode!=null){console.log('got cnNode');vidNode = dojo.byId('videodiv');if (vidNode!=null){console.log('got vidNode');}cnNode.containerNode.appendChild(vidNode);}i++;}}checkContainter();i=0;var checkNode;function checkVideoNode(){while(checkNode==null&&i<50){checkNode = dojo.byId('videodiv');i++;console.log(i);}}checkVideoNode();console.log('done');<\/scr" + "ipt>";      //var data = graphic.attributes.liveviewdata;     //data = data.replace("jwplayer",videoNode);     cpX.set("content", videoNode2);     return cpX.domNode;      }    identifiedFeatures.addCallback(function(response) {    return dojo.map(response, function(result) {     var feature = result.feature;     //console.log(feature);       if(feature.attributes.liveviewdata!=null && feature.attributes.liveviewdata!="" ){        var template = new esri.InfoTemplate("",getLiveViewContent);        feature.setInfoTemplate(template);        }     return feature;      });    });     map.infoWindow.setFeatures([ identifiedFeatures ]);     map.infoWindow.show(evt.mapPoint);     }   
brian
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
Brian,  Esri Support was looking at this same issue and perhaps you could try the following.  Like you've done, set the template title and content.

Eventually I need to get a reference to a node within the dojox.layout.ContentPane, whether that node was part of the content or dynamically created. The problems is that I cannot get a reference to a node within the ContentPane in IE 8. The code works fine in FF, Safari, and Chrome.


[PHP]
// set content template to a function
template = new esri.InfoTemplate();
template.setTitle("<b>${notes}</b>");
template.setContent(getLiveViewContent);
[/PHP]

Then revise your getLiveViewContent function to look like below.

[PHP]
function getLiveViewContent(graphic) {
     dfd = new dojo.Deferred();
     dfd.addCallback(callbackFired);

     var cpX = new dojox.layout.ContentPane({id:"videoContainer"});
     var videoNode1 = "<div id='videoNode1'>Loading.....</div>";
     cpX.set("content", videoNode1);
 
    //A short setTimeout seems to resolve this issue.  In the callbackFired function you can begin working with the ContentPane, as expected.
    setTimeout(function(){ dfd.callback({success: true}); },200)
    return cpX.domNode;
}

[/PHP]

Lastly, create the callbackFired() function.

[PHP]
function callbackFired(param) {
var p = param;
var vidNode = dijit.byId('videoContainer');
if (vidNode!=null){
  dojo.place("<div>More stuff....</div>", vidNode.containerNode);
  alert('Succeed to get vidNode');
}else{
  alert('Failed to get vidNode');
}
}

[/PHP]

Hope this helps.

Regards,
Doug Carroll, ESRI Support Services SDK Team
http://support.esri.com/

View solution in original post

0 Kudos
8 Replies
danbecker
Frequent Contributor
I wish I had an answer...
this is interesting;  a method of firing a js script from inside a popup to retrieve content that's not in the identify featureset attributes??

I could really use something like this to display related data in a popup, but can't figure out how to return queryrelatedfeatures() results to the popup.
0 Kudos
bbieb
by
Frequent Contributor
Hi Dan,
I use the following to return related records.  I don't know if it would apply in your case as my code just queries related records based on the objectid.  The code creates a tag for the related records, once the data comes back from the second query, it populates that tag.
brian

deferred.addCallback(function(response) {    
    // response is an array of identify result objects    
    // Let's return an array of features.
    //class='mapTipTitle'
    return dojo.map(response, function(result) {
   //console.log(result.layerName);
   var feature = result.feature;
   feature.attributes.layerName = result.layerName;
   switch(result.layerName){
    case "cameras":
     var media = new Array();
     if(feature.attributes.Link!="Null"){
      media.push({
       "title": "<div id='cameraNDDOT' class='mapTipTitle'>{Description}</div>",
       "type": "image",
       "value": {
       "sourceURL": "{Link}",
       "linkURL": "{FullPath}"}})
     }
    case "incidents":
     var webLink="";
     var addInfo="";
     var objectID = feature.attributes.ObjectID;
     var restrictionSpan = "<br/><span class='mapTipContentBold'>Restriction(s):</span> <span id='inrestr-" + objectID + "' class='mapTipContent'>{restrictiontext}</span>";
     //build query
     queryTask = new esri.tasks.QueryTask(restrInUrl);
     //build query filter
     query = new esri.tasks.Query();
     query.returnGeometry = false;
     query.outFields = ["ObjectID","RestrictionText","RestrictionUnits","RestrictionDesc"];
     query.where = "ObjectID=" + objectID;
     //execute query
     queryTask.execute(query,function(results){
      var tmpRestr = ""  
      dojo.forEach(results.features,
       function(feat, index, array) {
        tmpRestr = tmpRestr + "<br/>   " + feat.attributes.RestrictionDesc + " - " + feat.attributes.RestrictionText + " " + feat.attributes.RestrictionUnits;
       }
      );
      if (results.features.length > 0) {
       var tmpSpan = dojo.byId("inrestr-" + objectID);
       dojo.forEach(map.infoWindow.features,
        function(feat,index,array){
         if(feat.attributes.ObjectID = objectID){
          feat.attributes.restrictiontext = tmpRestr
          return false;
         }
         return true;
        }
       );
       //need to do this to the first one so it shows, the rest are handled by graphic attribute "restrictiontext)
       if (tmpSpan != null){
        tmpSpan.innerHTML = tmpRestr;  
       }
      }
     });
     if(feature.attributes.AttachedFile!="Null"){
      addInfo = "<br/><span class='mapTipContentBold'><a href='downloads-incidents/{AttachedFile}' target='_blank'>Additional Information</a>"
     }
     if(feature.attributes.WebLink!="Null"){
      webLink = "<br/><span class='mapTipContent'><a href='{WebLink}' target='_blank'>Web Link</span>"
     }
     var content = "<div id='contentNDDOT'><span class='mapTipContentBold'>Highway:</span> <span class='mapTipContent'>{HwyDesc} {Direction}  (MP: {MPFrom})</span><br/><span class='mapTipContentBold'>Location:</span> <span class='mapTipContent'>{PublicFrom}</span><br/><span class='mapTipContentBold'>Description:</span> <span class='mapTipContent'>{ConditionDesc}</span>" + restrictionSpan + "<br/><span class='mapTipContentBold'>Comment:</span> <span class='mapTipContent'>{Comment}</span>" + addInfo + webLink + "</div>";
     var template = new esri.dijit.PopupTemplate({
     title: "<div class='mapTipTitle tocBdrDkGrey tocBgRed'>Incidents</div>",
     description: content});
     feature.attributes.restrictiontext="None"
     feature.setInfoTemplate(template); 
     break;
   }
   return feature;
    });
  });
 
   
   // InfoWindow expects an array of features from each deferred
   // object that you pass. If the response from the task execution
   // above is not an array of features, then you need to add a callback
   // like the one above to post-process the response and return an
   // array of features.
   map.infoWindow.setFeatures([ deferred ]);
   map.infoWindow.show(evt.mapPoint);
brian
0 Kudos
danbecker
Frequent Contributor
thanks so much for your help!!

I'm finally able to queryrelatedfeatures() and insert the string formatted results into popup, but when a single feature is clicked, nothing shows up in the popup??
If > 1 feature is clicked, the second feature, after hitting the next button on popup displays fine??

Here's what I have

 
        function executeIdentifyTask(evt) {
  //since LAYER_OPTION_VISIBLE only pertains to scale visibility, not TOC checked/not checked, we have to manually set the identifyParams.layerIds
  var lids = [];
  dojo.forEach(legendLayers, function(layer){
   if (layer.layer.visible === true){
    lids.push(map.getLayer(layer.layer.id).layerId)
   }   
  })
  console.log(lids);
                identifyParams.layerIds = lids;           
                identifyParams.width  = map.width;
                identifyParams.height = map.height;
  identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;    
                identifyParams.geometry = evt.mapPoint;
                identifyParams.mapExtent = map.extent;
       
                var deferred = identifyTask.execute(identifyParams);
  
                deferred.addCallback(function(response) {
                          // response is an array of identify result objects    
                         // Let's return an array of features.
                         return dojo.map(response, function(result) {
                                 var feature = result.feature;
                                 feature.attributes.layerName = result.layerName;
   
            switch(result.layerName){
            case "RSC63D.DBO.logistics2":
     var template = new esri.dijit.PopupTemplate({
      title: "{site_code}",
      description: "Type: {Type} <br /> Shop: {SHOP}"
     });
                                feature.setInfoTemplate(template);
            break;
    
    
               case "RSC63D.DBO.query2":
        var featObjId = feature.attributes.OBJECTID_1;
        var relatedBranch = new esri.tasks.RelationshipQuery();
     relatedBranch.outFields = ["*"];
     relatedBranch.relationshipId = 1; //fac -to- Branch
     relatedBranch.objectIds = [featObjId];
                facSel.queryRelatedFeatures(relatedBranch, function(relatedBranches) {
      var branchFound = false;
      if(relatedBranches.hasOwnProperty(featObjId) == true){
       branchFound = true;
       var branchSet = relatedBranches[featObjId];
       var cmdBranch = dojo.map(branchSet.features, function(feature){
        return feature.attributes;
       })
       //console.log(cmdBranch);
      } 
      var relatedQuery = new esri.tasks.RelationshipQuery();
                    relatedQuery.outFields = ["*"];
                    relatedQuery.relationshipId = 0; //fac -to- cmdMain
                    relatedQuery.objectIds = [featObjId];
      //rather then listen for "OnSelectionComplete" we are using the queryRelatedFeatures callback function
      facSel.queryRelatedFeatures(relatedQuery, function(relatedRecords) {
       var data = []
       if(relatedRecords.hasOwnProperty(featObjId) == true){
        var fset = relatedRecords[featObjId]
        var cmdMain = dojo.map(fset.features, function(feature) {
         return feature.attributes;
        })
        //we need to fill an array with the objectids of the returned cmdMain records
        //the length of this list == total number of mainCmd records returned for the clicked facility
        objs = []
        for (var k in cmdMain){
         var o = cmdMain;
         objs.push(o.OBJECTID)      
        }
        //third relationship query to find records related to cmdMain (cmdSub)
        var subQuery = new esri.tasks.RelationshipQuery();
        subQuery.outFields = ["*"];
        subQuery.relationshipId = 2;
        subQuery.objectIds = [objs]
        subTbl.queryRelatedFeatures(subQuery)
        dojo.connect(subTbl,"onQueryRelatedFeaturesComplete",function (subRecords){
         //subRecords is an object where each property is the objectid of a cmdMain record
         //if a cmdRecord objectid is present in subRecords property, cmdMain has sub records
         //we no longer need these objectids, so we'll remove them and put the array into cmdsub
         var cmdSub = []
         for (id in subRecords){
          dojo.forEach(subRecords[id].features, function(rec){
           cmdSub.push(rec.attributes)
          })
         }
         var j = cmdSub.length;
         var p;
         var sub_key;
         var obj;
         if (branchFound == true){
          var p1 = "branch";
          obj1 = {};
          obj1[p1] = [cmdBranch[0].Branches]
          data.push(obj1)
         }       
         for (var i=0, iLen = cmdMain.length; i<iLen; i++) {
            p = cmdMain.ASGMT_Name
            obj = {};
            obj
 = [];
            sub_key = cmdMain.sub_key;
            for (var j=0, jLen=cmdSub.length; j<jLen; j++) {
              if (cmdSub.sub_key == sub_key) {
                 obj
.push(cmdSub.Long_Name);
              }
            }
            data.push(obj);
         }
         //format data  array here
         var template = new esri.dijit.PopupTemplate({
          title: "something",
          description: formatCmdData(data)
         });
         var template = new esri.InfoTemplate("",formatCmdData(data));
         feature.setInfoTemplate(template);
        });        
       }
       else {
        p = "No Data Available"
        obj = {}
        obj
 = []
        data.push(obj)
        //format data array here
        var template = new esri.dijit.PopupTemplate({
         title: "{site_code} - {facil_name}",
         description: formatCmdData(data)
        });
        feature.setInfoTemplate(template);
       }
       
      })     
      
     })
     break;
    
    
      
     }
     console.log(feature)
     return feature;
     
     
     
          });
        });
  
        // InfoWindow expects an array of features from each deferred
        // object that you pass. If the response from the task execution
        // above is not an array of features, then you need to add a callback
        // like the one above to post-process the response and return an
        // array of features.
  map.infoWindow.setFeatures([ deferred ]);  
        map.infoWindow.show(evt.mapPoint);
  
      }

0 Kudos
bbieb
by
Frequent Contributor
Just heading out the door and didn't quite follow all of your code but I believe the following is how I got around that problem in my situation.  As far as why, didn't dig that far into it.


       //need to do this to the first one so it shows, the rest are handled by graphic attribute "restrictiontext)
       if (tmpSpan != null){
        tmpSpan.innerHTML = tmpRestr;  
       }
brian
0 Kudos
danbecker
Frequent Contributor
weird that I have this problem; i'm not filling a previously created div, I'm setting the dijit.popup to pull the already formatted query result string, i.e. description: function(getmystring)??

If i console.log(map.infoWindow.features[0].infoTemplate.info.description) my data string is there, but it's not displayed on the popup?
0 Kudos
by Anonymous User
Not applicable
Brian,  Esri Support was looking at this same issue and perhaps you could try the following.  Like you've done, set the template title and content.

Eventually I need to get a reference to a node within the dojox.layout.ContentPane, whether that node was part of the content or dynamically created. The problems is that I cannot get a reference to a node within the ContentPane in IE 8. The code works fine in FF, Safari, and Chrome.


[PHP]
// set content template to a function
template = new esri.InfoTemplate();
template.setTitle("<b>${notes}</b>");
template.setContent(getLiveViewContent);
[/PHP]

Then revise your getLiveViewContent function to look like below.

[PHP]
function getLiveViewContent(graphic) {
     dfd = new dojo.Deferred();
     dfd.addCallback(callbackFired);

     var cpX = new dojox.layout.ContentPane({id:"videoContainer"});
     var videoNode1 = "<div id='videoNode1'>Loading.....</div>";
     cpX.set("content", videoNode1);
 
    //A short setTimeout seems to resolve this issue.  In the callbackFired function you can begin working with the ContentPane, as expected.
    setTimeout(function(){ dfd.callback({success: true}); },200)
    return cpX.domNode;
}

[/PHP]

Lastly, create the callbackFired() function.

[PHP]
function callbackFired(param) {
var p = param;
var vidNode = dijit.byId('videoContainer');
if (vidNode!=null){
  dojo.place("<div>More stuff....</div>", vidNode.containerNode);
  alert('Succeed to get vidNode');
}else{
  alert('Failed to get vidNode');
}
}

[/PHP]

Hope this helps.

Regards,
Doug Carroll, ESRI Support Services SDK Team
http://support.esri.com/
0 Kudos
bbieb
by
Frequent Contributor
Hi Doug,
Thanks.  Your suggestion really helped.  I had to set the content twice on the dojox.layout.ContentPane to get the javascript to fire.  Set it once to get IE to recognize the tag, then set the content again with the same tag to get the javascript to execute.  Seems to work on the major browsers.
brian

   function dfdVideoCallback(param) {
     var cpX = param.cp
     //try to get videodiv, in IE 8 had to wait little, seems to work ie even though the videodiv node is being replaced by the set content
     var vidDiv = dojo.byId('videodiv');
     if (vidDiv!=null){
      cpX.set("content", "<div id='videodiv'>Loading....</div>" + param.liveview);
     }else{
      alert('Failed to get video');
     }
   }
   
   //used to get the liveviewdata
   //called by maptip each time the maptip record selector moves to that graphic
   function getLiveViewContent(graphic) {
    var videoscript = graphic.attributes.liveviewdata;
    var dfdVideo = new dojo.Deferred();
    dfdVideo.addCallback(dfdVideoCallback);
    var cpX = new dojox.layout.ContentPane({id:"videoContainer"});
    var videoNode = "<div id='videodiv'>Loading....</div>" //+ videoscript
    cpX.set("content", videoNode);
    //give ie8 some time to catch up
    setTimeout(function(){dfdVideo.callback({liveview:videoscript,cp:cpX});},200)
    return cpX.domNode;
   }
brian
0 Kudos
Celeste_SuliinBurris
Occasional Contributor
I wish this were more straightforward. I am just getting started with Dojo.  I am trying to let the user look at the content in a feature layer, and if it is what they want, print a detailed report. I already have the report logic working from select text statements, I just want it to get the key from the selected record and fire a script.  Seems like it should be way less complicated. I find Dojo far less easy to use than JQuery. Even Javascript without a framework seems more straightforward (or maybe the documentation is better).
0 Kudos