Link to home
Start Free TrialLog in
Avatar of flfmmqp
flfmmqp

asked on

Coding Javascript into chunks

I'm creating a web mapping interface that is using some html and javascript along with dojo.  

I am in the process of creating some different functions that will be put into buttons.  I don't want all of the code in one place where it gets confusing to follow.  I want to put each buttons code in a module and call it.  Kind of like you do for CSS.  
 <link rel="stylesheet" type="text/css" href="myWidgets/Buffer_Customers/buffer_customers.css" />

I don't know anything about creating diggits and would like to shy away from that as it looks confusing.  

My page at the moment is pretty simple.  It has a toggle button that when you click on it you can click on the map - get a .25 mile buffer - and then it reports data back on the map.  

The code below should work for anyone wanting to try and help.  

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Select with feature layer</title>
    <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/dojo/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/esri/css/esri.css">
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dijit/themes/claro/claro.css" media="screen">

<style>
    
	html, body, #mapDiv {
    padding: 0;
    margin: 0;
    height: 100%;
}
#messages {
    background-color: #fff;
    box-shadow: 0 0 5px #888;
    font-size: 1.1em;
    max-width: 15em;
    padding: 0.5em;
    position: absolute;
    right: 20px;
    top: 20px;
    z-index: 40;
}
	
    </style>	
	
	<script src="http://js.arcgis.com/3.9/"></script>
    <script>
      var map;
 
      require([
        "esri/map", "esri/layers/FeatureLayer", 
        "dijit/form/ToggleButton",
        "esri/tasks/query", "esri/geometry/Circle",
        "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
        "esri/config", "esri/Color", "dojo/parser", "dojo/dom", "dojo/on", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        ToggleButton,
        Query, Circle,
        Graphic, InfoTemplate, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        esriConfig, Color, parser, dom, on
      ) {

        esriConfig.defaults.io.proxyUrl = "/proxy";
        
        parser.parse();
//"xmin":-13587617,"ymin":4564540,"xmax":-13587178,"ymax":4564976
        map = new Map("mapDiv", { 
          basemap: "streets",
          center: [-73.9890,40.7504],
          zoom: 17,
          slider: false
        });
        var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{
          infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
          outFields: ["POP2000","HOUSEHOLDS","HSE_UNITS", "TRACT", "BLOCK"]
        });
        // selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE, 
          12, 
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL, 
            new Color([247, 34, 101, 0.9]), 
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol); 
        
        //make unselected features invisible
        var nullSymbol = new SimpleMarkerSymbol().setSize(1);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
        
        map.addLayer(featureLayer);
        
        var circleSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
          ), new Color([255, 255, 0, 0.25])
        );
        var circle;
        
        
        new ToggleButton({
          showLabel: true,
          onChange: function(val){            
            if(val == true){
			  document.getElementById("messages").style.display = 'block'
			  buffer = map.on("click", function(evt){
                circle = new Circle({
                center: evt.mapPoint,
                geodesic: true,
                radius: .1,
                radiusUnit: "esriMiles"
              });
              //Being used 
			  map.graphics.clear();
              map.infoWindow.hide();
              var graphic = new Graphic(circle, circleSymb);
              map.graphics.add(graphic);

              var query = new Query();
              query.geometry = circle.getExtent();
              //use a fast bounding box query. will only go to the server if bounding box is outside of the visible map
              featureLayer.queryFeatures(query, selectInBuffer);
            });
            this.set('label', 'Close Buffer Report Tool');
           }
           else{
			map.graphics.clear();
            featureLayer.clearSelection();
            buffer.remove();             
            document.getElementById("messages").style.display = 'none'
			this.set('label', 'Open Buffer Report Tool');
			
			dom.byId("messages").innerHTML = "Click on the map <br> to select 1 mile buffer.";
           }
          },
          label: "Open Buffer Report Tool"
        }, "btnBufferTool");
                

        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];
          //filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
          for (var i = 0; i < features.length; i++) {
            feature = features[i];
            if(circle.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
          //use a fast objectIds selection query (should not need to go to the server)
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            //var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the buffer is <i>" + sumPopulation(results) + "</i>.</b>";
            dom.byId("messages").innerHTML = r;
          });
        }
        
        function sumPopulation(features) {
          var popTotal = 0;
          for (var x = 0; x < features.length; x++) {
            popTotal = popTotal + features[x].attributes["POP2000"];
          }
          return popTotal;
        }

      });
	  
    </script>
  </head>

  <body class="claro">
    <span id="messages" >Click on the map <br> to select 1 mile buffer.</span>
   
    <div id="mapDiv">
      <button id="btnBufferTool"></button>
    </div>
  </body>
</html>

Open in new window

Avatar of Ken Butters
Ken Butters
Flag of United States of America image

so... what is the question?

Sounded to me like you wanted to know how to put javascript in an external file... but you already have an example of that in the code you posted:
<script src="http://js.arcgis.com/3.9/"></script>

Open in new window

Avatar of flfmmqp
flfmmqp

ASKER

Not really that is not my code.    I need that for the map I am creating.  Basically what I am trying to do is seperate my Toggle button and its functions in another file.  This way my main html stays clean and I can use that button in multiple projects.
you can follow the example of the arcquis script, just create your own file and make a reference to it. Then you just treat that file like you would a javascript block.

for example, create a sub folder in your site called js and create a file called pageFuncs.js. Then, in your <head> section of your html page, you would create a reference to it like this:

<script src="/js/commonFuncs.js"></script>

then, in commonFuncs.js, move your javascript over to the file so that the contents of the js file is as follows:

      var map;
 
      require([
        "esri/map", "esri/layers/FeatureLayer", 
        "dijit/form/ToggleButton",
        "esri/tasks/query", "esri/geometry/Circle",
        "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
        "esri/config", "esri/Color", "dojo/parser", "dojo/dom", "dojo/on", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        ToggleButton,
        Query, Circle,
        Graphic, InfoTemplate, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        esriConfig, Color, parser, dom, on
      ) {

        esriConfig.defaults.io.proxyUrl = "/proxy";
        
        parser.parse();
//"xmin":-13587617,"ymin":4564540,"xmax":-13587178,"ymax":4564976
        map = new Map("mapDiv", { 
          basemap: "streets",
          center: [-73.9890,40.7504],
          zoom: 17,
          slider: false
        });
        var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{
          infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
          outFields: ["POP2000","HOUSEHOLDS","HSE_UNITS", "TRACT", "BLOCK"]
        });
        // selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE, 
          12, 
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL, 
            new Color([247, 34, 101, 0.9]), 
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol); 
        
        //make unselected features invisible
        var nullSymbol = new SimpleMarkerSymbol().setSize(1);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
        
        map.addLayer(featureLayer);
        
        var circleSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
          ), new Color([255, 255, 0, 0.25])
        );
        var circle;
        
        
        new ToggleButton({
          showLabel: true,
          onChange: function(val){            
            if(val == true){
			  document.getElementById("messages").style.display = 'block'
			  buffer = map.on("click", function(evt){
                circle = new Circle({
                center: evt.mapPoint,
                geodesic: true,
                radius: .1,
                radiusUnit: "esriMiles"
              });
              //Being used 
			  map.graphics.clear();
              map.infoWindow.hide();
              var graphic = new Graphic(circle, circleSymb);
              map.graphics.add(graphic);

              var query = new Query();
              query.geometry = circle.getExtent();
              //use a fast bounding box query. will only go to the server if bounding box is outside of the visible map
              featureLayer.queryFeatures(query, selectInBuffer);
            });
            this.set('label', 'Close Buffer Report Tool');
           }
           else{
			map.graphics.clear();
            featureLayer.clearSelection();
            buffer.remove();             
            document.getElementById("messages").style.display = 'none'
			this.set('label', 'Open Buffer Report Tool');
			
			dom.byId("messages").innerHTML = "Click on the map <br> to select 1 mile buffer.";
           }
          },
          label: "Open Buffer Report Tool"
        }, "btnBufferTool");
                

        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];
          //filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
          for (var i = 0; i < features.length; i++) {
            feature = features[i];
            if(circle.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
          //use a fast objectIds selection query (should not need to go to the server)
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            //var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the buffer is <i>" + sumPopulation(results) + "</i>.</b>";
            dom.byId("messages").innerHTML = r;
          });
        }
        
        function sumPopulation(features) {
          var popTotal = 0;
          for (var x = 0; x < features.length; x++) {
            popTotal = popTotal + features[x].attributes["POP2000"];
          }
          return popTotal;
        }

      });
	  

Open in new window

forgot to mention, the folder and file names can be whatever you want, I was just using that as an example
Avatar of flfmmqp

ASKER

Hmm I tried that but it does not seem to be working for me.
Avatar of flfmmqp

ASKER

Here are the parts as I broke them down.  

http://jsfiddle.net/bearcatrunner/ybS9F/

I created the following path "myWidgets\Buffer_Customers\" and then two files buffer_customers.css and buffer_customers.js

So in my html file I have added      <link rel="stylesheet" href="myWidgets\Buffer_Customers\buffer_customers.css">
<script src="myWidgets\Buffer_Customers\buffer_customers.js"></script>
you have to use relative paths, change your reference to:

<link rel="stylesheet" href="/myWidgets/Buffer_Customers/buffer_customers.css">
<script src="/myWidgets/Buffer_Customers/buffer_customers.js"></script>
Avatar of flfmmqp

ASKER

I tried that but is not working.  If you copy the code and break it up does it work for you?
i don't have somewhere i can test it right now, do you have a link you can share?
Avatar of flfmmqp

ASKER

The closest I have is this - http://jsfiddle.net/bearcatrunner/ybS9F/1/

All of our stuff sits behind the firewall so I made this example so that the only difference is the layer I am using is public and not behind our firewall.
and if you move your javascript to a js file and reference that in the html is the jsfiddle, does it work?
Avatar of flfmmqp

ASKER

Everything seems to work in jsfiddle just fine but I don't think jsfiddle looks at the references as it already knows that the three pieces of code are supposed to work together.  Not sure how all of that works but that is how I understand it.
if it works in jsfiddle then the only thing I can think of is that the relative path is inaccurate.

Relative meaning... you need to specify the src attribute in the HTML file so the when the HTML file is read, the Javascript file can be found.

You mentioned where you javascript file resides in your earlier post.
<script src="myWidgets\Buffer_Customers\buffer_customers.js"></script>

Where is your HTML file in relation to the buffer_customers.js file?
Is this CSS file being read and processed correctly?

<link rel="stylesheet" href="myWidgets\Buffer_Customers\buffer_customers.css">

judging from the href links specified here... your HTML file would have to stored in the the same folder/directory as the "myWidgets" folder.  Is that what you have?

Also, can you try using forward slashes instead?  (like this)
<script src="myWidgets/Buffer_Customers/buffer_customers.js"></script>
One other thing I noticed... on your CSS links.... I'd close your tag with a closing forward slash... ( /> )

Like this:
<link rel="stylesheet" href="http://js.arcgis.com/3.9/js/dojo/dijit/themes/tundra/tundra.css" />

It shouldn't matter... just trying to be extra picky since it isn't working.
Avatar of flfmmqp

ASKER

Yes all three are in the same folder for testing.  I've added them in a zip file that I attached along with a file called buffer_customers_All_In_One.html which is the whole application in one file so you can see that it works.  Then I have the three files html, css, js that I am trying to use to break it down.  

Can one of you take a look at this and see if you can get it to work.  I think it will be a very simple task for you.  I'm just struggling with it.  I'm sure I'm just missing a slash here or a something there.  

Thanks,

Michael
no attachment :)
ASKER CERTIFIED SOLUTION
Avatar of Ken Butters
Ken Butters
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of flfmmqp

ASKER

Thanks that really helped.
what was the issue?