I just want to use part of the drawbox dijit but cant call my function from the widget HTML

2359
20
Jump to solution
08-22-2019 04:16 AM
JamesHone1
New Contributor III

HI m making use of the drawbox dijit but I dont want my users to have access to all the drawing options.

After looking at the drawbox dijit it seems I just want to call "this.drawBox.activate('EXTENT')" then I can do stuff _onDrawComplete.

but Im not sure why I cant call my function from the HTML.

Hers my js, Im trying to call the grabArea function from my HTML

define(['dojo/_base/declare',
	'jimu/BaseWidget',
  	'dijit/_WidgetsInTemplateMixin',
  	'dojo/_base/html',
	'dojo/_base/lang',
	'dojo/on',
	'jimu/dijit/drawbox',
],
function(declare, BaseWidget, _WidgetsInTemplateMixin, html, lang, on, Drawbox) {
	var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {

		baseClass: 'jimu-widget-JimDrawbox',

		name: 'JimDrawbox',

		drawBox: null,


		_initStuff: function(){
        	this.drawBox = new Drawbox;
		},

      	postCreate: function() {
        	this.inherited(arguments);
        	this._initStuff();
        	this.drawBox.setMap(this.map);
        	this.drawBox.types = ["EXTENT"];
        	this.drawBox.keepOneGraphic = true;
        	this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
        	console.log(this.drawBox.types)

        	//this.drawBox.activate('EXTENT')
      	},

      	grabArea: function() {
      		this.drawBox.activate('EXTENT')
      	},

      	_onDrawComplete: function(graphic) {
      		var geometry = graphic.geometry;
      		console.log(geometry);

      	}

	});

And here's my HTML

<div>
	<button class ="button" onclick="this.grabArea()">Click to draw extent</button>
</div>

I just keep getting

Uncaught TypeError: this.grabArea is not a function
at HTMLButtonElement.onclick

So it seems my grabArea function isnt visible to the HTML at that point, but I'm not sure why.

JS isnt my main language so Im struggling a bit to resolve it.

Finding WAB one of the hardest frameworks I've come across to decipher so far...

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

James,

  When building widgets you need to get use to using the data-dojo-attach-point property in your html code:

<div>
     <button class="button" data-dojo-attach-point="drawBtn">Click to draw extent</button>
</div>

js code

define(['dojo/_base/declare',
    'jimu/BaseWidget',
    'dijit/_WidgetsInTemplateMixin',
    'dojo/_base/html',
    'dojo/_base/lang',
    'dojo/on',
    'jimu/dijit/drawbox'
  ],
  function (declare, BaseWidget, _WidgetsInTemplateMixin, html, lang, on, Drawbox) {
    var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {

      baseClass: 'jimu-widget-JimDrawbox',
      name: 'JimDrawbox',
      drawBox: null,

      postCreate: function () {
        this.inherited(arguments);
        this.own(on(this.drawBtn, "click", lang.hitch(this, this.grabArea)));
        this.drawBox = new Drawbox;
        this.drawBox.setMap(this.map);
        this.drawBox.types = ["EXTENT"];
        this.drawBox.keepOneGraphic = true;
        this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
      },

      grabArea: function () {
        this.drawBox.activate('EXTENT')
      },

      _onDrawComplete: function (graphic) {
        var geometry = graphic.geometry;
        console.log(geometry);
      }
    });
  });

Are you sure you want your UI to have a simple button with text? Why not just use the drawBox in your widget with only the extent button available?

View solution in original post

20 Replies
JamesHone1
New Contributor III

so I think the problem is that  my function is set in the local scope of the require callback so its unavailable in the global scope, but I dont know how I make it available, have I got to attach the button click event during postcreate somehow?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

James,

  When building widgets you need to get use to using the data-dojo-attach-point property in your html code:

<div>
     <button class="button" data-dojo-attach-point="drawBtn">Click to draw extent</button>
</div>

js code

define(['dojo/_base/declare',
    'jimu/BaseWidget',
    'dijit/_WidgetsInTemplateMixin',
    'dojo/_base/html',
    'dojo/_base/lang',
    'dojo/on',
    'jimu/dijit/drawbox'
  ],
  function (declare, BaseWidget, _WidgetsInTemplateMixin, html, lang, on, Drawbox) {
    var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {

      baseClass: 'jimu-widget-JimDrawbox',
      name: 'JimDrawbox',
      drawBox: null,

      postCreate: function () {
        this.inherited(arguments);
        this.own(on(this.drawBtn, "click", lang.hitch(this, this.grabArea)));
        this.drawBox = new Drawbox;
        this.drawBox.setMap(this.map);
        this.drawBox.types = ["EXTENT"];
        this.drawBox.keepOneGraphic = true;
        this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
      },

      grabArea: function () {
        this.drawBox.activate('EXTENT')
      },

      _onDrawComplete: function (graphic) {
        var geometry = graphic.geometry;
        console.log(geometry);
      }
    });
  });

Are you sure you want your UI to have a simple button with text? Why not just use the drawBox in your widget with only the extent button available?

JamesHone1
New Contributor III

hi Robert, that is kinda what I would really like to do but I couldnt decipher the drawbox widget enough to only display the extent option. I thought of just taking the whole thing end editing the dijit HTML to only leave that item but ended up going down thgis route. I had got a bit closer to the answer just now, realise I needed to use on and a data attach point but still got the following error

'init.js:115 TypeError: Cannot read property 'on' of null' seems I was missing the this.own stuff.

heres where I ended up before reading your post

postCreate: function() {
        	this.inherited(arguments);
        	this._initStuff();
        	this.drawBox.setMap(this.map);
        	this.drawBox.types = ["EXTENT"];
        	this.drawBox.keepOneGraphic = true;
        	this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
        	console.log(this.drawBox.types)

        	var getareabutton = dom.byId('getareabutton');

        	on(getareabutton, "click", function(evt){
        		this.grabArea();
        	})

        	console.log(getareabutton)
      	},

      	grabArea: function() {
      		this.drawBox.activate('EXTENT')
      	},

I need to read up a bit on the lang hitch thing I think and learn when to use this.own

I tried the plan of just using the drawbox as you describer but couldnt work out how to instantiate it with only the extent available unless I took a copy of the whole dijit and just edited the HTML to leave only that one, seemed like the wrong way to do it to me and I would have a dijit with loads on unused code in my widget.

Is there a way to configure the dijit when you creeate it to only have the extent?

Thanks for the help!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

James,

Is there a way to configure the dijit when you create it to only have the extent?

Absolutely. In your widget.html

<div data-dojo-attach-point="drawBox" data-dojo-type="jimu/dijit/DrawBox" data-dojo-props="types:['extent'],showClear:false" style="margin-top:5px;"></div>
JamesHone1
New Contributor III

thanks, I think I did try something similar to this but I tried setting the props in the js rather than the html and didnt get it to work, I willgive this one a go.

0 Kudos
JamesHone1
New Contributor III

I have tried that method but whenever I add that line to my html it ends up with. 

'init.js:115 Error: dijit._WidgetsInTemplateMixin: parser returned unfilled promise (probably waiting for module auto-load), unsupported by _WidgetsInTemplateMixin.   Must pre-load all supporting widgets before instantiation.'

This one has really confused me a bit, googling it it seems something to fdo wiht define/require being incorrect but I cant see the problem.

<div>
	<div data-dojo-attach-point="drawBox" data-dojo-type="jimu/dijit/DrawBox" data-dojo-props="types:['extent'],showClear:false" style="margin-top:5px;"></div>
	<button class="button" data-dojo-attach-point="getareabutton">Click to draw extent</button>
	<div data dojo attach point="selectionmenu"></div> 
</div>
define(['dojo/_base/declare',
	'jimu/BaseWidget',
  	'dijit/_WidgetsInTemplateMixin',
  	'dojo/_base/html',
	'dojo/_base/lang',
	'dojo/on',
	'jimu/dijit/drawbox',
	'dojo/dom'
],
function(declare, BaseWidget, _WidgetsInTemplateMixin, html, lang, on, Drawbox, dom) {
	var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {

		baseClass: 'jimu-widget-JimDrawbox',

		name: 'JimDrawbox',

		drawBox: null,


		_initStuff: function(){
        	this.drawBox = new Drawbox;
		},

      	postCreate: function() {
        	this.inherited(arguments);
        	this._initStuff();
        	this.drawBox.setMap(this.map);
        	this.drawBox.types = ["EXTENT"];
        	this.drawBox.keepOneGraphic = true;
        	this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
        		
        	html.place(this.drawBox.domNode, this.drawBox);

        	this.own(on(this.getareabutton, 'click', lang.hitch(this, this._grabArea)));
      	},

      	_grabArea: function() {
      		this.drawBox.activate('EXTENT')
      	},

      	_onDrawComplete: function(graphic) {
      		var geometry = graphic.geometry;
      		this.drawBox.deactivate();
      		console.log(geometry);

      	}

	});

  	return clazz;
});
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

James,

  That is because you have the CaSe of the DrawBox dijit wrong in your require array.

JamesHone1
New Contributor III

I found that one eventually but now I'm using something I've used before and it seems like it cant see my data attach point.

Im trying to place the dijit at the node, but the node come up as undefined when I log it. I  have used html place before and I cant see a difference.

<div>
	<div data-dojo-attach-point="drawBoxNode" data-dojo-type="jimu/dijit/drawbox" data-dojo-props="types:['extent'],showClear:false" style="margin-top:5px;"></div>
	<button class="button" data-dojo-attach-point="getareabutton">Click to draw extent</button>
	<div data dojo attach point="selectionmenu"></div> 
</div>
      	postCreate: function() {
        	this.inherited(arguments);
        	this._initStuff();
        	this.drawBox.setMap(this.map);
        	this.drawBox.types = ["EXTENT"];
        	this.drawBox.keepOneGraphic = true;
        	this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
        	console.log(this.drawBoxNode);
        	html.place(this.drawBox.domNode, this.drawBoxNode);

        	this.own(on(this.getareabutton, 'click', lang.hitch(this, this._grabArea)));
      	},

its bombing out at the html.place because drawBoxNode is undefined. yet I seem to have used the same thing for the select dijit before with no problem. draBox.domnode has the html in it.

html.place(this.selectDijit.domNode, this.selectDijitNode);

Not sure why its undefined.

0 Kudos
JamesHone1
New Contributor III

after messing about some more, drawboxnode is populated, just cant get the html place to work

init.js:115 TypeError: c.appendChild is not a function

define(['dojo/_base/declare',
	'jimu/BaseWidget',
  	'dijit/_WidgetsInTemplateMixin',
  	'dojo/_base/html',
	'dojo/_base/lang',
	'dojo/on',
	'jimu/dijit/DrawBox',
	'dojo/dom'
],
function(declare, BaseWidget, _WidgetsInTemplateMixin, html, lang, on, Drawbox, dom) {
	var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {

		baseClass: 'jimu-widget-JimDrawbox',

		name: 'JimDrawbox',

		drawBox: null,


		_initStuff: function(){
        	this.drawBox = new Drawbox;
		},

      	postCreate: function() {
        	this.inherited(arguments);
        	this._initStuff();
        	this.drawBox.setMap(this.map);
        	this.drawBox.types = ["EXTENT"];
        	this.drawBox.keepOneGraphic = true;
        	this.own(on(this.drawBox, 'DrawEnd', lang.hitch(this, this._onDrawComplete)));
        	
        	console.log('---------------------------')
        	console.log(this.drawBoxNode);
        	console.log(this.getareabutton);
        	console.log('---------------------------')

        	html.place(this.drawBox.domNode, this.drawBoxNode);

        	this.own(on(this.getareabutton, 'click', lang.hitch(this, this._grabArea)));
      	},

      	_grabArea: function() {
      		this.drawBox.activate('EXTENT')
      	},

      	_onDrawComplete: function(graphic) {
      		var geometry = graphic.geometry;
      		this.drawBox.deactivate();
      		console.log(geometry);

      	}

	});

  	return clazz;
});
<div>
	<div data-dojo-attach-point="drawBoxNode" data-dojo-type="jimu/dijit/DrawBox" data-dojo-props="types:['extent'],showClear:false" style="margin-top:5px;"></div>
	<button class="button" data-dojo-attach-point="getareabutton">Click to draw extent</button>
	<div data dojo attach point="selectionmenu"></div> 
</div>

Im not sure why theres an error now I have a value appearing in this.drawBoxNode as I thought that was the problem.

Off on hols soon so at least I wont have to look at this again for a week!

Thanks for all the help!

0 Kudos