Monday, March 26, 2012

ARCGIS JavaScript API – ADDING A LAYER SELECTION – PART III


1.     Introduction


Before going to implementing different tools and commands from the toolbars for doing different GIS functions I add a list that contains all the layers that  can be used for doing spatial and attribute queries.  This list is similar to what can be found in the ArcGis desktop application AcMap on the second tab.  As is the case of the legend module I used a jQuery extension in combination with a template to create a layer selection list. The actions needed for creation the layer selection list consists of the following steps

·         Create a jQuery HTML template that is hosted on the web server and will serve as the blueprint for a list item. The template is retrieved through an AJAX request.

·         Create a simple jQuery extension that will call the jQuery template plug-in.

·         Build an array of layers with for each layer a number of useful attribute information. The creation of the array will consists of a call of a rest service for each layer. In the example outlined here, I will limit the array of layers to feature layers. This could easy be extended to all layers having a query capability and not necessary having attributes exposed.

To make the layer selection list available to all components, the list will be maintained in the gisOperation class.

2.     Layer selection template


The template I use is much simpler than the one used in the legend. It can easy be customized by CSS to enhance the presentation of the list. In my example, the template looks like this:

<li>

  <input type="checkbox" style="float:left" id="${$item.getCheckboxID()}" checked="${$item.getChecked()}" />

  <h3 class="agsSelect" style="margin:0 0 0 25px;padding:0;" >${title}</h3>

</li>

<div style="clear:both"/>

In this template I use two functions  to calculate an unique ID and event handling of the checkbox checked.

3.     Layer selection jQuery extension


The most important is the update of the array list with the selection set or reset. This is done by the code below that is linked to the click event of the checkbox.

// Handle the select toggle click event
function checkSelectLayer(ev) {
// We'll find the layer based on the select id, so capture it
  var selectId = this.id,select =this.checked;
  $.each(iGisOperation.getLayersSelectionInfos(), function (index, selectLayer) {
     if (selectLayer.selectId === selectId){
        iGisOperation.getLayersSelectionInfos()[index].selected = select; 
     }
     return;
  });                                       
}

4.     Layer selection list creation


The creation of the layer selection list is largely done in a the layer selection module. In this module I put some initialization into it that will be responsible for the maintenance of the list. For its creation the layer selection list depends on the output of the legend module. To synchronize the maintenance of the layer selection list with the legend module, I used the event aggregator  class to subscribe to the end of the legend build. After the legend is build, all extra information needed will be available.
The init of the layer selection module is responsible for the subscription process.

var layerSelectionModule = (function () {
    var i, j, k, l, index;
    var totalLayers2Check = 0;
    var totalLayersChecked = 0;
    var urlGet;
    var divLegend;
    var selectionInfo;

….

    return {
        init: function (divElement) {
            this.divLegend = divElement;
            iEventAggregator.subscribe("legendBuild", selectBuild, divElement);
        }
    }
});

The selectBuild function will actual create the layer selection list upon the end of the build of the legend.

function selectBuild() {
// Calculate number or layers
  for (i = 0; i < iGisOperation.getLayersLegendInfos().length; i++) {
    if (iGisOperation.getLayersLegendInfos()[i].layers != null)
      totalLayers2Check += iGisOperation.getLayersLegendInfos()[i].layers.length;
  }
  // Start building the selection layer list
  for (i = 0; i < iGisOperation.getLayersLegendInfos().length; i++) {
    if (iGisOperation.getLayersLegendInfos()[i].layers != null) {
     for (j = 0; j < iGisOperation.getLayersLegendInfos()[i].layers.length; j++) {
     // Skip group layer
       if (iGisOperation.getLayersLegendInfos()[i].layers[j].parentLayerId > -1) {
         urlGet = iGisOperation.getLayersLegendInfos()[i].url + "/" + iGisOperation.getLayersLegendInfos()[i].layers[j].id + "?f=json&callback=?";
         $.getJSON(urlGet, function (data) {
            if (data.type == 'Feature Layer') {
              index = -1;
              for (k = 0; k < iGisOperation.getLayersLegendInfos().length; k++) {
                if (iGisOperation.getLayersLegendInfos()[k].layers != null) {
                  for (l = 0; l < iGisOperation.getLayersLegendInfos()[k].layers.length; l++) {
                    if (iGisOperation.getLayersLegendInfos()[k].layers[l].name == data.name) {
                       index = k;
                       break;
                     }
                   }
                   if (index > -1)
                     break;
                 }
               }
               if (index > -1) {
                 selectionInfo = 
                   new layerSelectionInfo(iGisOperation.getLayersLegendInfos()[index].url, data.id, data.name, data.fields, data.displayField, iGisOperation.getLayersSelectionInfos().length);
                   iGisOperation.getLayersSelectionInfos().push(selectionInfo);
               }
             }
             terminateLayerInitialize();
           });
         }
         else
           terminateLayerInitialize();
       }
     }
   }
 }
 function terminateLayerInitialize() {
   totalLayersChecked += 1;
   if (totalLayersChecked == totalLayers2Check) {
   // All layers has been retrieved, ready to move the contents to the list
     var selectLayers = $("#selectRegion").agsSelect({ autoLoadTemplates: true });
   }
 }

I use a simple counter system to know when all rest services has been processed. When this is done, the jQuery extension is called with the template plugin. During the processing of the rest services important information as fields are included into the layer selection list. This will be useful during the query command and tools. I also maintain the layer selection array into the gisOperation class for common use.

The final result looks like this:

No comments:

Post a Comment