Programmatically fire map's click event

15158
12
Jump to solution
07-22-2014 02:49 PM
TomRippetoe
Occasional Contributor

Hello,

I am using the Esri's Javascript API 3.9. I have created functionality that allows a user to add a graphic to the map by clicking on the map. The type of graphic added depends on some previous selection that user has made. For example, selecting one option (say Option A) adds a circle graphic whereas selecting a different option (say Option B) adds a square graphic. 

My need for the programmatic map 'click' event is with the automated unit tests I am creating (I am using Jasmine for my unit tests). My hope is to write a unit test which selects programmatically Option A, programmatically triggers a click on the map, and verifies that the correct 'map click' event handler was called (the one that handles the map clicks when Option A is selected).

I have tried using dojo's emit function.  The code seems to execute with no errors, i.e. the function call returns an 'event' object, but no map click event handler is ever called. I am pretty sure the event is hooked up correctly because if I follow those same steps manually, the correct event handler is called. As part of my testing, i have tried passing the 'emit' function both the map object and the div which contains the map object. Neither way seems to work, i.e. the click event handler is not called. Its not critical to my testing that a 'correct' argument is passed to the event handler; i just want to know that the correct handler is called. 

So, my question is how can i programmatically fire/trigger a map's click event?

Thank you.

//relevant code

this.map = new Map(divId, {

                     basemap: "streets",

                     center: [-122, 45.6],

                     zoom: 5,

                     smartNavigation: false

                 });

//passing the div which contains the map

var theMapDiv = dom.byId(divId);

var testEvent = on.emit(theMapDiv, "click", { bubbles: true, cancelable: true });

//passing the map

var testEvent = on.emit(this.map, "click", { bubbles: true, cancelable: true });

1 Solution

Accepted Solutions
TomRippetoe
Occasional Contributor

I was able to figure this out. It turns out that dojo adds an 'emit' function to javascript objects. Instead of using 'on.emit()' I just called 'object.emit()'

The old, not working code:

var testEvent = on.emit(this.map, "click", { bubbles: true, cancelable: true });

The new, working code:

this.map.emit("click", { bubbles: true, cancelable: true });

View solution in original post

12 Replies
StephenLead
Regular Contributor III

Great question.

I have no experience with Jasmine, but I have done similar testing using Selenium‌. This is a great framework for simulating user input and interaction.

0 Kudos
TomRippetoe
Occasional Contributor

Thanks Stephen.  I did a quick peek at Selenium and that might get me down the right path with its functionality to record user interactions. I will post back and let you know.

I am still hoping that there is some way, outside of a testing framework, to programmatically trigger a map click event (or any other map event i suppose).

Thanks again.

Tom

0 Kudos
StephenLead
Regular Contributor III

Hi Thomas,

Here's another potential approach: jquery - How to simulate a click by using x,y coordinates in JavaScript? - Stack Overflow

(where the XY would be page coordinates over the map). I haven't tested this......

Steve

0 Kudos
TomRippetoe
Occasional Contributor

Hi Stephen.

Thanks again for the tip.

I tried both approaches described in the Stack Overflow question you linked to......without any good luck for either one. 

I suspect the challenge is to know which piece of the 'overall map' is emitting the click event in the real world - is it the container, one of the layers, etc.  Once i figure that out, i can have that particular element programmatically trigger the event?

I'll keep poking around.

0 Kudos
TomRippetoe
Occasional Contributor

I was able to figure this out. It turns out that dojo adds an 'emit' function to javascript objects. Instead of using 'on.emit()' I just called 'object.emit()'

The old, not working code:

var testEvent = on.emit(this.map, "click", { bubbles: true, cancelable: true });

The new, working code:

this.map.emit("click", { bubbles: true, cancelable: true });

StephenLead
Regular Contributor III

Excellent - I'm glad you figured it out!

0 Kudos
JeffPace
MVP Alum

How do you specify the click location with

map.emit("click", { bubbles: true, cancelable: true });

TomRippetoe
Occasional Contributor

Hi Jeff.

You can 'value add' a 'mapPoint' and/or 'screenPoint' objects to the click event. I think 'mapPoint' might be the object you are looking for. I have done something like this (I am pretty sure that i am not doing  'screenPoint' correctly - that's why i am using mapPoint):

var scrPt = new Point(-122, 45.6);

var mpPt = new Point(-122, 45.6);

map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });

deleted-user-FwGV4nJuPxiQ
New Contributor

  Thanks for documenting this! It's crucial to my app and I couldn't find this information anywhere else.

  As you say, it's not clear why you need to provide a screen point and a map point, but you can use map.toScreen(mapPoint) and map.toMap(screenPoint) to convert either one to the other.