Select to view content in your preferred language

Problem with toolbar.deactivate(); method for draw toolbar

3623
9
Jump to solution
06-07-2013 02:24 PM
GISProgrammer
Deactivated User
I took a look at the drawing tools example and got it up and running fairly quickly (I seperated out the html code and the js code into two seperate files). 

I see the toolbar.deactivate(); method works in the example but I can't get it to work in my code.  I'm adding it everywhere and I even created a button to deactivate it. 

dojo.connect(dojo.byId("drawPolygon"),"click", function(){
         tb.deactivate();

http://developers.arcgis.com/en/javascript/jsapi/draw.html

It just doesn't work!

Here's my code

[HTML]

<!-- ******************** Spatial Select Button ***************************-->
       <div id="info">
      <div>Select a shape then draw on map to add graphic</div>
   
          <button id="deactivateDraw" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ initToolbar();}'>DeActivate</button>
    <button id="drawExtent" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ initToolbar();}'>Extent</button>
  
    
         <!--button id="drawPolygon" data-dojo-type="dijit.form.Button">Polygon</button-->
            
             
       </div>
       
<!-- ******************** End Spatail Select Button ***************************-->[/HTML]



 var tb; //toolbar for draw tools      //*************** TOOLBAR CODE ******************************   function initToolbar() {         tb = new esri.toolbars.Draw(map);         dojo.connect(tb, "onDrawEnd", addGraphic);             dojo.connect(dojo.byId("drawExtent"),"click", function(){           tb.activate(esri.toolbars.Draw.EXTENT);     map.hideZoomSlider();         });            dojo.connect(dojo.byId("deactivateDraw"),"click", function(){          tb.deactivate();          map.showZoomSlider();           });       }         //*************** END TOOLBAR CODE ******************************     function addGraphic(geometry) {         // try to deactivate the toolbar and clear existing graphics    var symbol;         tb.deactivate(); //doesn't work   map.showZoomSlider(); //works         map.graphics.clear(); //works          switch (geometry.type) {           case "point":           case "multipoint":             symbol = new esri.symbol.SimpleMarkerSymbol();             break;           case "polyline":             symbol = new esri.symbol.SimpleLineSymbol();             break;           default:             symbol = new esri.symbol.SimpleFillSymbol();             break;         }         var graphic = new esri.Graphic(geometry, symbol);         map.graphics.add(graphic);     tb.deactivate();            }  //*************** END TOOLBAR CODE ******************************
0 Kudos
1 Solution

Accepted Solutions
BenFousek
Deactivated User
A couple other things with your code that may or may not be causing problems.

1) You should be using dijit.byId() instead of dojo.byId(). dojo.byId() is for regular elements like '<div id="myDiv"></div>', while dijit.byId() should be used for dijits like '<div id="myDiv" data-dojo-type="dijit/form/Button"></div>'.

2) When you connect to a dijit the onClick event is 'onClick', not 'click'.

3) You don't need to recreate the toolbar every time. In your initialization code, after you have created the map, create the toolbar once using a global var like you have done. I create one toolbar and use it for everything that may need to draw, e.g. measurement, creating features, etc.

3) The onClick property in data-dojo-props does not need to be wrapped in a function or use parentheses if you are not passing variables.
[HTML]<div id="myDiv" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: myFunction "></div>[/HTML]

4) You should disconnect from events once they fire. The way your code is now every time the toolbar is initialized you add another identical 'onDrawEnd' listener. It's not that big of a deal if the user just performs 1 or 2 cycles through the task, but it adds up to decreased performance in a heavily used app.

Here's how I would do it with one function:
var map, tb; function init() {  //initialize the app    map = new esri.Map({});    tb = new esri.toolbars.Draw(map); }  function draw() {  tb.activate(esri.toolbars.Draw.EXTENT);  var conn = new dojo.connect(tb, 'onDrawEnd', function(evt) {   dojo.disconnect(conn); //disconnect      tb.deactivate();      map.graphics.clear();      //create and add graphic  }); }

View solution in original post

0 Kudos
9 Replies
ShreyasVakil
Frequent Contributor
after a quick scan through your code, I noticed that even on the onClick for the Deactivate button you are calling initToolBar() funtion which will again activate the toolbar.
 <button id="deactivateDraw" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ initToolbar();}'>DeActivate</button>


Write another function to deactivate the toolbar.

//*************** TOOLBAR CODE ******************************

 function initToolbar() {
        tb = new esri.toolbars.Draw(map);
        dojo.connect(tb, "onDrawEnd", addGraphic);
  

        dojo.connect(dojo.byId("drawExtent"),"click", function(){
          tb.activate(esri.toolbars.Draw.EXTENT);
    map.hideZoomSlider();
        });
}

function deactivateToolbar(){
 tb.deactivate(); 
        map.showZoomSlider(); 
}  
 


and in the HTML call that function on clicking the deactivate button:
 <button id="deactivateDraw" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:deactivateToolbar();'>DeActivate</button>


Let me know if it helps.
0 Kudos
GISProgrammer
Deactivated User
Shreyas,

Thanks for the reply.

I added your code and no luck...still doesn't work.  I know it is respecting the new function to deactivate because when I hit the deactivate button it shows the map zoom slider.  I also added a alert message just to make sure it hitting the method/button click and it is:

 function deactivateDrawToolbar(){
        tb.deactivate(); 
  window.alert('Yuup')
        map.showZoomSlider(); 
  }




In my previous post you can see I have the  tb.deactivate(); code in my addGraphic function.  I would like to just have it hear so and turn off the draw tools have the graphics are added so the endusers don't have to hit another button.  I only try to add a deactivate button to try and isolate the problem.

Any more ideas?

Thanks
0 Kudos
ShreyasVakil
Frequent Contributor
I created a sample application and it seems to be working:

<!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>Shapes and Symbols</title>

    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dojo/dijit/themes/nihilo/nihilo.css">
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/esri/css/esri.css">

    <style>
      #info {
        top: 20px;
        color: #444;
        height: auto;
        font-family: arial;
        right: 20px;
        margin: 5px;
        padding: 10px;
        position: absolute;
        width: 115px;
        z-index: 40;
        border: solid 2px #ccc;
        border-radius: 4px;
        background-color: #fff;
      }
      html,body,#mapDiv{
        padding:0;
        margin:0;
        height:100%;
      }

    </style>

    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.layers.agstiled");
      dojo.require("esri.toolbars.draw");

      var map, tb;

      function init() {

        map = new esri.Map("mapDiv", {
          basemap: "streets",
          center: [-25.312, 34.307],
          zoom: 3
        });
        dojo.connect(map, "onLoad", initToolbar);
      }

      function initToolbar() {
        tb = new esri.toolbars.Draw(map);
        dojo.connect(tb, "onDrawEnd", addGraphic);

        //hook up the button click events 
        dojo.connect(dojo.byId("drawPoint"),"click", function(){
          tb.activate(esri.toolbars.Draw.POINT);
        });
        
        dojo.connect(dojo.byId("drawPolygon"),"click", function(){
          tb.activate(esri.toolbars.Draw.POLYGON);
        });
       
        dojo.connect(dojo.byId("drawLine"),"click", function(){
          tb.activate(esri.toolbars.Draw.LINE);
        });
      }



      function addGraphic(geometry) {
        //deactivate the toolbar and clear existing graphics 
        tb.deactivate(); 
        map.graphics.clear();


        //Marker symbol used for point and multipoint created using svg path. See this site for more examples
        // http://raphaeljs.com/icons/#talkq. You could also create marker symbols using the SimpleMarkerSymbol class
        //to define color, size, style or the PictureMarkerSymbol class to specify an image to use for the symbol. 
        var markerSymbol = new esri.symbol.SimpleMarkerSymbol();
        markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");
        markerSymbol.setColor(new dojo.Color("#00FFFF"));


        //line symbol used for freehand polyline, polyline and line. In this example we'll use a cartographic line symbol
        //Try modifying the cartographic line symbol properties like CAP and JOIN. For CAP try CAP_ROUND or CAP_SQUARE
        //for JOIN try JOIN_BEVEL or JOIN_MITER or JOIN_ROUND
        var lineSymbol = new esri.symbol.CartographicLineSymbol(
          esri.symbol.CartographicLineSymbol.STYLE_SOLID,
          new dojo.Color([255,0,0]), 10, 
          esri.symbol.CartographicLineSymbol.CAP_ROUND,
          esri.symbol.CartographicLineSymbol.JOIN_MITER, 5
        );

        //fill symbol used for extent, polygon and freehand polygon. In this example we use a picture fill symbol
        //the images folder contains additional fill images - try swapping mangrove out for one of the other options
        //(sand, swamp or stiple)
        var fillSymbol = new esri.symbol.PictureFillSymbol("images/mangrove.png",
           new esri.symbol.SimpleLineSymbol(
            esri.symbol.SimpleLineSymbol.STYLE_SOLID,
             new dojo.Color('#000'), 1
            ), 42, 42
        );


        var type = geometry.type, symbol;
       /* if (type === "point" || type === "multipoint") {
          symbol = markerSymbol;
        }
        else if (type === "line" || type === "polyline") {
          symbol = lineSymbol;
        }
        else {
          symbol = fillSymbol;
        }*/
        
        switch (geometry.type) {
          case "point":
                      symbol = markerSymbol;
                      break;
          case "line":
                      symbol = lineSymbol;
                      break;
          default:
                      symbol = fillSymbol;
                      break;
        }

      //Add the graphic to the map 
       map.graphics.add(new esri.Graphic(geometry, symbol));
      }

     

      dojo.ready(init);
    </script>
  </head>
  <body class="nihilo">
    <div id="info">
      <div>Select a shape then draw on map to add graphic</div>
      <button id="drawPoint" data-dojo-type="dijit.form.Button">Point</button>
      <button id="drawPolygon" data-dojo-type="dijit.form.Button">Polygon</button>
      <button id="drawLine" data-dojo-type="dijit.form.Button">Line</button>
    </div>

    <div id="mapDiv"></div>



  </body>
</html>


Can you please test this sample and let me know if it works!

-Shreyas
0 Kudos
BenFousek
Deactivated User
A couple other things with your code that may or may not be causing problems.

1) You should be using dijit.byId() instead of dojo.byId(). dojo.byId() is for regular elements like '<div id="myDiv"></div>', while dijit.byId() should be used for dijits like '<div id="myDiv" data-dojo-type="dijit/form/Button"></div>'.

2) When you connect to a dijit the onClick event is 'onClick', not 'click'.

3) You don't need to recreate the toolbar every time. In your initialization code, after you have created the map, create the toolbar once using a global var like you have done. I create one toolbar and use it for everything that may need to draw, e.g. measurement, creating features, etc.

3) The onClick property in data-dojo-props does not need to be wrapped in a function or use parentheses if you are not passing variables.
[HTML]<div id="myDiv" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: myFunction "></div>[/HTML]

4) You should disconnect from events once they fire. The way your code is now every time the toolbar is initialized you add another identical 'onDrawEnd' listener. It's not that big of a deal if the user just performs 1 or 2 cycles through the task, but it adds up to decreased performance in a heavily used app.

Here's how I would do it with one function:
var map, tb; function init() {  //initialize the app    map = new esri.Map({});    tb = new esri.toolbars.Draw(map); }  function draw() {  tb.activate(esri.toolbars.Draw.EXTENT);  var conn = new dojo.connect(tb, 'onDrawEnd', function(evt) {   dojo.disconnect(conn); //disconnect      tb.deactivate();      map.graphics.clear();      //create and add graphic  }); }
0 Kudos
GISProgrammer
Deactivated User
Shreyas,

The sample works.  Looks the similar to the sample on ESRI resources JS page and that works too.  Something must be wrong with my code and I'm not sure???  I have some query tasks/buttons and if I migrate to API 3.3, 3.4, or 3.5 they break.  Currently they work at 3.2...just changing the api ref makes the buttons not work.  Not entirely sure what is happening.  I'm trying to separate all my code into different JS file (one for each tool/function) so I can reuse more easily in other apps.  Not sure??
0 Kudos
GISProgrammer
Deactivated User
Ben,

Thanks for all the suggestions that cleared a bunch stuff up for me.  I'm self taught and I appreciate it.

As I mentioned before I have a .js script firing in 3.2 API but it doesn't work in the 3.5 API and I'm not sure.  It seems like it fails at my switch statement.

Any ideas

var grid;
var txtType = "SIGNTYPE = ";  //String for Type Search
var txtDate = "DATEINST = TO_DATE(";  //String for Type Search
var txtFacId = "FACILITYID = ";  //String for Type Search
var queryTask; //Query Task
var query;  //Query Task


 
 function doSignTypeQuery() {


  query = new esri.tasks.Query();
     query.where = (txtType + "\'" + dojo.byId("SignQuery").value + "\'").toString();
        // //execute query
     queryTask.execute(query,showFResults);
   }
   
  function doDateQuery() {
         query = new esri.tasks.Query();
      query.where = (txtDate + "\'" + dojo.byId("DateQuery").value + " 00:00:00\',\'YYYY-MM-DD HH24:MI:SS\')").toString();
        //execute query
        queryTask.execute(query,showQResults);
  }
      
  function doFacIdQuery() {
        query = new esri.tasks.Query();
     query.where = (txtFacId + "\'" + dojo.byId("FacIdQuery").value + "\'").toString();
        //execute query
        queryTask.execute(query,showFResults);
  }
      
      
   
      
      
      function showFResults(results) {
       
   //remove all graphics on the maps graphics layer
    map.graphics.clear();
    esri.hide(dojo.byId("gridsup"));
    esri.show(dojo.byId("grid"));
     
        var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98,194,204]), 2), new dojo.Color([98,194,204,0.5]));
        var markerSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 255]), 1), new dojo.Color([0, 255, 0, 0.25]));
        var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 1);
  

     dojo.forEach(results.features, function (feature) {
                    var graphic = feature;
                    switch (graphic.geometry.type) { //Here's where my problem is???
               case "point":
                 graphic.setSymbol(markerSymbol);
                 break;
               case "polyline":
                 graphic.setSymbol(lineSymbol);
                 break;
               case "polygon":
                 graphic.setSymbol(polygonSymbol);
                 break;
               }
               
               // //Set the infoTemplate.
            //  graphic.setInfoTemplate(SignInfoTemplate);
               
               //Add graphic to map
         
                    map.graphics.add(graphic);
                   // return feature.attributes;
                    items.push(feature.attributes);
                });
     
 
 
       //Create data object to be used in store
        var data = {
          identifier: "OBJECTID",  //This field needs to have unique values
          label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

 
         //Create data store and bind to grid.
        store = new dojo.data.ItemFileReadStore({ data:data });
        grid = dijit.byId('grid');
        grid.setStore(store);
  

    
        //+++++++++++++++++++++++++ Zoom back to extent of graphics selected ++++++++++++++++++++++++++++++++++
        
        //Check to see if there is only one graphic 
  
         for (var i=0, il=results.features.length; i<il; i++) {
          dojo.forEach(map.graphics.graphics,function(graphic){
            g = graphic; 
   
            return;    
          });
         }
         
         //if only one graphic and graphic is a point then go to the extent of that graphic 
        if (g.geometry.type === "point" &&  i===1)
        {
        var pExtent = new esri.geometry.Extent({"xmin":g.geometry.x - 500,"ymin":g.geometry.y - 500,"xmax":g.geometry.x + 500,"ymax":g.geometry.y + 500,"spatialReference":{"wkid":g.geometry.spatialReference.wkid}});
      map.setExtent(pExtent);
    }
    else  //go to the extent of all the graphics
    {
         var graphicExtent = esri.graphicsExtent(map.graphics.graphics);
       map.setExtent(graphicExtent);
      };
     
  
     //***************END Zoom back to extent of graphics selected ++++++++++++++++++++++++//////////
    
      }
   

0 Kudos
BenFousek
Deactivated User
I have all but given up on switch. Kept running into unexplained problems. This is out of an identify task, but same concept.

var feature = results[0].feature;
var atts = feature.attributes;
var type = feature.geometry.type;
if (type == 'point') {
 var sym = POINT_SYMBOL
} else if (type == 'polyline') {
 var sym = POlYLINE_SYMBOL
} else if (type == 'polygon') {
 var sym = POLYGON_SYMBOL
}
var graphic = new esri.Graphic(feature.geometry, sym, atts, null);


Also, I always create an esri.Graphic.
0 Kudos
GISProgrammer
Deactivated User
Ben,

Thanks for the heads up but that didn't help.  I'm using the same basic switch state for my find and addrss search task and they work.  I reworte using the if / if else statements and same result.  The grid opens but never populates and the features never get selected so the map doesn't zoom. For some reasone all my query tasks break if I move out of 3.2...hence the reason why I never update.  I'm been dealing with this issue since 3.3 and I've spent days on it.  I guess I might start another post and post all my code on that new thread to see if ESRI can help.

Thanks
0 Kudos
KellyHutchins
Esri Frequent Contributor
Check out the list of breaking changes between version 3.2 and 3.3 here.

http://developers.arcgis.com/en/javascript/jshelp/new_v33.html


If they don't help resolve your upgrade issue can you post a simplified version of your problem code?

Kelly
0 Kudos