Select to view content in your preferred language

Identify - exclude tabs / contentpanes with no features returned

1296
7
Jump to solution
01-30-2013 06:03 AM
DavidBoyd
Emerging Contributor
I'm working on a webmap that identifies on 10 layers in a dynamicmapservice.  The results are displayed in a tabcontainer with 10 tabs or contentpanes.  I'm trying to exclude or hide the tabs or contantpanes where no results are returned.  So...if the user clicks the map and only two layers include features at that location, only 2 tabs will appear in the popup (instead of all 10).  I thought I could edit the code for each layer in the layertabcontent function, but my attempts have failed so far.

Any help is appreciated.  I'll attach the complete code as a Word file.
0 Kudos
1 Solution

Accepted Solutions
DianaBenedict
Frequent Contributor
Have you considered adding the Tabs on the fly once you get your reslutls?  For example, you can loop through the results array and add a tab for each feature class results.  Otherwise, you will need to get the dojo dijit tab container and remove the child tabcontainer or figure out what the hide property is for the tab container tabs.  This is just a suggestion, there are of course many different ways to do this. Good luck

//quick example on how to create a simple tab container (non AMD) //this code would be within your loop of results //you would generate the content on the fly and get the layername from the results for each ... var tab1 = new dijit.layout.ContentPane({     title: "myTabTitle1",     selected: true,     content: "point to the content the create on the fly here for 1st identify results"   }); dijit.byId("myTabcontainer").addChild(tab1); 


Happy to help.  Not sure if you are already doing this, but I would use the following example as a guide to help you build your content.
http://help.arcgis.com/en/webapi/javascript/arcgis/jssamples/#sample/find_drilldown

Essentially, you will need to do something similar to what they do in the example above
1) take your identifyResults and reorganize them into groups of featureclassName and/or ID with array of respective fetures
2) after you have "resorted" the identify results then you can loop through each feature class in your new object (above) and
  a) create the content
  b) create your new tab
  c) bind the content to the tab
3) don't forget to removeChild tabs from the TabContainer before you add all the new child Tabs  ... this might be the first thing you do
Something like (if tabcontainer has childtabs then remove all child tabs .. can't remember but I think there is a pretty simple method to do that in Dojo

Good Luck

View solution in original post

0 Kudos
7 Replies
DianaBenedict
Frequent Contributor
Have you considered adding the Tabs on the fly once you get your reslutls?  For example, you can loop through the results array and add a tab for each feature class results.  Otherwise, you will need to get the dojo dijit tab container and remove the child tabcontainer or figure out what the hide property is for the tab container tabs.  This is just a suggestion, there are of course many different ways to do this. Good luck

//quick example on how to create a simple tab container (non AMD)
//this code would be within your loop of results
//you would generate the content on the fly and get the layername from the results for each ...
var tab1 = new dijit.layout.ContentPane({
    title: "myTabTitle1",
    selected: true,
    content: "point to the content the create on the fly here for 1st identify results"
  });
dijit.byId("myTabcontainer").addChild(tab1);

0 Kudos
DavidBoyd
Emerging Contributor
Thanks Diana!  I'll try this approach and code you posted.  I looked into hiding the child tab container and couldn't get it to work.  I'm still new to javascript so I'm not surprised it didn't work.  I appreciate your reply!
0 Kudos
DianaBenedict
Frequent Contributor
Have you considered adding the Tabs on the fly once you get your reslutls?  For example, you can loop through the results array and add a tab for each feature class results.  Otherwise, you will need to get the dojo dijit tab container and remove the child tabcontainer or figure out what the hide property is for the tab container tabs.  This is just a suggestion, there are of course many different ways to do this. Good luck

//quick example on how to create a simple tab container (non AMD) //this code would be within your loop of results //you would generate the content on the fly and get the layername from the results for each ... var tab1 = new dijit.layout.ContentPane({     title: "myTabTitle1",     selected: true,     content: "point to the content the create on the fly here for 1st identify results"   }); dijit.byId("myTabcontainer").addChild(tab1); 


Happy to help.  Not sure if you are already doing this, but I would use the following example as a guide to help you build your content.
http://help.arcgis.com/en/webapi/javascript/arcgis/jssamples/#sample/find_drilldown

Essentially, you will need to do something similar to what they do in the example above
1) take your identifyResults and reorganize them into groups of featureclassName and/or ID with array of respective fetures
2) after you have "resorted" the identify results then you can loop through each feature class in your new object (above) and
  a) create the content
  b) create your new tab
  c) bind the content to the tab
3) don't forget to removeChild tabs from the TabContainer before you add all the new child Tabs  ... this might be the first thing you do
Something like (if tabcontainer has childtabs then remove all child tabs .. can't remember but I think there is a pretty simple method to do that in Dojo

Good Luck
0 Kudos
DavidBoyd
Emerging Contributor
Yeah, my code follows the example pretty closely, with a few differences.  I tried adding the removeChild at the if/else part of the script where the tab contents are set up.  I'm not sure if this is the right place to do it and I doubt I did it correctly.  Right now if an identify doesn't intersect any features, it just doesn't display the whole tabcontainer.  I just want to exclude the landsTab.  "tc" is the variable name for the tabcontainer in the previous function...not sure I used that correctly.  Here's the section I edited:

   if(layerName === "landsResults"){
      if(layerResults.features.length > 0){
        content = "<i>Conservation Lands returned: " + layerResults.features.length +
        "</i>";
        content += "<table border='1'><tr><th>Label</th><th>Land Type</th><th>Manager</th><th>Weblink</th></tr>";
        for (var i=0, il=layerResults.features.length; i<il; i++) {
          content+="<tr><td>"+layerResults.features.attributes['LABEL']+" <a href='#' onclick='showFeature(" + layerName + ".features[" + i + "]); return false;'>(show)</a></td>";
          content+="<td>"+layerResults.features.attributes['MATYPE']+"</td>";
          content+="<td>"+layerResults.features.attributes['MAAGENCY']+"</td>";
          content+="<td>"+" <a href=" + layerResults.features.attributes['LANDLINK'] + " target=_blank ;'>More Info</a></td>";
        }
        content+="</tr></table>";
    }else{
      dijit.byId("tc").removeChild(landsTab);

    }
  }
0 Kudos
DianaBenedict
Frequent Contributor

   if(layerName === "landsResults"){
      if(layerResults.features.length > 0){
        content = "<i>Conservation Lands returned: " + layerResults.features.length +
        "</i>";
        content += .....
     .....
    }else{
      dijit.byId("tc").removeChild(landsTab);

    }
 

 
Not sure what "landTab" is but here is the syntax that I got from dojo

dijit.byId('MyTabContainer').removeChild(dijit.byId('MyTab'));


Not to derail you too much but I ask .. why do you want your results seperated into tabs?  I believe that if you loop through your featureset and creaet an info template for each GRAPHIC and set the content then you can pass the featureset to a popup template or InfoWindow. Both of these Windows will allow you to navigate to each record with a built in "Next" and "Previous" buttons. 

http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/#Graphic/setInfoTemplate

Obviously, the major disadvantage to this is that the users will need to navigate to each record to see the results for each "Layer". Whereas your method allows the user to quickly visualize the selected records per "tab".

If you choose the Tab Page method then I might suggest that you create some methods to quickly remove All child tabs and add them dynamically each time an Identify task is executed.

if (tabControl.hasChildren()) {
      var tabControlChildren = tabControl.getChildren();
//loop through tabcontrol and remove all children...
}
//call code to add all tabs based on the unique list of IdentifyResult.LayerName.


Good luck ...
0 Kudos
TimCollyer
Regular Contributor
David,

I've done something similar to what Diana suggested and I think it is similar to what you are attempting to do.

I'm using dgrid to present a variable number of grids in separate tabs.

The only "non-standard" thing about my setup is that I have an intermediatery service between my client and my map server which performs the query via REST and formats the results in a specific way before passing it back to the client.

i.e. The json that my service returns is formatted as below such that it is easy to create the dgrid object. To be honest I'm not sure this is a great idea and I'm yet to convince myself to keep it this way... but for now it works. 😛

[    {
        "title":"Sites",
        "columns":{"SLOT_TYPE_CD":"Slot Type Code","USER_REF_ID":"Site Id"},
        "features":[
            {"SLOT_TYPE_CD":"XX","USER_REF_ID":"P123456-A"},
            {"SLOT_TYPE_CD":"YY","USER_REF_ID":"P123456-B"}
        ]
    },
    {
        "title":"Properties",
        "columns":{"PLAN":"Plan No.","LOCALITY":"Suburb","LOT":"Lot No."},
        "features":[
            {"PLAN":"RP12345","LOCALITY":"Somewhereville","LOT":"1"},
            {"PLAN":"RP54321","LOCALITY":"Somewhereville","LOT":"2"}
        ]
    }
]


So the function called from the map "onclick" sets a variable (called "resultSet" in the code below) to be the above json string returned from my service, it then calls the function to display the popup window with it's tabs as so...

function displayIdentify(evt) {

    // destroy any existing/leftover identify dijit 
    if (dijit.byId("identifyResults")) {
        dijit.byId("identifyResults").destroy();
    }    
    
    // create the tab container
    var tc = new dijit.layout.TabContainer({
        id: "identifyResults",
        style: "height: 300px; width: 100%;"            
    }, dojo.create("div"));    
    
    // for each record in the resultset, create a dgrid and add it to the tabcontainer
    for (var i = 0; i < resultSet.length; i++) {
        var featureType = resultSet;
        
        var columns = featureType.columns;
        var data = featureType.features;


        var grid = new dgrid.Grid({
            columns: columns
        }, dojo.create("div"));
        
        grid.renderArray(data);        
        
        tc.addChild(new dijit.layout.ContentPane({
            title: featureType.title,
            style: "height: 100%; width: 100%",
            content: grid.domNode
        }));
    }    


    map.infoWindow.setTitle("Identify results");
    map.infoWindow.setContent(tc.domNode);
    map.infoWindow.show(evt.mapPoint);
    
    dijit.byId("identifyResults").resize();
    
    hideLoading();
}
0 Kudos
DavidBoyd
Emerging Contributor
So, I'm still trying to follow Diane's example and struggling with it.  I'm still very much a beginner and trying to understand how all of the functions interact, how to call variables, and general javascript stuff.  I added the following line to my code to remove the child tab (landsTab) from the main tab container (tc) if the results were blank:

dijit.byId("tc").removeChild(dijit.byId('landsTab'));

Obviously I'm not doing something correctly, and the problem may be elsewhere in the code.  When I click on the map where "lands" are present, the identify works properly.  If no lands are present the whole tab container just doesn't come up at all.  Instead I'm trying to get it to just remove the childTab named "landsTab" if no lands are present.

Diane mentioned removing all childtabs before all of this...would that be within the function addToMap(idResults, evt)?

One of these days I might get it!  Any more pointers you can provide are appreciated.  Sorry to be such a slow learner.
0 Kudos