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 });
Solved! Go to Solution.
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 });
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.
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
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
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.
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 });
Excellent - I'm glad you figured it out!
How do you specify the click location with
map.emit("click", { bubbles: true, cancelable: true });
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 });
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.