Question

I have code ArcGIS Javascript like this:

<script type="text/javascript">
      require(["dojo/ready",
      "dgrid/OnDemandGrid",
      "dgrid/Selection",
      "dojo/store/Memory", 
      "dojo/_base/array",
      "dojo/dom-style",
      "dijit/registry",
      "esri/map", 
      "esri/dijit/Popup",
      "esri/dijit/PopupTemplate",
      "esri/layers/FeatureLayer",
      "dojo/dom-class",
      "dojo/dom-construct",
      "dojo/on", 
      "esri/InfoTemplate",
      "esri/symbols/SimpleLineSymbol",
      "esri/symbols/SimpleFillSymbol",
      "esri/tasks/QueryTask",
      "esri/tasks/query",
      "dojo/_base/declare", 
      "dojo/number", 
      "dojo/on",
      "dojox/charting/Chart",
      "esri/renderers/UniqueValueRenderer",
      "dojo/parser",
      "dojo/_base/Color", 
      "dijit/layout/BorderContainer",
      "dijit/layout/ContentPane"
      ], function (
        ready,
        Grid, 
        Selection, 
        Memory, 
        array,
        domStyle,
        registry,
        Map,
        Popup,
        PopupTemplate, 
        FeatureLayer,
        domClass,
        domConstruct,
        on, 
        InfoTemplate,
        SimpleLineSymbol,
        SimpleFillSymbol,
        QueryTask,
        Query,
        declare, 
        dojoNum, 
        on,
        Chart, 
        UniqueValueRenderer,
        parser
      ) {
        ready(function() {

          parser.parse();

          var popup = Popup({
            titleInBody: false
          },domConstruct.create("div"));

          // create the dgrid
          window.grid = new (declare([Grid, Selection]))({
            // use Infinity so that all data is available in the grid
            bufferRows: Infinity,
            columns: {
              "FID": "FID",
              "PROV": "PROV"
            }
          }, "grid");
          // add a click listener on the ID column
          grid.on(".field-id:click", selectState);

          var initialExtent = new esri.geometry.Extent({"xmin":89.971,"ymin":-12.472,"xmax":144.301,"ymax":9.511,"spatialReference":{"wkid":4326}});
          map = new esri.Map("map", { extent: initialExtent,infoWindow: popup});

          //var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer");
          var basemap2 = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer",{"opacity":0.4});
          map.addLayer(basemap2);
          //map.addLayer(basemap);


          domClass.add(window.map.infoWindow.domNode, "myTheme");
            var template = new PopupTemplate({
            title: "Data Luas Lahan Sawah {PROV}",
            description: "of starters from {PROV} finished",
          });

          window.statesUrl = "http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer/8";
          window.outFields = ["FID","PROV"];

          var fl = new FeatureLayer(window.statesUrl, {
            id: "stat",
            mode: 1, // ONDEMAND, could also use FeatureLayer.MODE_ONDEMAND
            infoTemplate:template,
            outFields: window.outFields
          });

          fl.on("load", function() {
            fl.maxScale = 0; // show the states layer at all scales
            fl.setSelectionSymbol(new SimpleFillSymbol().setOutline(null).setColor("#AEC7E3"));
          });

          fl.on("click", selectGrid);

          // change cursor to indicate features are click-able
          fl.on("mouse-over", function() {
            map.setMapCursor("pointer");
          });
          fl.on("mouse-out", function() {
            map.setMapCursor("default");
          });


          map.addLayer(fl);

          map.on("load", 
            function addFeatureLayer() {
              var defaultSymbol = new SimpleFillSymbol().setStyle(SimpleFillSymbol.STYLE_NULL);
              defaultSymbol.outline.setStyle(SimpleLineSymbol.STYLE_NULL);

              //create renderer
              var renderer = new UniqueValueRenderer(defaultSymbol, "PROV");

              //add symbol for each possible value
              renderer.addValue("Banten", new SimpleFillSymbol().setColor("#00FA1D"));
              renderer.addValue("Dki Jakarta", new SimpleFillSymbol().setColor("#FA0000"));
              renderer.addValue("Jawa Barat", new SimpleFillSymbol().setColor("#FAFA00"));
              renderer.addValue("Jawa Tengah", new SimpleFillSymbol().setColor("#00FA1D"));
              renderer.addValue("Daerah Istimewa Yogyakarta", new SimpleFillSymbol().setColor("#FAFA00"));
              renderer.addValue("Jawa Timur", new SimpleFillSymbol().setColor("#FAFA00"));
              var template = new PopupTemplate({
                title: "Data {PROV}",
                description: "Data Luas Lahan Sawah {PROV}",
              });
              var featureLayer = new FeatureLayer("http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer/8", {
                mode: 1, // ONDEMAND, could also use FeatureLayer.MODE_ONDEMAND
                infoTemplate:template,
                outFields: window.outFields
              });

              featureLayer.setRenderer(renderer);
              map.addLayer(featureLayer);
            } ,
            function( evt ){
              // show the border container now that the dijits 
              // are rendered and the map has loaded
              domStyle.set(registry.byId("container").domNode, "visibility", "visible");
              populateGrid(Memory); // pass a reference to the MemoryStore constructor
          });

          function populateGrid(Memory) {
            var qt = new QueryTask(window.statesUrl);
            var query = new Query();
            query.where = "1=1";
            query.returnGeometry = false;
            query.outFields = window.outFields;
            qt.execute(query, function(results) {
              var data = array.map(results.features, function(feature) {
                return {
                  // property names used here match those used when creating the dgrid
                  "FID": feature.attributes[window.outFields[0]],
                  "PROV": feature.attributes[window.outFields[1]]
                }
              });
              var memStore = new Memory({ data: data });
              window.grid.set("store", memStore);
            });
          }
          // fires when a row in the dgrid is clicked
          function selectState(e) {
            // select the feature
            var fl = map.getLayer("stat");
            var query = new Query();
            query.objectIds = [parseInt(e.target.innerHTML)];
            fl.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(result) {
              if ( result.length ) {
                // re-center the map to the selected feature
                window.map.centerAt(result[0].geometry.getExtent().getCenter());
              } else {
                console.log("Feature Layer query returned no features... ", result);
              }
            });
          }

          // fires when a feature on the map is clicked
          function selectGrid(e) {
            var profinsi = e.graphic.attributes.PROV;
            var id = e.graphic.attributes.FID;
            // select the feature that was clicked
            var query = new Query();
            query.objectIds = [id];
            var states = map.getLayer("stat");
            states.selectFeatures(query, FeatureLayer.SELECTION_NEW);
            // select the corresponding row in the grid
            // and make sure it is in view
            grid.clearSelection();
            grid.select(id);
          }

          function test(){
            alert("alert");
          }
        });
    });
</script>

I want call function inside dojo.ready function. For example, I want call function test() with onclick with this:

<input type="submit" value="Submit" onclick="test();">

but still not work.
Can anybody help me explain how to call function inside dojo.ready?

Was it helpful?

Solution

That's because it's a bad practice to write event handlers in your document. If you add functions inside functions, they're scoped to that function (that means, they're only accessible from inside the ready() function and not from the DOM (= from the HTML page).

In normal words: "the button cannot see function test()".

You can solve that in two ways:

The first way is byglobally scoping the test() function by moving it out of the ready() callback or by replacing the function by this:

test = function() {
    alert("alert");
};

Because you're not putting a var in front of the test variable, it means it's globally scoped now, which means it can be accessed from the DOM. However, I do not recommend it, it's considered a bad practice. Googling "why global variables are bad javascript" gives you an overview of why it's bad.


The second possibility is by moving the event declaration itself in the ready() scope, by using the dojo/on module or the dojo/query module, for example:

require(["dojo/ready", "dojo/query"], function(ready, query) {
    ready(function() {
        query("input[type=\"submit\"]").on("click", test);

        function test() {
            alert("test");
        }
    });
});

And a JSFiddle: http://jsfiddle.net/g00glen00b/tLN5b/

This can be considered a better practice because you're not using the global namespace and you can define event handlers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top