Solved

Coding Javascript into chunks

Posted on 2014-04-17
19
838 Views
Last Modified: 2014-04-18
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

0
Comment
Question by:flfmmqp
  • 8
  • 7
  • 4
19 Comments
 
LVL 19

Expert Comment

by:Ken Butters
Comment Utility
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

0
 

Author Comment

by:flfmmqp
Comment Utility
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.
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
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

0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
forgot to mention, the folder and file names can be whatever you want, I was just using that as an example
0
 

Author Comment

by:flfmmqp
Comment Utility
Hmm I tried that but it does not seem to be working for me.
0
 

Author Comment

by:flfmmqp
Comment Utility
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>
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
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>
0
 

Author Comment

by:flfmmqp
Comment Utility
I tried that but is not working.  If you copy the code and break it up does it work for you?
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
i don't have somewhere i can test it right now, do you have a link you can share?
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:flfmmqp
Comment Utility
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.
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
and if you move your javascript to a js file and reference that in the html is the jsfiddle, does it work?
0
 

Author Comment

by:flfmmqp
Comment Utility
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.
0
 
LVL 19

Expert Comment

by:Ken Butters
Comment Utility
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>
0
 
LVL 19

Expert Comment

by:Ken Butters
Comment Utility
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.
0
 

Author Comment

by:flfmmqp
Comment Utility
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
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
no attachment :)
0
 
LVL 19

Accepted Solution

by:
Ken Butters earned 500 total points
Comment Utility
Based on your previous posts... I'm attaching a zip file that contains the files...

Note where the files are located in the directories in relation to one another.

I created a new toplevel diretory called Q_2841872.  You can make that directory anything you want... but everything else inside that directory has to be the same.

If you want to move the files around... then you'd need to change the src= and/or href= attributes to match the change.
Q-28414872.zip
0
 

Author Closing Comment

by:flfmmqp
Comment Utility
Thanks that really helped.
0
 
LVL 32

Expert Comment

by:Big Monty
Comment Utility
what was the issue?
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
This article discusses how to create an extensible mechanism for linked drop downs.
In this tutorial viewers will learn how to style transparent/translucent elements using alpha transparency in CSS Start with a normal styled element, such as a div.: Define its "background-color" property as "rgba (255, 255, 255, .5): The numbers in…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now