Select to view content in your preferred language

One button to independently trigger functions of users' choice

1881
10
Jump to solution
05-20-2014 01:56 PM
AlexGole1
Emerging Contributor
I am looking to simplify my code. As of right now I have a code that allows the users to extract GIS data in three different ways. 1) Extract by Drawn extent, 2) Extract by extent of the a county, 3) Extract by Extent by Unit.

1st function:

   
function extractData() {             //get clip layers             var clipLayers = [];             if (registry.byId("layer1").get("checked")) {                clipLayers.push("SRA");             }             if (registry.byId("layer2").get("checked")) {                clipLayers.push("Burn");             }             if (clipLayers.length === 0|| map.graphics.graphics.length === 0) {                alert("Select layers to extract and draw an area of interest.");                return;             }              var featureSet = new FeatureSet();             var features = [];             features.push(map.graphics.graphics[0]);             featureSet.features = features;              var params3 = {                "Layers_to_Clip": clipLayers,                "Area_of_Interest": featureSet,                "Feature_Format": registry.byId("formatBox").get("value")             };              domStyle.set(loading2, "display", "inline-block");             gp.submitJob(params3, completeCallback, statusCallback2, function (error) {                alert(error);                domStyle.set(loading2, "display", "none");             });          }

2nd fucntion:

   
function executeQueryTask(county) {    var clipLayers = [];             if (registry.byId("layer1").get("checked")) {                clipLayers.push("SRA");             }             if (registry.byId("layer2").get("checked")) {                clipLayers.push("Burn");             }    if (clipLayers.length === 0) {                alert("No layers to clip, please select a layer you would like to clip...");                return;             }         var county = document.getElementById("sel_county").value                   var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Counties/MapServer/0");     queryTask.on("complete", addToMap)     var query = new Query();           query.returnGeometry = true;           query.outFields = ["NAME_PCASE"];           query.where = "NAME_PCASE = '" + county + "'";           query.outSpatialReference = map.spatialReference;     queryTask.execute(query, function (featureSet) {    var AOI = featureSet.features[0].geometry;    var graphic = new Graphic(AOI, symbol);       var features = [];             features.push(graphic);             var fSet = new FeatureSet();             fSet.features = features;           var params = {                "Layers_to_Clip": clipLayers,                "Area_of_Interest": fSet,                "Feature_Format": registry.byId("formatBox").get("value")   };                       domStyle.set(loading, "display", "inline-block");             gp.submitJob(params, completeCallback, statusCallback, function (error) {                alert(error);                domStyle.set(loading, "display", "none");             });     });    }


And a third that looks exactly like the  one above except that I query by units not county.

Each function is triggered by this:

 
  registry.byId("extract1").on("click", executeQueryTask);


And this:

    <button id="extract1" data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'Query', showLabel:false">              Extract Data             </button>

Now here is my question: How can independently trigger each function from ONE AND ONLY ONE button? As of right now I have three buttons that triggers each function. Would it be possible to trigger each function independently from only 1 button? For example, If users draw then the 1 and only "extract" button would extract data by the extent drawn by the user. FYI I am using a dijit/from/dropdown for selecting counties and units, which means there always be one element selected in these two extraction process.
Thank you,
Alex
0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor
You can define any sort of function you'd like, but until you call it, it won't do anything. You'd essentially have to do something like this

  case "extractByUnit":     executeQueryTask1(unit);     function executeQueryTask1(unit) {       var clipLayers = [];       if (registry.byId("layer1").get("checked")) {         clipLayers.push("SRA");       }       etc.


Here's an example showing the difference. Try clicking all three buttons to see what happens.

As for your "addTomap" error, you probably have the function name misspelled. But you say
"addtomap" is a function that  i call outside the switch function.

Remember that JavaScript is case sensitive.

View solution in original post

0 Kudos
10 Replies
SteveCole
Honored Contributor
I think one way would be using a global variable (something like "var extractMethod;") that gets populated at the conclusion of all three "methods". So, for example, at the conclusion of the user's draw event, code something like:
extractMethod = "extractByPoly";


In the dropdown's update method for your county list, code something like:
extractMethod = "extractByCounty";


...and finally, at the end of the dropdown's update method for your unit's info, code something like:
extractMethod = "extractByUnit";


Now, in the click event for your "Extract" button, use a switch conditional to then determine what to do:
switch (extractMethod )
{
   case "extractByPoly": 
       someSubRoutine();
       break;
   case "extractByCounty":
       executeQueryTask(countyName);
       break;
   default: 
       executeQueryTask(unitName);
       break;
}


Steve
0 Kudos
AlexGole1
Emerging Contributor
I think one way would be using a global variable (something like "var extractMethod;") that gets populated at the conclusion of all three "methods". So, for example, at the conclusion of the user's draw event, code something like:
extractMethod = "extractByPoly";


In the dropdown's update method for your county list, code something like:
extractMethod = "extractByCounty";


...and finally, at the end of the dropdown's update method for your unit's info, code something like:
extractMethod = "extractByUnit";


Now, in the click event for your "Extract" button, use a switch conditional to then determine what to do:
switch (extractMethod )
{
   case "extractByPoly": 
       someSubRoutine();
       break;
   case "extractByCounty":
       executeQueryTask(countyName);
       break;
   default: 
       executeQueryTask(unitName);
       break;
}


Steve



This is the first time I hear about this "switch" javascript function. I am going to look into it right now and probably get back to you if I am too confused.  That being said, how will the "switch" and "case" differentiate between the two dropdown forms (county and units). will by clicking on one drop down menu automatically trigger the "swicth"/"case"?
Thank you for your help!
0 Kudos
SteveCole
Honored Contributor
If you have two dropdown combo boxes, they would both have their own change event and that's how you would differentiate between County and unit by populating the global variable like I described in my original reply. No matter which of the three options the user chooses, the extractMethod variable stores a value which you then retrieve during the click event for your Extract button to learn which method the user wants. The switch conditional statement is used to chose a path of action based on multiple options. If you've programmed in VB or VBA, it's a lot like the SELECT CASE statement.

Steve
0 Kudos
AlexGole1
Emerging Contributor
Here is my code. It is not working yet. It seems like it cannot find my "myFunction" function but maybe I am doing something wrong. Any idea?
Thank you,
Alex

function myFunction() {
   var extractMethod = "extractByPoly";
   var extractMethod = "extractByCounty";
   var extractMethod = "extractByUnit";
   
   switch (extractMethod) {
   default:
   
   function extractData() {
            //get clip layers
            var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
               clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
               clipLayers.push("Burn");
            }
            if (clipLayers.length === 0|| map.graphics.graphics.length === 0) {
               alert("Select layers to extract and draw an area of interest.");
               return;
            }

            var featureSet = new FeatureSet();
            var features = [];
            features.push(map.graphics.graphics[0]);
            featureSet.features = features;

            var params3 = {
               "Layers_to_Clip": clipLayers,
               "Area_of_Interest": featureSet,
               "Feature_Format": registry.byId("formatBox").get("value")
            };

            domStyle.set(loading2, "display", "inline-block");
            gp.submitJob(params3, completeCallback, statusCallback2, function (error) {
               alert(error);
               domStyle.set(loading2, "display", "none");
            });
         }
   break;
   
   case "extractByCounty":
         function executeQueryTask(county) {
   var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
               clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
               clipLayers.push("Burn");
            }
   if (clipLayers.length === 0) {
               alert("No layers to clip, please select a layer you would like to clip...");
               return;
            }
   
    var county = document.getElementById("sel_county").value
    var unit = document.getElementById("sel_unit").value 
          var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Counties/MapServer/0");
    var queryTask1 = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
    queryTask.on("complete", addToMap)
    var query = new Query();
          query.returnGeometry = true;
          query.outFields = ["NAME_PCASE"];
          query.where = "NAME_PCASE = '" + county + "'";
          query.outSpatialReference = map.spatialReference;
    queryTask.execute(query, function (featureSet) {
   var AOI = featureSet.features[0].geometry;
   var graphic = new Graphic(AOI, symbol);
      var features = [];
            features.push(graphic);
            var fSet = new FeatureSet();
            fSet.features = features;

    
    var params = {
               "Layers_to_Clip": clipLayers,
               "Area_of_Interest": fSet,
               "Feature_Format": registry.byId("formatBox").get("value")
  };
  
  
   
            domStyle.set(loading, "display", "inline-block");
            gp.submitJob(params, completeCallback, statusCallback, function (error) {
               alert(error);
               domStyle.set(loading, "display", "none");
            });
    });
   }
  break;
    
    
   case "extractByUnit":
   function executeQueryTask1(unit) {
   var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
               clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
               clipLayers.push("Burn");
            }
   if (clipLayers.length === 0) {
               alert("No layers to clip, please select a layer you would like to clip...");
               return;
            }
   
    var unit = document.getElementById("sel_unit").value          
          var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
    queryTask.on("complete", addToMap2)
    var query = new Query();
          query.returnGeometry = true;
          query.outFields = ["UNITCODE"];
          query.where = "UNITCODE = '" + unit + "'";
          query.outSpatialReference = map.spatialReference;
    queryTask.execute(query, function (featureSet) {
   var AOI = featureSet.features[0].geometry;
   var graphic = new Graphic(AOI, symbol);
      var features = [];
            features.push(graphic);
            var fSet = new FeatureSet();
            fSet.features = features;

    
    var params2 = {
               "Layers_to_Clip": clipLayers,
               "Area_of_Interest": fSet,
               "Feature_Format": registry.byId("formatBox").get("value")
  };
  
  
   
            domStyle.set(loading1, "display", "inline-block");
            gp.submitJob(params2, completeCallback, statusCallback1, function (error) {
               alert(error);
               domStyle.set(loading1, "display", "none");
            });
    });
   }
   }
   }


HTML:
<button onclick="myFunction()" data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'DownIcon', showLabel:false">


Error:

ReferenceError: myFunction is not defined
0 Kudos
KenBuja
MVP Esteemed Contributor
If your code is in AMD, then this is a problem of scoping. The "myFunction" function is not available in the HTML portion of your code. Instead, you should create a listener for the button in your script. See the documention for dojo events.

You'd use something like this

HTML
<button id="myButton" data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'DownIcon', showLabel:false">

JavaScript
require(["dijit/registry"], function(registry){
    registry.byId("myButton").on("click", myFunction); 
});
0 Kudos
AlexGole1
Emerging Contributor
If your code is in AMD, then this is a problem of scoping. The "myFunction" function is not available in the HTML portion of your code. Instead, you should create a listener for the button in your script. See the documention for dojo events.

You'd use something like this

HTML
<button id="myButton" data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'DownIcon', showLabel:false">

JavaScript
require(["dijit/registry"], function(registry){
    registry.byId("myButton").on("click", myFunction); 
});



Thank you! That was the issue for the "myFunction". Now it seems like when I run the tool using the switch statement, nothing happens. No errors to report either. What did I do wrong in the way I wrote the switch?
Thanks,
Alex
0 Kudos
KenBuja
MVP Esteemed Contributor
The way you have it written, you're defining functions within each case, but never calling them. And be aware that the way it's currently written where you keep defining  the variable extractMethod, it will only run the "extractByUnit" method. This value should be set outside the function. Try something like this

set the extractMethod somewhere outside this function

function myFunction() {
    //var extractMethod = "extractByPoly";
    //var extractMethod = "extractByCounty";
    //var extractMethod = "extractByUnit";

    switch (extractMethod) {
        default:

            //function extractData() {
            //get clip layers
            var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
                clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
                clipLayers.push("Burn");
            }
            if (clipLayers.length === 0 || map.graphics.graphics.length === 0) {
                alert("Select layers to extract and draw an area of interest.");
                return;
            }

            var featureSet = new FeatureSet();
            var features = [];
            features.push(map.graphics.graphics[0]);
            featureSet.features = features;

            var params3 = {
                "Layers_to_Clip": clipLayers,
                "Area_of_Interest": featureSet,
                "Feature_Format": registry.byId("formatBox").get("value")
            };

            domStyle.set(loading2, "display", "inline-block");
            gp.submitJob(params3, completeCallback, statusCallback2, function (error) {
                alert(error);
                domStyle.set(loading2, "display", "none");
            });
            //}
            break;

        case "extractByCounty":
            //function executeQueryTask(county) {
            var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
                clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
                clipLayers.push("Burn");
            }
            if (clipLayers.length === 0) {
                alert("No layers to clip, please select a layer you would like to clip...");
                return;
            }

            var county = document.getElementById("sel_county").value
            var unit = document.getElementById("sel_unit").value
            var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Counties/MapServer/0");
            var queryTask1 = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
            queryTask.on("complete", addToMap)
            var query = new Query();
            query.returnGeometry = true;
            query.outFields = ["NAME_PCASE"];
            query.where = "NAME_PCASE = '" + county + "'";
            query.outSpatialReference = map.spatialReference;
            queryTask.execute(query, function (featureSet) {
                var AOI = featureSet.features[0].geometry;
                var graphic = new Graphic(AOI, symbol);
                var features = [];
                features.push(graphic);
                var fSet = new FeatureSet();
                fSet.features = features;


                var params = {
                    "Layers_to_Clip": clipLayers,
                    "Area_of_Interest": fSet,
                    "Feature_Format": registry.byId("formatBox").get("value")
                };



                domStyle.set(loading, "display", "inline-block");
                gp.submitJob(params, completeCallback, statusCallback, function (error) {
                    alert(error);
                    domStyle.set(loading, "display", "none");
                });
            });
            //}
            break;


        case "extractByUnit":
            //function executeQueryTask1(unit) {
            var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
                clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
                clipLayers.push("Burn");
            }
            if (clipLayers.length === 0) {
                alert("No layers to clip, please select a layer you would like to clip...");
                return;
            }

            var unit = document.getElementById("sel_unit").value
            var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
            queryTask.on("complete", addToMap2)
            var query = new Query();
            query.returnGeometry = true;
            query.outFields = ["UNITCODE"];
            query.where = "UNITCODE = '" + unit + "'";
            query.outSpatialReference = map.spatialReference;
            queryTask.execute(query, function (featureSet) {
                var AOI = featureSet.features[0].geometry;
                var graphic = new Graphic(AOI, symbol);
                var features = [];
                features.push(graphic);
                var fSet = new FeatureSet();
                fSet.features = features;


                var params2 = {
                    "Layers_to_Clip": clipLayers,
                    "Area_of_Interest": fSet,
                    "Feature_Format": registry.byId("formatBox").get("value")
                };



                domStyle.set(loading1, "display", "inline-block");
                gp.submitJob(params2, completeCallback, statusCallback1, function (error) {
                    alert(error);
                    domStyle.set(loading1, "display", "none");
                });
            });
            //}
    }
}
0 Kudos
AlexGole1
Emerging Contributor
The way you have it written, you're defining functions within each case, but never calling them. And be aware that the way it's currently written where you keep defining  the variable extractMethod, it will only run the "extractByUnit" method. This value should be set outside the function. Try something like this



Alright thanks to you! First a question. What is the logic behind removing the "excecuteQuerytasks" functions? Why cant we keep it the way it was?
Now, my scrip error is" addTomap is not define"

"addtomap" is a function that  i call outside the switch function.

Here is the rest of the script as I have it right now:
   case "extractByUnit":
            //function executeQueryTask1(unit) {
            var clipLayers = [];
            if (registry.byId("layer1").get("checked")) {
                clipLayers.push("SRA");
            }
            if (registry.byId("layer2").get("checked")) {
                clipLayers.push("Burn");
            }
            if (clipLayers.length === 0) {
                alert("No layers to clip, please select a layer you would like to clip...");
                return;
            }

            var unit = document.getElementById("sel_unit").value
            var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
            queryTask.on("complete", addToMap2)
            var query = new Query();
            query.returnGeometry = true;
            query.outFields = ["UNITCODE"];
            query.where = "UNITCODE = '" + unit + "'";
            query.outSpatialReference = map.spatialReference;
            queryTask.execute(query, function (featureSet) {
                var AOI = featureSet.features[0].geometry;
                var graphic = new Graphic(AOI, symbol);
                var features = [];
                features.push(graphic);
                var fSet = new FeatureSet();
                fSet.features = features;


                var params2 = {
                    "Layers_to_Clip": clipLayers,
                    "Area_of_Interest": fSet,
                    "Feature_Format": registry.byId("formatBox").get("value")
                };



                domStyle.set(loading1, "display", "inline-block");
                gp.submitJob(params2, completeCallback, statusCallback1, function (error) {
                    alert(error);
                    domStyle.set(loading1, "display", "none");
                });
            });
            //}
   break;
    }
}
    
    function addToMap(results){
    map.graphics.clear();
    var featureArray = results.featureSet.features;
          var feature = featureArray[0];
          var graph = map.graphics.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
    var extent = esri.graphicsExtent(map.graphics.graphics);
    map.setExtent(extent, true);
    
    }
    
    
    function addToMap2(results){
    map.graphics.clear();
    var featureArray = results.featureSet.features;
          var feature = featureArray[0];
          var graph = map.graphics.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
    var extent = esri.graphicsExtent(map.graphics.graphics);
    map.setExtent(extent, true);
    
    }
  
  
         function completeCallback(jobInfo) {
            if (jobInfo.jobStatus !== "esriJobFailed") {
               gp.getResultData(jobInfo.jobId, "output_zip", downloadFile);
            }
         }

         function statusCallback(jobInfo) {
          var status = jobInfo.jobStatus;
          if ( status === "esriJobFailed" ) {
            alert(status);
            domStyle.set("loading", "display", "none");
          }
          else if (status === "esriJobSucceeded"){
            domStyle.set("loading", "display", "none");
          }
        }
  function statusCallback1(jobInfo) {
          var status = jobInfo.jobStatus;
          if ( status === "esriJobFailed" ) {
            alert(status);
            domStyle.set("loading1", "display", "none");
          }
          else if (status === "esriJobSucceeded"){
            domStyle.set("loading1", "display", "none");
          }
        }
  function statusCallback2(jobInfo) {
          var status = jobInfo.jobStatus;
          if ( status === "esriJobFailed" ) {
            alert(status);
            domStyle.set("loading2", "display", "none");
          }
          else if (status === "esriJobSucceeded"){
            domStyle.set("loading2", "display", "none");
          }
        }
 
         function downloadFile(outputFile) {
            map.graphics.clear();
            var theurl = outputFile.value.url;
            window.location = theurl;
         }

Thank you again for your tremendous help!
0 Kudos
KenBuja
MVP Esteemed Contributor
You can define any sort of function you'd like, but until you call it, it won't do anything. You'd essentially have to do something like this

  case "extractByUnit":     executeQueryTask1(unit);     function executeQueryTask1(unit) {       var clipLayers = [];       if (registry.byId("layer1").get("checked")) {         clipLayers.push("SRA");       }       etc.


Here's an example showing the difference. Try clicking all three buttons to see what happens.

As for your "addTomap" error, you probably have the function name misspelled. But you say
"addtomap" is a function that  i call outside the switch function.

Remember that JavaScript is case sensitive.
0 Kudos